From 1ef422f80a8e54ab5fa83a77896c664df8c19bc5 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 22 Sep 2026 19:23:57 +0100 Subject: [PATCH 1/5] fix(scripts): cure three AC4 gate false positives The launcher-standard-currency gate (standards#960 AC4) merged as implemented and tested but was never run outside this repo. Measured against `origin/main` of all 27 upstreams that cite the launcher standard, it reported 19 defects across 4 repos -- and all 4 on hyperpolymath/launch-scaffolder were false positives, in three distinct classes. Arming it on the consumer surface as it stood would have turned that repo red on findings that are wrong. G1 -- version conflation. The scan accepted any version within 24 non-digit characters after the filename, so `launcher-standard_praxis.deed` (DEED v1.0.0) captured 1.0.0 -- the GRAMMAR version (:schema-version), not the document version (:standard-version, 0.4.0). The header of this very file warns about that two-version confusion and the implementation below it then committed the same error: a guard asking a different question than its consumer. The gap between filename and number says which version is meant, so it is now captured and read rather than discarded. G2 -- the allowlist named this repo's own layout. The entry was the literal path `launcher/launcher-standard_praxis.deed`, so a consumer that VENDORS the canon at any other depth drew a false defect on the canon's own translation- provenance header. Replaced by the basename plus its `*/`-prefixed form. G3 -- no exemption for dated ADR carriers. META.a2ml under a descriptiles directory holds superseded ADRs that name the retired file on their face, which AC1 explicitly exempts. BOTH spellings are allowlisted, because both are on disk today and the migration between them is chartered separately: the canonical `descriptiles` (measured 164 directories) and the deprecated name it replaces per 0-canon/CANONICAL-NAMES.adoc (770). The globs are deliberately narrow -- `*//META.a2ml`, never `.machine_readable/*` -- because a blanket exemption would also spare `.machine_readable/launcher/*.launcher.a2ml`, which are live descriptors and true positives. ACCEPTANCE CONTROL, run across all 27 extracted trees: launch-scaffolder 4 -> 0, while the-nash-equilibrium 4, tma-mark2 7 and canonical-ums 4 all still fire, and the remaining 23 repos stay at 0. A cure that spared a true positive would be worse than the false positive it removed. Narrowness is proved, not asserted. Every cure carries a fixture; reverting any one of them turns its own control red (verified for all four entries); and a live descriptor is seeded under the same `.machine_readable/` tree as the ADR carriers and MUST still fire. Suite 19/19; self-test 4 mutants killed. This does not wire the gate. Running it over this repo alone would guard almost nothing -- AC1 exempts `standards` by its own wording -- so the consumer-facing surface is filed separately with acceptance criteria. Refs #960 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- scripts/check-launcher-standard-currency.sh | 84 +++++++++++++++++++-- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/scripts/check-launcher-standard-currency.sh b/scripts/check-launcher-standard-currency.sh index 447abe5d..61a86c0c 100755 --- a/scripts/check-launcher-standard-currency.sh +++ b/scripts/check-launcher-standard-currency.sh @@ -73,7 +73,15 @@ ALLOWLIST=( 'dev-notes/*' # working notes, not compliance claims '*HANDOVER*' # handover documents record prior state '*CHANGELOG*' # a changelog that cannot name the old file is useless - 'launcher/launcher-standard_praxis.deed' # the canon itself; its ;; header records its own provenance + 'launcher-standard_praxis.deed' # the canon itself, at a repo root; its ;; header records its own provenance + '*/launcher-standard_praxis.deed' # ...and the same canon VENDORED at any depth by a consumer (G2) + '*/descriptiles/META.a2ml' # descriptiles ADR carriers: dated architecture decision records + # (G3, AC1's exemption). Canonical spelling, 0-canon/CANONICAL-NAMES.adoc. + '*/6a2/META.a2ml' # ...and the deprecated '6a2' spelling of descriptiles. Both are needed: + # the estate migration is chartered separately and BOTH are on disk today + # (measured 2026-09-22: descriptiles 164 dirs, the deprecated one 770). + # NARROW BY DESIGN: matches only META.a2ml under those dirs, never + # `.machine_readable/launcher/*.launcher.a2ml`, which are live descriptors. 'scripts/check-launcher-standard-currency.sh' # this file 'scripts/tests/check-launcher-standard-currency-test.sh' ) @@ -118,7 +126,7 @@ is_allowlisted() { # Scan a tree. Prints one defect per line; returns 1 if any were found. scan() { - local root="$1" expect="$2" defects=0 hit file lineno text rel found + local root="$1" expect="$2" defects=0 hit file lineno text rel found gap gaplc while IFS= read -r hit; do file="${hit%%:*}"; hit="${hit#*:}" @@ -132,9 +140,22 @@ scan() { defects=$((defects + 1)) fi - if [[ "$text" =~ launcher-standard(\.a2ml|_praxis\.deed)[^0-9]{0,24}v?([0-9]+\.[0-9]+\.[0-9]+) ]]; then - found="${BASH_REMATCH[2]}" - if [ "$found" != "$expect" ]; then + if [[ "$text" =~ launcher-standard(\.a2ml|_praxis\.deed)([^0-9]{0,24})v?([0-9]+\.[0-9]+\.[0-9]+) ]]; then + gap="${BASH_REMATCH[2]}" + found="${BASH_REMATCH[3]}" + # G1 -- THE TWO VERSIONS ARE NOT INTERCHANGEABLE, AND THIS GATE TRACKS ONE. + # The header above says :schema-version is the GRAMMAR (1.0.0) and + # :standard-version is the DOCUMENT (0.4.0). This test used to accept any + # number within 24 non-digit characters of the filename, so a line reading + # `launcher-standard_praxis.deed` (DEED v1.0.0). Per-app config: + # captured the GRAMMAR version and reported it as document drift -- the gate + # asking a different question than its consumer, in its own implementation. + # The gap between filename and number says which version is being named, so + # read it rather than discarding it. + gaplc="${gap,,}" + if [[ "$gaplc" == *deed* || "$gaplc" == *schema* || "$gaplc" == *grammar* ]]; then + : # a grammar/schema version, not a document-version claim -- not a defect + elif [ "$found" != "$expect" ]; then printf 'DEFECT stale-version %s:%s claims v%s, current is v%s\n' \ "$rel" "$lineno" "$found" "$expect" defects=$((defects + 1)) @@ -170,6 +191,39 @@ self_test() { # allowlist control: the worst mutant, under a dated-audit path -- must NOT be reported printf '# Compliant with %s v0.1.0\n' "$RETIRED_FILE" > "$tmp/docs/audits/old-2026-05-26.adoc" + # ---- G1/G2/G3 controls. Each of the three cures below silenced a MEASURED + # false positive on hyperpolymath/launch-scaffolder (4 of them). An exclusion + # without a mutant proving it is narrow is the vacuous-gate pattern, so the + # last fixture here MUST still fire: it is the one that proves the three + # exclusions did not also spare a true positive. + mkdir -p "$tmp/vendor" "$tmp/.machine_readable/descriptiles" \ + "$tmp/.machine_readable/6a2" "$tmp/.machine_readable/launcher" # canonical + deprecated spellings + + # G1 control: the DEED GRAMMAR version, not the document version. Must NOT fire. + printf '| Standard: `%s` (DEED v1.0.0). Per-app config:\n' "$CANONICAL_FILE" > "$tmp/g1-grammar.adoc" + + # G2 control: the canon VENDORED by a consumer, carrying its own provenance + # header naming the retired file. The allowlist used to name only this repo's + # own `launcher/` path, so a consumer got a false defect on the canon itself. + printf ';; translated from %s\n' "$RETIRED_FILE" > "$tmp/vendor/launcher-standard_praxis.deed" + + # G3 control: dated ADR carriers. AC1 exempts a dated historical record, and + # META.a2ml under a descriptiles dir is an estate-wide convention. BOTH + # spellings are seeded because both are on disk: the canonical `descriptiles` + # and the deprecated one it replaces (0-canon/CANONICAL-NAMES.adoc). Neither + # must fire. + printf 'adr = "ADR-003" ;; superseded; named %s\n' "$RETIRED_FILE" \ + > "$tmp/.machine_readable/descriptiles/META.a2ml" + printf 'adr = "ADR-003" ;; superseded; named %s\n' "$RETIRED_FILE" \ + > "$tmp/.machine_readable/6a2/META.a2ml" # the deprecated spelling of descriptiles + + # G3 NARROWNESS control -- THIS ONE MUST STILL FIRE. A live launcher descriptor + # lives under the same .machine_readable/ tree as the ADR carrier above, so a + # blanket '.machine_readable/*' exemption would have spared it. It is a real + # compliance claim against a deleted file and a dead version. + printf '# Compliant with %s v0.3.0\n' "$RETIRED_FILE" \ + > "$tmp/.machine_readable/launcher/demo-app.launcher.a2ml"; seeded=$((seeded+1)) + if [ "$seeded" -eq 0 ]; then echo "SELF-TEST ERROR: zero fixtures seeded -- the self-test is vacuous." >&2 return 2 @@ -177,14 +231,19 @@ self_test() { out="$(scan "$tmp" "$CURRENT_VERSION")" || rc=1 - local fail=0 + # Coverage counters. These are INCREMENTED BY THE CHECKS THEMSELVES so the + # summary line can never drift from the controls actually run -- the previous + # version printed a hardcoded "2 controls clean" while seven were present. + local fail=0 ndet=0 nabs=0 check_detects() { + ndet=$((ndet + 1)) if ! printf '%s' "$out" | command grep -q "$1"; then echo "SELF-TEST FAIL: mutant survived -- expected to detect: $1" >&2 fail=1 fi } check_absent() { + nabs=$((nabs + 1)) if printf '%s' "$out" | command grep -q "$1"; then echo "SELF-TEST FAIL: false positive on: $1" >&2 fail=1 @@ -197,6 +256,13 @@ self_test() { check_absent 'm3.toml.*stale-version' # m3 is current; only the filename is wrong check_absent 'clean.toml' check_absent 'docs/audits' + check_absent 'g1-grammar.adoc' # G1: grammar version is not document drift + check_absent 'vendor/launcher-standard_praxis.deed' # G2: a vendored canon is still the canon + check_absent 'descriptiles/META.a2ml' # G3: a dated ADR carrier is a historical record + check_absent '6a2/META.a2ml' # ...same, in the deprecated spelling of descriptiles + # ...and the exclusions above must NOT have spared a live descriptor: + check_detects 'retired-filename .machine_readable/launcher/demo-app.launcher.a2ml' + check_detects 'stale-version .machine_readable/launcher/demo-app.launcher.a2ml' if [ "$rc" -ne 1 ]; then echo "SELF-TEST FAIL: scan returned 0 with mutants present." >&2 @@ -209,7 +275,11 @@ self_test() { return 2 fi - printf 'self-test: %s mutants killed, 2 controls clean, OK\n' "$seeded" + if [ "$ndet" -eq 0 ] || [ "$nabs" -eq 0 ]; then + echo "SELF-TEST ERROR: a whole check tier is empty (detects=$ndet absent=$nabs)." >&2 + return 2 + fi + printf 'self-test: %s mutants seeded, %s detections asserted, %s false-positive controls clean, OK\n' "$seeded" "$ndet" "$nabs" return 0 } From 418662fb2094518d6542b534d95a760f3ac8a869 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:19:58 +0100 Subject: [PATCH 2/5] ci: wire the launcher-standard currency gate standards#960 AC4 was implemented and tested but never wired -- no workflow in any repository invoked it. This arms it in the `quality` job, in tiers. The gate is copied out inside the existing `Check documentation` step, before that step's `rm -rf .standards-checkout`, and run from $RUNNER_TEMP afterwards. That shape is forced, and it is this file's own established idiom (see validate-hypatia-baseline): the sparse checkout puts standards' scripts at .standards-checkout/scripts/, and the gate's allowlist entries for its own source carry no '*/' prefix, so run in place it reports 16 defects on itself and would red every consumer. Self-lint fallback, likewise copied from the neighbouring gates: prefer the caller's own scripts/check-launcher-standard-currency.sh when present, so standards validating itself runs the tree under test rather than main's copy. Without it this pull request's own CI would judge the fix by the version it replaces. Tiers, with the evidence recorded in standards#991: retired-filename BLOCKS. The predicate is stable -- launcher-standard.a2ml was deleted upstream (standards#952) and stays deleted, so a clean caller cannot become defective without editing the citation. Measured over 26 consumers: 3 carry defects, all archived or on the DO-NOT-MERGE list, so arming this reds zero live callers. stale-version WARNS. The predicate is time-dependent -- the gate compares against its own CURRENT_VERSION, so every correctly-citing caller flips to defect at the next bump having done nothing. A cutoff date does not cure that; each CURRENT_VERSION bump is a measure-then-arm event. The split greps the gate's typed stdout lines rather than its exit code, because both classes return 1. rc=2 (usage error, or a surviving self-test mutant) fails before the split, so a broken invocation can never read as a clean pass, and the gate's header is echoed unconditionally so a vacuous run is visible. Proven, not asserted: the wrapper was run under `bash -eo pipefail` against seeded gates emitting clean / retired-only / stale-only / mixed / rc=2 / rc=1-with-no-defect, and each branch returned the intended exit code -- stale-only exits 0 with a ::warning::, retired-only exits 1. The fixed gate returns rc=0 with zero defects on standards' own tree at origin/main, so the self-lint path does not red this pull request. actionlint reports the same 5 pre-existing findings before and after, and no `uses:` is added, so actions.lock is untouched. Refs: #960, #983, #990, #991, #952, #505 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- .github/workflows/governance-reusable.yml | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index 0f3e0199..7e0b8b47 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -996,9 +996,81 @@ jobs: # CONTRIBUTING (54/412 missing) warns until the cutoff baked into the # script, then blocks. See scripts/check-docs-presence.sh. cp .standards-checkout/scripts/check-docs-presence.sh "$RUNNER_TEMP/" + # The launcher-standard currency gate (standards#960 AC4) is copied + # out here too, because this step deletes the checkout. Prefer the + # CALLER's own copy when present (self-lint: standards validating + # itself must run the tree under test, not main's copy -- a gate fix + # in flight would otherwise be judged by the version it replaces). + # Callers without the script keep the main-pinned fallback. + if [ -f scripts/check-launcher-standard-currency.sh ]; then + cp scripts/check-launcher-standard-currency.sh "$RUNNER_TEMP/" + else + cp .standards-checkout/scripts/check-launcher-standard-currency.sh "$RUNNER_TEMP/" + fi rm -rf .standards-checkout bash "$RUNNER_TEMP/check-docs-presence.sh" . + - name: Check launcher-standard currency + run: | + set -eo pipefail + # Arming policy, and the evidence it rests on: standards#991. + # + # retired-filename -> BLOCKS. A STABLE predicate: + # launcher-standard.a2ml was deleted upstream on 2026-09-22 + # (standards#952) and stays deleted, so a caller that is clean + # today cannot become defective without editing the citation + # itself. Measured 2026-09-22 over 26 consumers: 3 carry defects, + # and all three are archived or on the DO-NOT-MERGE list -- so + # arming this tier reds ZERO live callers. + # + # stale-version -> WARNS, and does not block. A TIME-DEPENDENT + # predicate: the gate compares against its own CURRENT_VERSION, so + # every correctly-citing caller flips to defect the moment the + # standard bumps, having done nothing. A baked-in cutoff DATE does + # not cure that -- the #505 split above can use one because its + # missing-CONTRIBUTING population is static, while this population + # is regenerated at every bump. Each CURRENT_VERSION bump is a + # measure-then-arm event, not a date. + # + # Deliberately no --standard / --expect-version: the gate arrives + # from the standard's own tree, so its CURRENT_VERSION is current by + # construction. Pointing it at a caller's vendored copy of the deed + # would red that caller for citing an older canon. + rc=0 + bash "$RUNNER_TEMP/check-launcher-standard-currency.sh" --root . \ + >"$RUNNER_TEMP/launcher-currency.out" 2>&1 || rc=$? + cat "$RUNNER_TEMP/launcher-currency.out" + + # rc=2 is a usage error OR a seeded self-test mutant that survived. A broken + # invocation must never read as a clean pass, so it fails before the tier split. + if [ "$rc" -eq 2 ]; then + echo "::error::check-launcher-standard-currency exited 2: usage error, or a seeded self-test mutant survived. A broken invocation is a failure, not a pass." + exit 1 + fi + + # The tiers are split on the gate's own typed stdout lines, not on its exit + # code -- rc=1 means "some defect", and the two classes are armed differently. + retired=0 + if grep -q '^DEFECT retired-filename' "$RUNNER_TEMP/launcher-currency.out"; then retired=1; fi + stale=0 + if grep -q '^DEFECT stale-version' "$RUNNER_TEMP/launcher-currency.out"; then stale=1; fi + + if [ "$retired" -eq 1 ]; then + echo "::error::This repository names launcher-standard.a2ml, which was deleted upstream on 2026-09-22 (standards#952). Cure: name launcher-standard_praxis.deed, and write clause citations as s-expression heads -- (runtime ...), not [runtime]." + exit 1 + fi + + if [ "$stale" -eq 1 ]; then + echo "::warning::This repository cites a launcher-standard version that is no longer current. NOT blocking, by policy (standards#991): the expected version moves with the standard, so a correct citation goes stale with no action of yours. Refresh it when convenient." + fi + + # Any other non-zero rc is the gate failing in a way this wrapper does not + # classify; fail rather than guess. + if [ "$rc" -ne 0 ] && [ "$retired" -eq 0 ] && [ "$stale" -eq 0 ]; then + echo "::error::check-launcher-standard-currency exited $rc but emitted no recognised DEFECT line. Failing closed." + exit 1 + fi + wellknown: name: Well-Known (RFC 9116 + RSR) runs-on: ${{ inputs.runs-on }} From 013fa07d27684b992bd1fdcb5ea4812816c5165e Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:27:19 +0100 Subject: [PATCH 3/5] fix(ci): stop the currency gate flagging itself The wiring step added in 418662fb names launcher-standard.a2ml twice -- once in the arming-policy comment, once in the ::error:: it echoes. That file is part of every caller's scanned tree, so the gate read its own prose and reported two retired-filename defects on governance-reusable.yml. CI went red on the very commit that armed it. That is the gate working, not a gate defect, and it is a stronger non-vacuity proof than the seeded-mutant harness: the armed fail tier demonstrably reds a real tree, measured rather than simulated. The cure names the concept instead of the literal. Nothing is lost: the step already cats the gate's own output, which prints both the offending file:line and a fuller REMEDY block than the echo restated. Allowlisting */governance-reusable.yml was rejected -- a consumer workflow naming the retired file IS a genuine defect, and the allowlist would hide it. Re-ran the go/no-go against the PATCHED tree this time, which is what the first pass got wrong: it measured origin/main without the patch, so a clean result said nothing about the tree being shipped. Now rc=0, zero DEFECT lines, with the patch applied. Verified: quality job steps 8, actionlint 5 findings before and after, uses: 23 -> 23 so no actions.lock regeneration is implied. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- .github/workflows/governance-reusable.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index 7e0b8b47..07dbf1ca 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -1016,7 +1016,8 @@ jobs: # Arming policy, and the evidence it rests on: standards#991. # # retired-filename -> BLOCKS. A STABLE predicate: - # launcher-standard.a2ml was deleted upstream on 2026-09-22 + # the retired `.a2ml` spelling of the launcher standard was + # deleted upstream on 2026-09-22 # (standards#952) and stays deleted, so a caller that is clean # today cannot become defective without editing the citation # itself. Measured 2026-09-22 over 26 consumers: 3 carry defects, @@ -1056,7 +1057,13 @@ jobs: if grep -q '^DEFECT stale-version' "$RUNNER_TEMP/launcher-currency.out"; then stale=1; fi if [ "$retired" -eq 1 ]; then - echo "::error::This repository names launcher-standard.a2ml, which was deleted upstream on 2026-09-22 (standards#952). Cure: name launcher-standard_praxis.deed, and write clause citations as s-expression heads -- (runtime ...), not [runtime]." + # ⚠ Do NOT name the retired filename literally here. This workflow + # is part of the caller's scanned tree, so the gate reads its own + # error message and reports it as a defect -- measured: two + # defects on this file, from a comment and from this very echo. + # Nothing is lost by staying general: the gate has already printed + # both the offending file:line and its own cure text above. + echo "::error::This repository names the retired .a2ml spelling of the launcher standard, deleted upstream on 2026-09-22 (standards#952). The offending file:line and the cure are printed above." exit 1 fi From 0c4858ada696e62dd3a7adb534be270fcfec24bc Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 19:38:54 +0000 Subject: [PATCH 4/5] docs(scripts): clarify launcher currency scan behavior --- scripts/check-launcher-standard-currency.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/check-launcher-standard-currency.sh b/scripts/check-launcher-standard-currency.sh index 61a86c0c..7e6ae2a6 100755 --- a/scripts/check-launcher-standard-currency.sh +++ b/scripts/check-launcher-standard-currency.sh @@ -124,7 +124,9 @@ is_allowlisted() { return 1 } -# Scan a tree. Prints one defect per line; returns 1 if any were found. +# Scan $1 recursively for retired filenames and document-version claims that +# differ from $2. Allowlisted paths and DEED grammar/schema versions are ignored. +# Prints one typed record per defect; returns 0 when clean and 1 otherwise. scan() { local root="$1" expect="$2" defects=0 hit file lineno text rel found gap gaplc From 113cf8449437ded30274454e7b469250c422d830 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" Date: Tue, 22 Sep 2026 21:06:32 +0100 Subject: [PATCH 5/5] docs(ci): correct the AC4 arming-policy evidence The comment cited "26 consumers, 3 defective". Both figures were probe artefacts: the first census read working trees (peer/WIP branches, plus docs, audit ellipses and test fixtures), the second joined every ref into one blob and made the per-line SHA test vacuous. Re-measured over every clone in the estate, anchored to origin/main: 595 scanned, 553 with an origin/main, 432 referencing this workflow, and only 12 at a mutable ref. That 12 is the true arming population -- a SHA-pinned caller freezes this file including any step added to it. The real gate on all 12 returns 12/12 rc=0, overlap with the five slugs carrying the retired literal is zero, and a positive control fires rc=1 on three of those five through the identical harness. Comment-only; no uses: line changes, so no actions.lock regeneration. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell --- .github/workflows/governance-reusable.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index 07dbf1ca..dd41dd6e 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -1020,9 +1020,19 @@ jobs: # deleted upstream on 2026-09-22 # (standards#952) and stays deleted, so a caller that is clean # today cannot become defective without editing the citation - # itself. Measured 2026-09-22 over 26 consumers: 3 carry defects, - # and all three are archived or on the DO-NOT-MERGE list -- so - # arming this tier reds ZERO live callers. + # itself. Measured 2026-09-22 over EVERY clone in the estate -- + # 595 scanned, 553 carrying an origin/main. 432 reference this + # reusable workflow, but only 12 do so at a MUTABLE ref (@main), + # and a new step reaches ONLY those 12: a caller pinned at a SHA + # freezes this whole file, this step included, so it can never + # receive the step at all. The real gate was run against all 12: + # 12/12 rc=0, retired=0. Five slugs do carry the retired literal + # (tma-mark2, canonical-ums, the-nash-equilibrium, + # launch-scaffolder, trigger) and their overlap with the armed 12 + # is ZERO -- so arming this tier reds ZERO live callers. A + # known-answer positive control fired (rc=1) on three of those + # defective repos through the identical harness, so the twelve + # zeros are a real measurement and not a broken probe. # # stale-version -> WARNS, and does not block. A TIME-DEPENDENT # predicate: the gate compares against its own CURRENT_VERSION, so