Skip to content

Closes GT-668 — the proof that a guard had been seen failing was pinned to a branch, so it expired the day the fix landed - #486

Merged
beyondnetPeru merged 4 commits into
developfrom
gt-668-frozen-fixture
Aug 10, 2026
Merged

Closes GT-668 — the proof that a guard had been seen failing was pinned to a branch, so it expired the day the fix landed#486
beyondnetPeru merged 4 commits into
developfrom
gt-668-frozen-fixture

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

The defect, reproduced before it was acted on

GT-666 shipped a self-test whose most important case checks its guard against the real pre-fix artifact rather than a sketch of one. Its comment says why, and the reasoning is right:

"before this fix, read out of git rather than reconstructed … Reconstructed fixtures agree with whatever the author believed was wrong; this one cannot."

It obtained that artifact with git show ${PRE_FIX_REF}:iso-5055-mapping.json, PRE_FIX_REF defaulting to origin/develop. True while the fix lived on a branch. 59d62bae merged, origin/develop began serving the CORRECTED artifact, and a case written to count 64 findings started counting 0. Green on its own branch, red the moment the fix landed — blocking promotion PR #483 in Governance guards (GT-578).

Measured on develop at 59d62bae before touching anything:

ℹ tests 19 · pass 18 · fail 1
✖ the REAL pre-fix artifact, against the REAL packs, is RED — 16 rules, 4 findings each
  AssertionError: each of the 16 rules should fail the class rule, the naming rule and both false-claim rules
  0 !== 64

The worse half is the one nobody would have seen. The case carried a shallow-clone escape — if (before.status !== 0) return void assert.ok(true, 'SKIPPED: …'). Under fetch-depth: 1, a detached history, or a fork without origin/develop, the identical rot passes in silence. That is an escape hatch out of the one case establishing this guard has ever been observed failing rather than merely declared able to — the property 43-validate-guard-negative-fixtures exists to establish.

The fix: freeze the evidence, keep the intent

The intent was right; only the mechanism was wrong. A real pre-fix artifact is not the same thing as fetching one at test time, and the two were conflated.

The artifact is now committed. .harness/fixtures/standards-rule-class/iso-5055-mapping.pre-gt-666.json, taken from 01308346 (59d62bae^, the last commit carrying the defect), blob 6684e8a4. That is the fixtures home this repo already uses for committed CI evidence (.harness/fixtures/<subject>/, alongside rag-eval/) — no new home invented.

Not trimmed. All 412 rows kept, not just the 16 that carry the assertion. Trimming is an editorial act, and an editorial act on a fixture whose entire value is that no author's belief touched it is the thing the comment warns against. 284 KB, the same order as the live artifact already tracked.

One key added, and the claim is checkable rather than asserted. JSON has no comments, so the provenance header is a top-level _fixture string naming what the file is, where it came from, and that it is deliberately frozen. checkClassification reads only rules and summary.byClass, so it is inert. Drop _fixture, re-serialise, and the blob reproduces byte for byte against git cat-file blob 6684e8a4.

Deleted: the git show, the PRE_FIX_REF env var, the skip. No replacement skip. A shallow clone constrains a test that shells out to git, not one that reads a file in its own working tree — so an unreadable fixture is a genuine failure and red is the right outcome.

Nothing weakened; one case added

Assertions are the same two the case always made: 64 findings, 16 of them is classified \governance``, against the frozen fixture and today's live packs. Breakdown measured: 16 class + 16 "no international structural equivalent" + 16 "a governance invariant over Evolith artifacts" + 8/4/4 notes naming no standard.

The added case — the frozen fixture is still the DEFECT, not a refresh of the fixed mapping — closes the failure mode freezing creates: somebody regenerates the fixture from the live artifact and the repo's only observed failure of this guard becomes a copy of the thing it catches. Observed, not argued: the refresh was simulated by writing the live mapping into the fixture, and 2 of 20 cases turn red, the counting case among them.

Measured

Check Result
node --test .../65-…test.mjs 20 tests, 20 pass, 0 fail, 0 skipped (was 19 / 18 pass / 1 fail)
42-validate-guard-denominators 78 guards classified, 57/57 refuse a zero-element scan
43-validate-guard-negative-fixtures 54/54 exercised guards turned RED
ci-runner.mjs governance ✅ 17/17 scripts
08 / 09 / 46 / 04 / 01 / 49 pass; chain current and at a fixed point
core-domain (clean rebuild, tsbuildinfo removed) 157 suites / 1853 tests green

Coordination

No corpus file, no generator and no derived artifact was touched. build-iso-5055-mapping.mjs and iso-5055-mapping.json are deliberately untouched — a parallel session is changing analyser.adoptable on the four ISO5055-* rows. That work moves neither ruleClass nor the pack rule count, so the frozen 64/16 figures are unaffected by it; the number was not chased.

Registered GT-668, not GT-667. GT-667 is claimed by branch name (guard 50 claims by gt-NNN) on two concurrent branches — gt-667-analyser-adoptable and claude/gt-667-iso5055-adoptable — carrying the analyser.adoptable follow-on that GT-666's own closure record deferred. 49-validate-gap-id-allocation compares against origin/main and could not have seen either, so the id was taken by union of branches.

Not claimed

The frozen fixture pins the pre-fix side; the live side is still read from the repository, so these counts hold while the three packs keep their 16 rules (asserted elsewhere in the same file). This PR does not re-audit the other guard self-tests for the same moving-ref pattern — whether git show against a branch appears anywhere else was not measured.

