From 2fbf95a6cb697a1e6adcc05f3d48a85caed505d8 Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 15:53:33 +0200 Subject: [PATCH 1/6] :bug: fix(audit): sync AUD-S18 CHECK_STAGES pin with Taskfile check task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EX-S08 (PR #61) added dogfood-examples and dogfood-wiring-test to Taskfile.yml's check: task, bringing it to 17 stages, but the AUD-S18 exit gate's CHECK_STAGES array still pinned only 15 — silently reddening hack/audit/exitgate_test.sh on every push to main since befce0f1 (the release-exitgate job only runs on push, so no PR ever saw it). Add the two missing stages in Taskfile order. --- hack/audit/exitgate_test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hack/audit/exitgate_test.sh b/hack/audit/exitgate_test.sh index 19a5836..60a5cd0 100644 --- a/hack/audit/exitgate_test.sh +++ b/hack/audit/exitgate_test.sh @@ -133,6 +133,7 @@ CHECK_STAGES=( test coverage build + dogfood-examples dogfood-comparison compare-exitgate-test changelog-verify @@ -141,6 +142,7 @@ CHECK_STAGES=( docs-gates lint-depguard-test lint-workflow-pins-test + dogfood-wiring-test ci-audit-test ) From dcd255f2a197e188e62eaf7cdcd7797bf488f15b Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 16:04:13 +0200 Subject: [PATCH 2/6] :memo: docs(changelog): regenerate CHANGELOG.md for the AUD-S18 CHECK_STAGES fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a68994a..42691be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,7 @@ repository still gets a decision, never by following the link; no release carrie - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 lane - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 F2/F5 fixes - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 F6 fix +- :memo: docs(changelog): regenerate CHANGELOG.md for the AUD-S18 CHECK_STAGES fix ### Features - :sparkles: feat(docs): gate example pack and format claims against dogfood @@ -152,6 +153,7 @@ repository still gets a decision, never by following the link; no release carrie - :bug: fix(docs): pin case+decision pairs, not just case names, in the walkthrough (F1) - :bug: fix(examples): scope format extraction to match: lines, not the whole classes: block (F2) - :bug: fix(examples): close the same-line trailing-comment gap in format extraction (F6) +- :bug: fix(audit): sync AUD-S18 CHECK_STAGES pin with Taskfile check task ### Refactoring - :recycle: refactor(examples): discover dogfood packs instead of a hardcoded 3-name loop From 8866e26eb38662c166fb1d50e7bc19a584f700a5 Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 16:09:40 +0200 Subject: [PATCH 3/6] :bug: fix(audit): narrow check_coverage_bar to avoid dogfood-examples' per-pack coverage lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EX-S08's dogfood-examples stage echoes "coverage: OK — N rule(s), every rule tested in both polarities" once per example pack — three lines on main today — and check_coverage_bar's `coverage: ` prefix match at column 1 counted them alongside the real D-010 aggregate echo, so a real task check transcript now has 4 matches where the check expects exactly 1. This bug was masked by the CHECK_STAGES stage-count drift (check_check_wiring failed and aborted the script first) and only surfaced once that was fixed. Anchor the match on a digit immediately after "coverage: " — only the gate's own `echo "coverage: ${pct}% (required: ...)"` (Taskfile.yml coverage:) starts that way; the dogfood-examples lines start with "OK". Adds a permanent regression control mirroring the existing per-package-line control. --- hack/audit/exitgate_test.sh | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/hack/audit/exitgate_test.sh b/hack/audit/exitgate_test.sh index 60a5cd0..d1e3172 100644 --- a/hack/audit/exitgate_test.sh +++ b/hack/audit/exitgate_test.sh @@ -559,12 +559,18 @@ check_coverage_bar() { # local plain="$WORK/cov.plain" strip_ansi "$tr" >"$plain" - # Anchored at column 1: `go test -coverprofile` prints a per-PACKAGE - # `… coverage: 92.3% of statements` on every ok line, and grading on the - # minimum of those would compare the worst package against the aggregate bar. - # Only the gate's own `echo "coverage: ${pct}% (required: …)"` starts the line. + # Anchored at column 1 AND on a digit right after the colon-space: `go test + # -coverprofile` prints a per-PACKAGE `… coverage: 92.3% of statements` on + # every ok line (not at column 1, already excluded by the anchor), and + # EX-S08's dogfood-examples stage echoes ONE "coverage: OK — N rule(s), + # every rule tested in both polarities" line per example pack (at column 1, + # excluded only by the digit check — "OK" is not `[0-9]`). Grading on either + # impostor would either compare the worst package against the aggregate bar + # or count N-pack lines as N spurious "aggregate" measurements. Only the + # gate's own `echo "coverage: ${pct}% (required: …)"` (Taskfile.yml + # coverage:) starts the line with a digit. local hits="$WORK/hits.coverage" - awk 'index($0, "coverage: ") == 1 { print }' "$plain" >"$hits" + awk '/^coverage: [0-9]/ { print }' "$plain" >"$hits" local n n="$(wc -l <"$hits" | tr -d '[:space:]')" if ((n != 1)); then @@ -1702,6 +1708,25 @@ mutate_awk "$m" \ 'coverage: 62.5% of statements' expect_green check_coverage_bar "a per-package coverage line does not displace the aggregate one" "$m" +# EX-S08's dogfood-examples stage echoes its own "coverage: OK — N rule(s), +# every rule tested in both polarities" line per example pack — ALSO anchored +# at column 1, unlike the per-package control above. Without the digit anchor +# these three impostors plus the real aggregate line make `n == 4`, the exact +# regression this control pins (the bug this fix closes: reachable in +# practice as soon as dogfood-examples ran more than zero packs, and reached +# main unnoticed because check_check_wiring failed first and aborted the +# script before this check ever ran). +m="$WORK/check.synth.dogfoodcov" +cp "$SYNTH_CHECK" "$m" +mutate_awk "$m" \ + '{ print } /^task: \[dogfood-examples\]/ { + print "coverage: OK — 6 rule(s), every rule tested in both polarities" + print "coverage: OK — 8 rule(s), every rule tested in both polarities" + print "coverage: OK — 9 rule(s), every rule tested in both polarities" + }' \ + 'coverage: OK — 6 rule(s), every rule tested in both polarities' +expect_green check_coverage_bar "dogfood-examples' per-pack 'coverage: OK — N rule(s)' lines do not displace the aggregate one" "$m" + echo # --------------------------------------------------------------------------- From 2f5fd304333c478ec8a1cc115aa492b3129498be Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 16:09:51 +0200 Subject: [PATCH 4/6] :memo: docs(changelog): regenerate CHANGELOG.md for the check_coverage_bar narrowing fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42691be..b86be01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ repository still gets a decision, never by following the link; no release carrie - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 F2/F5 fixes - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 F6 fix - :memo: docs(changelog): regenerate CHANGELOG.md for the AUD-S18 CHECK_STAGES fix +- :memo: docs(changelog): regenerate CHANGELOG.md for the check_coverage_bar narrowing fix ### Features - :sparkles: feat(docs): gate example pack and format claims against dogfood @@ -154,6 +155,7 @@ repository still gets a decision, never by following the link; no release carrie - :bug: fix(examples): scope format extraction to match: lines, not the whole classes: block (F2) - :bug: fix(examples): close the same-line trailing-comment gap in format extraction (F6) - :bug: fix(audit): sync AUD-S18 CHECK_STAGES pin with Taskfile check task +- :bug: fix(audit): narrow check_coverage_bar to avoid dogfood-examples' per-pack coverage lines ### Refactoring - :recycle: refactor(examples): discover dogfood packs instead of a hardcoded 3-name loop From 3e12cae269fc37658ee91245620b04f492090eae Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 16:20:42 +0200 Subject: [PATCH 5/6] :art: style(audit): de-stale hardcoded '15 stages' literals in AUD-S18 gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer P2 cosmetic note from the CHECK_STAGES-sync review: the gate's own PASS banner and four comments still said '15' after EX-S08 grew task check to 17 stages. Interpolates ${#CHECK_STAGES[@]} where the surrounding code already does, and drops the stale count from prose comments where it adds no grading value. No behavioral change — CHECK_STAGES itself was already fixed to 17 entries by the prior two commits on this lane. --- hack/audit/exitgate_test.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hack/audit/exitgate_test.sh b/hack/audit/exitgate_test.sh index d1e3172..a97519b 100644 --- a/hack/audit/exitgate_test.sh +++ b/hack/audit/exitgate_test.sh @@ -6,7 +6,7 @@ # # (1) REL-07 — the AUD-S01 fail-closed cassettes PASS by name (not "go test # exited 0", which a `-run` regex matching nothing also does). -# (2) RELSE-01/TEST-03 — `task check` is green with all 15 pinned stages +# (2) RELSE-01/TEST-03 — `task check` is green with all pinned stages # actually executed (incl. `changelog-verify`) and the measured # aggregate coverage at or above the epic's 91.0% bar. # (3) RELSE-05 — the release job still runs the verify-green-on-tag-SHA gate, @@ -122,9 +122,9 @@ S01_TESTS_CMD=( TestFoldSnapshotPathsIncompleteEnumeration ) -# (2) The 15 stages of `task check`. This list is the authority: the Taskfile's +# (2) The stages of `task check`. This list is the authority: the Taskfile's # `check:` list must equal it, and a real `task check` transcript must show all -# 15 having run. Grading on the exit code alone is what "aborts at the first +# of them having run. Grading on the exit code alone is what "aborts at the first # failure" makes meaningless. CHECK_STAGES=( fmt @@ -457,7 +457,7 @@ check_s01_cassettes() { # # (2) RELSE-01 / TEST-03 — `task check` green at the new bar # ============================================================================ -# The Taskfile's `check:` list must be exactly the 15 pinned stages. Without +# The Taskfile's `check:` list must be exactly the pinned stages. Without # this, deleting `- task: changelog-verify` reopens RELSE-01 with `task check` # still exiting 0 — the regression the whole story exists to prevent. check_check_wiring() { # @@ -514,7 +514,7 @@ check_check_wiring() { # # Every pinned stage must have actually RUN. go-task prints `task: [] ` # per stage; that transcript is the only evidence a stage executed, because # `task check` aborts at the first failure and the exit code cannot distinguish -# "15 stages green" from "stage list truncated to 2". +# "all stages green" from "stage list truncated to 2". check_check_stages() { # local tr="$1" rc=0 [[ -f "$tr" ]] || { @@ -1559,7 +1559,7 @@ expect_red check_s01_cassettes "the -run pattern matched NO test (go test exits echo # --------------------------------------------------------------------------- -echo "== (2) RELSE-01 / TEST-03 — task check green, 15 stages, coverage >= ${COVERAGE_BAR}% ==" +echo "== (2) RELSE-01 / TEST-03 — task check green, ${#CHECK_STAGES[@]} stages, coverage >= ${COVERAGE_BAR}% ==" expect_green check_check_wiring "Taskfile check: runs exactly the ${#CHECK_STAGES[@]} pinned stages" "$TASKFILE" expect_green check_coverage_floor "the single-sourced D-010 floor (Taskfile COVERAGE_MIN) is >= ${COVERAGE_BAR}" "$TASKFILE" From 1a4715e211a20a1c698108b1b442ffb3a308cbe2 Mon Sep 17 00:00:00 2001 From: Konrad Heimel Date: Sun, 16 Aug 2026 16:20:51 +0200 Subject: [PATCH 6/6] :memo: docs(changelog): regenerate CHANGELOG.md for the stale-'15' cosmetic fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b86be01..91ce609 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -135,6 +135,7 @@ repository still gets a decision, never by following the link; no release carrie - :memo: docs(changelog): regenerate CHANGELOG.md for the EX-S10 F6 fix - :memo: docs(changelog): regenerate CHANGELOG.md for the AUD-S18 CHECK_STAGES fix - :memo: docs(changelog): regenerate CHANGELOG.md for the check_coverage_bar narrowing fix +- :memo: docs(changelog): regenerate CHANGELOG.md for the stale-'15' cosmetic fix ### Features - :sparkles: feat(docs): gate example pack and format claims against dogfood @@ -159,6 +160,7 @@ repository still gets a decision, never by following the link; no release carrie ### Refactoring - :recycle: refactor(examples): discover dogfood packs instead of a hardcoded 3-name loop +- :art: style(audit): de-stale hardcoded '15 stages' literals in AUD-S18 gate ### Testing - :white_check_mark: test(release): anchor the D-120 note check on its header sentence, not the bare token