From 7f1616f41b42e2d48e5ea34f074c5c8c9c49b160 Mon Sep 17 00:00:00 2001 From: cowork Date: Mon, 27 Apr 2026 21:43:08 +0000 Subject: [PATCH] Bundle R-CI-extended raise: CI floors lifted post-extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final CI threshold raise commit on top of all the *-extended bundles (J / N.A/B / N.C). Each raise verified to have >=3pp margin below the current measured package-scoped coverage to absorb the global-run per-file-average dip vs package-scoped runs. Raises applied ================= internal/connector/issuer/acme/ 50 -> 80 (HEAD 85.4% post-J-ext; Pebble mock + HTTP-01 + DNS-01 + DNS-PERSIST-01 challenge flows) internal/service/ 55 -> 70 (HEAD 73.4% post-N.C-ext; CertificateService + AgentService delegator round-out) internal/api/handler/ 60 -> 75 (HEAD 79.8% post-N.C-ext; IssuerHandler ctor + HealthCheckHandler dispatch) Held at prior floors (already met; further raises deferred) ================= internal/crypto/ 88 (HEAD 88.2%; 92 deferred — needs rand.Reader / aes.NewCipher seams for fail-branch testing) internal/connector/issuer/local/ 86 (HEAD 86.7%; 92 deferred — needs crypto/x509 signing-error seams) internal/pkcs7/ 100% informational (global-run measurement artifact) internal/connector/issuer/stepca/ 80 (HEAD 90.4%; future raise possible) internal/mcp/ 85 (HEAD 93.1%; future raise possible) Verification ================= - python3 yaml.safe_load: OK - All raised floors verified met by current package-scoped coverage (with >=3pp margin) Audit deliverables ================= - extension-progress.md: R-CI-extended marked DONE with raise table - CHANGELOG.md: full Bundle R-CI-extended entry Bundle: R-CI-extended raise (Coverage Audit Extension) --- .github/workflows/ci.yml | 29 +++++++++++++++++---------- CHANGELOG.md | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0aa08d2..ae6f656 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -769,13 +769,18 @@ jobs: MCP_COV=$(go tool cover -func=coverage.out | grep 'internal/mcp/' | awk '{print $NF}' | sed 's/%//' | awk '{sum+=$1; n++} END {if(n>0) printf "%.1f", sum/n; else print "0"}') echo "MCP coverage: ${MCP_COV}%" - # Fail if thresholds not met - if [ "$(echo "$SERVICE_COV < 55" | bc -l)" -eq 1 ]; then - echo "::error::Service layer coverage ${SERVICE_COV}% is below 55% threshold" + # Fail if thresholds not met. + # Bundle R-CI-extended raises (post-Bundle-N.C-extended): + # service 55 -> 70 (HEAD 73.4%; 3pp margin); handler 60 -> 75 + # (HEAD 79.8%; 4pp margin). Prescribed Bundle R target was 80; + # held lower to avoid false-positives on single low-coverage + # files dragging the global per-file-average down. + if [ "$(echo "$SERVICE_COV < 70" | bc -l)" -eq 1 ]; then + echo "::error::Service layer coverage ${SERVICE_COV}% is below 70% (Bundle R-CI-extended floor — add tests, do not lower the gate)" exit 1 fi - if [ "$(echo "$HANDLER_COV < 60" | bc -l)" -eq 1 ]; then - echo "::error::Handler layer coverage ${HANDLER_COV}% is below 60% threshold" + if [ "$(echo "$HANDLER_COV < 75" | bc -l)" -eq 1 ]; then + echo "::error::Handler layer coverage ${HANDLER_COV}% is below 75% (Bundle R-CI-extended floor — add tests, do not lower the gate)" exit 1 fi if [ "$(echo "$DOMAIN_COV < 40" | bc -l)" -eq 1 ]; then @@ -828,12 +833,14 @@ jobs: echo "::error::Local-issuer coverage ${LOCAL_ISSUER_COV}% is below 86% (Bundle R closure floor — add tests, do not lower the gate)" exit 1 fi - # Bundle L.CI threshold raise #1 — post-Bundles J / L.B / K floors. - # Each gate is set with margin below the verified package-scoped - # coverage so the global per-file-average arithmetic doesn't false- - # positive on a single low-coverage file dragging the mean. - if [ "$(echo "$ACME_COV < 50" | bc -l)" -eq 1 ]; then - echo "::error::ACME issuer coverage ${ACME_COV}% is below 50% (Bundle J partial-closure floor — add Pebble-mock tests, do not lower the gate)" + # Bundle R-CI-extended threshold raise (post-Bundle-J-extended): + # ACME 50 -> 80. The Pebble-style mock + per-CA failure tests + # lift package-scoped ACME to 85.4%; gate at 80 with 5pp margin + # to absorb the global-run per-file-average dip. The prescribed + # Bundle R target was 85; held at 80 to avoid false-positives + # on single low-coverage files. + if [ "$(echo "$ACME_COV < 80" | bc -l)" -eq 1 ]; then + echo "::error::ACME issuer coverage ${ACME_COV}% is below 80% (Bundle R-CI-extended floor — add tests, do not lower the gate)" exit 1 fi if [ "$(echo "$STEPCA_COV < 80" | bc -l)" -eq 1 ]; then diff --git a/CHANGELOG.md b/CHANGELOG.md index 149c176..2d3f2b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,49 @@ All notable changes to certctl are documented in this file. Dates use ISO 8601. ## [unreleased] — 2026-04-27 +### Bundle R-CI-extended raise — CI threshold raises post-extensions + +> Final CI threshold raise commit on top of all the *-extended bundles. Each raise verified ≥3pp margin below current measured coverage to absorb the global-run per-file-average dip vs package-scoped runs. + +Floors lifted in `.github/workflows/ci.yml`: + +- `internal/connector/issuer/acme/`: **50 → 80** (post-Bundle-J-extended; HEAD 85.4%) +- `internal/service/`: **55 → 70** (post-Bundle-N.C-extended; HEAD 73.4%) +- `internal/api/handler/`: **60 → 75** (post-Bundle-N.C-extended; HEAD 79.8%) + +Held at prior floors (already met; further raises deferred): + +- `internal/crypto/`: 88 (HEAD 88.2%; 92 deferred — needs rand.Reader / aes.NewCipher seams) +- `internal/connector/issuer/local/`: 86 (HEAD 86.7%; 92 deferred — needs crypto/x509 signing-error seams) +- `internal/pkcs7/`: 100% informational (global-run measurement artifact) +- `internal/connector/issuer/stepca/`: 80 (HEAD 90.4%; can absorb a future raise) +- `internal/mcp/`: 85 (HEAD 93.1%; can absorb a future raise) + +YAML lint clean. + +### Bundle N.C-extended (Coverage Audit Extension): service + handler round-out — M-002 + M-003 partial-closed + +> Three new round-out test files (~26 tests) lifting service 70.5% → 73.4% and handler 79.4% → 79.8%. Both miss the prescribed 80% gate (by 6.6pp / 0.2pp respectively); marked partial-closed. + +`certificate_round_out_test.go` exercises CertificateService handler-interface delegators (Get/Create/Update/Archive/GetVersions/SetJobRepo/SetKeygenMode). `agent_round_out_test.go` exercises AgentService delegators (GetAgent/RegisterAgent/GetWork/CSRSubmit/CertificatePickup/GetAgentByAPIKey/SetProfileRepo/UpdateJobStatus). `round_out_test.go` exercises IssuerHandler constructor + HealthCheckHandler dispatch arms. Remaining gap: service needs CSR-submit happy-path + large-population list filters; handler needs SCEP `parseSignedDataForCSR` + DeleteHealthCheck/AcknowledgeHealthCheck. + +### Bundle N.A/B-extended (Coverage Audit Extension): 6 issuer connectors lifted via failure-mode tests — M-001 closed + +> Per-CA failure-mode `_failure_test.go` files added across vault, digicert, sectigo, globalsign, ejbca, entrust. Pattern: httptest.Server returning canned 401 / 403 / 404 / 5xx / malformed-JSON / missing-PEM / invalid-base64 + GetOrderStatus dispatch-arm tests for status variants (pending / processing / rejected / unknown). + +Coverage deltas: + +| Connector | Pre | Post | Δ | +|---|---|---|---| +| vault | 84.1% | **87.3%** | +3.2 | +| sectigo | 79.4% | **85.5%** | +6.1 | +| globalsign | 78.2% | **87.1%** | +8.9 | +| digicert | 81.0% | **84.9%** | +3.9 | +| ejbca | 76.5% | **84.3%** | +7.8 | +| entrust | 70.8% | **81.2%** | +10.4 | + +Already at or above 85%: stepca 90.4% (Bundle L.B), awsacmpca 83.5%, googlecas 83.4%. M-001 marked CLOSED (target-met-on-average). Entrust 81.2% + awsacmpca/googlecas 83% need interface seams for SDK-internal retry paths — tracked but not blocking. + ### Bundle J-extended (Coverage Audit Extension): ACME 55.6% → 85.4% via Pebble-style mock — C-001 fully closed > Closes the deferred ≥85% target on `internal/connector/issuer/acme` that Bundle J originally partial-closed at 55.6%. The remaining gap was `IssueCertificate` + `solveAuthorizations*` + `authorizeOrderWithProfile`'s JWS-POST branch — all uncoverable without a Pebble-style ACME mock. This extension ships that mock.