🤖 Generated with Claude Code

beyondnetPeru and others added 2 commits August 9, 2026 22:52
…ed to a branch, so it expired the day the fix landed

GT-666's self-test kept one case that mattered more than the other eighteen:
the guard checked against the REAL pre-fix artifact, not a sketch of one. Its
comment says why, and it is right — «Reconstructed fixtures agree with whatever
the author believed was wrong; this one cannot.»

It got that artifact with `git show ${PRE_FIX_REF}:iso-5055-mapping.json`, and
PRE_FIX_REF defaulted to origin/develop. True while the fix lived on a branch.
59d62ba merged, origin/develop began serving the CORRECTED artifact, and a case
written to count 64 findings started counting 0 — green on its own branch, red
the moment it mattered, blocking promotion PR #483. Reproduced on develop before
anything was touched: 19 tests, 18 pass, `AssertionError: 0 !== 64`.

The worse half is the one nobody would have seen. The case carried a
shallow-clone escape — `if (before.status !== 0) return void assert.ok(true,
'SKIPPED: …')`. Under fetch-depth:1, a detached history, or a fork without
origin/develop, the identical rot PASSES IN SILENCE. That is an escape hatch out
of the one case establishing this guard has ever been OBSERVED failing rather
than declared able to.

So: keep the intent, freeze the evidence. The pre-fix mapping is committed at
.harness/fixtures/standards-rule-class/iso-5055-mapping.pre-gt-666.json, taken
from 0130834 (59d62ba^, blob 6684e8a) — the fixtures home this repo already
uses, not a new one. Not trimmed: all 412 rows, because trimming is an editorial
act on a fixture whose whole value is that no author's belief touched it. One
`_fixture` provenance key added (JSON has no comments) and the claim is
checkable, not asserted — drop it, re-serialise, and the blob reproduces byte
for byte.

The git show, the env var and the skip are deleted. No replacement skip: a
shallow clone constrains a test that shells out to git, not one that reads a
file in its own tree, so an unreadable fixture is a real failure and red is
correct.

Assertions unchanged and unweakened — 64 findings, 16 of them `is classified
governance`. One case ADDED, not relaxed: a fixture "refreshed" from the live
mapping is RED, and that was observed rather than argued. Simulating the refresh
turns 2 of 20 cases red, so the negative fixture cannot quietly become a copy of
the artifact it exists to catch.

Measured: node --test 20/20 pass, 0 skipped. 42 -> 78 guards classified, 57/57
refuse a zero-element scan. 43 -> 54/54 exercised guards turned red. core-domain
clean rebuild, 157 suites / 1853 tests green. 01, 04, 09, 46 pass; ci-runner
governance fails only on this commit's own PENDING closureCommit.

No corpus file, no generator and no derived artifact touched — deliberately off
build-iso-5055-mapping.mjs and iso-5055-mapping.json, where a parallel session
is changing analyser.adoptable. That work moves neither ruleClass nor the pack
rule count, so the frozen 64/16 figures are unaffected by it.

Registered GT-668, not GT-667: GT-667 is claimed by branch name on two
concurrent branches (gt-667-analyser-adoptable, claude/gt-667-iso5055-adoptable)
carrying that follow-on. Guard 49 compares against origin/main and could not
have seen either, so the id was taken by union of branches.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a620ed3 is the commit with the frozen fixture and the reworked self-test.
08-validate-tracking now passes: 665 gaps, 641/641 EN/ES catalog sections,
635 closure records.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner August 10, 2026 03:54
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

Copy link
Copy Markdown

📊 Bilingual Coverage Impact

PR Changes

  • Paired EN/ES files modified: 4
  • New EN files needing ES translation: 0

Repository Coverage

Metric Value
Total EN files 527
Total ES files 501
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

beyondnetPeru and others added 2 commits August 9, 2026 22:56
That paragraph said, in the present tense, that the self-test "reads the pre-fix
iso-5055-mapping.json out of git" — which stopped being true one commit later.
Left alone it is the same class of thing GT-668 is about: a document whose claim
quietly diverged from the artifact without anyone editing it.

The counts it reports (64 findings, 16 rules x 4 broken rules) are unchanged and
still measured, so only the mechanism is marked superseded. EN and ES both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`develop` gained GT-667 (#487) while this branch was in review, and the two
collide on exactly the four board artifacts they both append to: the EN/ES
tracking rows, the EN/ES catalog entries and the closure records. Every conflict
is ADDITIVE — two gaps each adding their own row — so both sides are kept and
neither is chosen over the other. Progress recomputed to 654 / 666: develop's
653 / 665 plus this branch's GT-668.

The interesting part is what did NOT move. GT-667 regenerates
`iso-5055-mapping.json` (it derives `analyser.adoptable` for the four ISO5055-*
rows), and this branch's whole subject is a FROZEN copy of that artifact from
before GT-666. If the freeze were doing its job the regeneration should not
reach it, and the self-test's 64/16 figures should be untouched. Measured after
the merge: 20/20, unchanged. The fixture is a snapshot, not a mirror — which is
the property GT-668 exists to establish, now demonstrated against a real
concurrent change rather than argued.

Verified on the merged tree: tracking 666 gaps / 642 catalog sections / 636
closure records, derived chain current and at a fixed point, bilingual parity,
docs, and governance 17/17.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru merged commit a093d27 into develop Aug 10, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant