diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 781c6ce..ec7d245 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -611,6 +611,51 @@ jobs: working-directory: web run: npx vite build + - name: Forbidden hardcoded source-count prose regression guard (S-1) + # S-1 master closed cat-s1-9ce1cbe26876 (README + features.md + # stale numeric counts; explicit CLAUDE.md violation per + # "version-stamped numbers rot") and + # cat-s1-features_md_issuer_count_contradiction (features.md + # self-disagreed on issuer count: 9 vs 12 in the same doc). + # The fix replaced source-derived numbers in prose with + # "rebuild via " patterns documented in CLAUDE.md:: + # "Current-state commands". This step grep-fails the build if + # any of the previously-stale sites reintroduces a hardcoded + # count. + # + # Allowed surfaces: demo-fixture prose in README ("32 + # certificates" — those are seed_demo.sql facts, not live + # source counts), historical-milestone counts in + # WORKSPACE-CHANGELOG.md, the testing-guide example phrasing + # ("README claims 8 issuer connectors but only 6 exist"), + # and any number that quotes the source command immediately + # adjacent. + # + # See coverage-gap-audit-2026-04-24-v5/unified-audit.md + # cat-s1-9ce1cbe26876 + cat-s1-features_md_issuer_count_contradiction + # for closure rationale. + run: | + set -e + BAD=$(grep -rnE '\b[0-9]+\s+(issuer connectors?|target connectors?|notifier connectors?|discovery connectors?|MCP tools|OpenAPI operations|migrations|database tables|frontend pages|HTTP routes)\b' \ + README.md docs/ 2>/dev/null \ + | grep -vE 'WORKSPACE-CHANGELOG|seed_demo|demo override' \ + | grep -vE 'DRIFT HAZARD|Source: |Rebuild|rebuild via|grep -|wc -l|ls -d|find ' \ + | grep -vE 'README claims [0-9]+ issuer connectors but only [0-9]+ exist' \ + || true) + if [ -n "$BAD" ]; then + echo "S-1 regression: hardcoded source-count prose reappeared:" + echo "$BAD" + echo "" + echo "CLAUDE.md rule: 'Numeric claims about current state rot.'" + echo "Replace the count with the grep command from CLAUDE.md::" + echo "'Current-state commands' (e.g. 'ls -d internal/connector/issuer/*/ | wc -l')" + echo "or rephrase to reference the rebuild command on the same line." + echo "See coverage-gap-audit-2026-04-24-v5/unified-audit.md" + echo "cat-s1-9ce1cbe26876 for closure rationale." + exit 1 + fi + echo "S-1 stale-counts guardrail: clean." + helm-lint: name: Helm Chart Validation runs-on: ubuntu-latest diff --git a/docs/examples.md b/docs/examples.md index 08aad18..ae019b1 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -111,7 +111,7 @@ The full walkthrough — including profile-based issuer assignment, testing with ## Beyond These Examples -These 5 scenarios cover the most common deployment patterns, but certctl supports 7 issuer backends and 10 target connectors. Once you have the basics running, you can mix and match: +These 5 scenarios cover the most common deployment patterns, but certctl supports a broader set of issuer and target backends — see `docs/features.md`'s Issuer Connectors and Target Connectors sections for the live catalogs (rebuild via `ls -d internal/connector/issuer/*/ | wc -l` and `ls -d internal/connector/target/*/ | wc -l`). Once you have the basics running, you can mix and match: **Issuers:** ACME (Let's Encrypt, ZeroSSL, Buypass, Google Trust Services), Local CA (self-signed or sub-CA), step-ca, Vault PKI, DigiCert CertCentral, OpenSSL/Custom CA script, Sectigo (coming soon). diff --git a/docs/features.md b/docs/features.md index 50cb934..6e93c48 100644 --- a/docs/features.md +++ b/docs/features.md @@ -8,17 +8,30 @@ Complete reference of every feature shipped in certctl through v2.1.0 (April 202 | Metric | Count | |---|---| -| HTTP routes | 107 (103 under `/api/v1/` + 4 EST) | -| OpenAPI 3.1 operations | 97 | -| MCP tools | 80 | -| CLI commands | 12 | -| Issuer connectors | 9 (+ EST server) | -| Target connectors | 14 | -| Notifier connectors | 6 channels | -| Database tables | 21 (across 10 migrations) | -| Background scheduler loops | 12 (8 always-on + 4 opt-in) | -| Web dashboard pages | 24 | -| Test functions | 1850+ | + +| Surface | Count (rebuild command) | +|---|---| +| HTTP routes | rebuild via `grep -cE 'r\.Register\("[A-Z]' internal/api/router/router.go` | +| OpenAPI 3.1 operations | rebuild via `grep -cE '^\s+operationId:' api/openapi.yaml` | +| MCP tools | rebuild via `grep -cE 'gomcp\.AddTool\(' internal/mcp/tools.go` | +| CLI commands | rebuild via `grep -cE 'AddCommand|RootCmd\.Add' cmd/cli/*.go internal/cli/*.go` (intentionally narrow — see CLI Scope §) | +| Issuer connectors | rebuild via `ls -d internal/connector/issuer/*/ \| wc -l` (+ EST server) | +| Target connectors | rebuild via `ls -d internal/connector/target/*/ \| wc -l` (includes shared `certutil/`) | +| Notifier connectors | rebuild via `ls -d internal/connector/notifier/*/ \| wc -l` | +| Discovery connectors | rebuild via `ls -d internal/connector/discovery/*/ \| wc -l` | +| Database tables | rebuild via `grep -hE '^CREATE TABLE' migrations/*.up.sql \| sed -E 's/CREATE TABLE (IF NOT EXISTS )?([a-zA-Z_]+).*/\2/' \| sort -u \| wc -l` (across `ls migrations/*.up.sql \| wc -l` migrations) | +| Background scheduler loops | rebuild via `grep -cE '^func \(s \*Scheduler\) [a-zA-Z]+Loop' internal/scheduler/scheduler.go` | +| Web dashboard pages | rebuild via `ls web/src/pages/*.tsx \| grep -v '\.test\.' \| wc -l` | +| Test functions (Go backend) | rebuild via the `find` + `grep '^func Test'` recipe in CLAUDE.md::Current-state commands | | Supported platforms | linux/amd64, linux/arm64, darwin/amd64, darwin/arm64 | --- @@ -325,9 +338,9 @@ Policies can be scoped to agent groups via `agent_group_id` foreign key. Violati ## Issuer Connectors - + -12 issuer connectors implementing the `issuer.Connector` interface. All support `ValidateConfig`, `IssueCertificate`, `RenewCertificate`, `RevokeCertificate`, `GetOrderStatus`, `GenerateCRL`, `SignOCSPResponse`, `GetCACertPEM`, `GetRenewalInfo`. +The issuer connector catalog (rebuild count via `ls -d internal/connector/issuer/*/ | wc -l`) implements the `issuer.Connector` interface. All support `ValidateConfig`, `IssueCertificate`, `RenewCertificate`, `RevokeCertificate`, `GetOrderStatus`, `GenerateCRL`, `SignOCSPResponse`, `GetCACertPEM`, `GetRenewalInfo`. ### Local CA @@ -616,9 +629,9 @@ For Let's Encrypt 6-day `shortlived` certificates, ARI is the expected renewal p ## Target Connectors - + -14 target connector types implementing the `target.Connector` interface. All support `ValidateConfig`, `DeployCertificate`, `ValidateDeployment`. +The target connector catalog (rebuild count via `ls -d internal/connector/target/*/ | wc -l`) implements the `target.Connector` interface. All support `ValidateConfig`, `DeployCertificate`, `ValidateDeployment`. ### Deployment Model @@ -1124,7 +1137,7 @@ Single SQL `UNION` query replaces the previous "fetch all, filter in Go" approac GUI-driven issuer CRUD with AES-256-GCM encrypted config storage in PostgreSQL. -- Per-type config schema validation for all 9 issuer types +- Per-type config schema validation for all issuer types (rebuild count via `ls -d internal/connector/issuer/*/ | wc -l`) - Test connection flow (instantiates throwaway connector, calls `ValidateConfig`) - Dynamic `sync.RWMutex`-guarded `IssuerRegistry` — rebuilds without server restart - Env var backward compatibility: seeds DB on first boot if no DB config exists @@ -1153,9 +1166,9 @@ Same pattern as issuer configuration: ## Web Dashboard - + -24 pages wired to real API endpoints. +The dashboard surface (rebuild count via `ls web/src/pages/*.tsx | grep -v '\.test\.' | wc -l`) wires every page to real API endpoints. ### Pages @@ -1274,7 +1287,7 @@ certctl-cli certs bulk-revoke --issuer-id iss-letsencrypt --reason caCompromise Separate standalone binary (`cmd/mcp-server/`) using the official MCP Go SDK (`modelcontextprotocol/go-sdk`). Stdio transport for Claude, Cursor, and similar AI tool integrations. -- 80 MCP tools covering all API endpoints +- MCP tools covering all API endpoints (rebuild count via `grep -cE 'gomcp\.AddTool\(' internal/mcp/tools.go`) - Stateless HTTP proxy — translates MCP tool calls to REST API calls - Typed input structs with `jsonschema` struct tags for automatic schema generation - Binary response support (DER CRL, OCSP)