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
Conversation
…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>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📊 Bilingual Coverage ImpactPR Changes
Repository Coverage
✅ Good: All EN changes have ES counterparts. Generated by GitHub Actions |
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect, reproduced before it was acted on
GT-666shipped 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:It obtained that artifact with
git show ${PRE_FIX_REF}:iso-5055-mapping.json,PRE_FIX_REFdefaulting toorigin/develop. True while the fix lived on a branch.59d62baemerged,origin/developbegan 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 inGovernance guards (GT-578).Measured on
developat59d62baebefore touching anything: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: …'). Underfetch-depth: 1, a detached history, or a fork withoutorigin/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 property43-validate-guard-negative-fixturesexists 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 from01308346(59d62bae^, the last commit carrying the defect), blob6684e8a4. That is the fixtures home this repo already uses for committed CI evidence (.harness/fixtures/<subject>/, alongsiderag-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
_fixturestring naming what the file is, where it came from, and that it is deliberately frozen.checkClassificationreads onlyrulesandsummary.byClass, so it is inert. Drop_fixture, re-serialise, and the blob reproduces byte for byte againstgit cat-file blob 6684e8a4.Deleted: the
git show, thePRE_FIX_REFenv var, the skip. No replacement skip. A shallow clone constrains a test that shells out togit, 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
node --test .../65-…test.mjs42-validate-guard-denominators43-validate-guard-negative-fixturesci-runner.mjs governance08/09/46/04/01/49tsbuildinforemoved)Coordination
No corpus file, no generator and no derived artifact was touched.
build-iso-5055-mapping.mjsandiso-5055-mapping.jsonare deliberately untouched — a parallel session is changinganalyser.adoptableon the fourISO5055-*rows. That work moves neitherruleClassnor the pack rule count, so the frozen 64/16 figures are unaffected by it; the number was not chased.Registered
GT-668, notGT-667.GT-667is claimed by branch name (guard 50 claims bygt-NNN) on two concurrent branches —gt-667-analyser-adoptableandclaude/gt-667-iso5055-adoptable— carrying theanalyser.adoptablefollow-on thatGT-666's own closure record deferred.49-validate-gap-id-allocationcompares againstorigin/mainand 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 showagainst a branch appears anywhere else was not measured.🤖 Generated with Claude Code