Skip to content

Close the remaining #112 coverage gaps - #118

Merged
gvonnessi merged 1 commit into
mainfrom
conformance/b1b-3c-1a-remaining-coverage
Aug 28, 2026
Merged

gvonnessi merged 1 commit into
mainfrom
conformance/b1b-3c-1a-remaining-coverage

Conversation

@gvonnessi

@gvonnessi gvonnessi commented Aug 28, 2026 •

Copy link
Copy Markdown
Collaborator

Closes the four remaining coverage items on #112. Does not auto-close it — four deferrals recorded there remain open: OQ-012 (the live semantic:ref false positive), the check:enumeration-coverage backtick gate, the rewriteIds→resolver compile-time link, and the anchorTargets defaulting.

Summary

The four items shared one shape: a check that exists but that nothing can prove is doing any work.

The document oracle's clean-case guards were unmutatable. An arm of confirm_clean runs only on a CLEAN fixture, and a fixture carrying the defect that arm looks for is by definition not clean — so no corpus case ever reaches it with its defect present. Deleting any one of the four arms B1b-3c-1a added left every gate green, and each deletion made confirm_clean return "clean" rather than being caught by a later arm. It now has a selftest() driving all 37 refusal arms, asserting the specific refusal message (it returns on its first failing arm, so "was refused at all" is satisfied by any later one).

Crucially it ratchets rather than restoring a snapshot: the arms are enumerated from the function's own AST and the drivers traced, so an arm added later with no driver fails instead of being silent. Inserting one was measured to leave every gate green before this — the same defect class the table exists to close, one level up.

A wrong hash was undetectable on any non-clean fixture. The fixture comparator is a subset check, so an unexpected hash mismatch is tolerated outright; and on a case already expecting WARNING or REJECT it cannot move the disposition either. Every hand-computed hash in fixture-corpus.ts was therefore unverified on any fixture that expects a finding. check:fixtures gains a coherence pass over every {path, hash} pair a manifest declares — content part, asset index, presentation layer and config slot alike. Corrupting one non-clean fixture's asset-index hash was measured invisible to check:conformance, check:fixtures, check:document-oracle and check:document-id together.

The Dublin Core array shape had no case. Document Hashing 4.3.1 projects creator, subject and language as arrays; every other DC part in the corpus authors a scalar, so the array shape never reached 4.3.2's scan. One fixture, plus verdict tests over all three terms — pinning only creator was measured to leave the other two unscanned in both implementations with the corpus green.

Run-flush had no negative control. The existing fixture pins that a run is reported at a non-text element, but not that the flush separates — deleting the reset leaves it green, since the longer merged run still violates NFC. The control is a pair carrying the same four text-node values in a blockquote, differing only by a paragraph between the second and third.

A reader fix that was written and then reverted

The panel found a real defect in the shipped reader: a config-slot reference whose hash is mistyped, or which carries a member beyond {path, hash}, is dropped from the manifest projection with nothing reported — a one-character manifest edit removes a side file's tamper-evidence and every gate stays green.

A fix was written and reviewed, then reverted from this branch. A dedicated three-lens cycle found that reusing CDX-E-MANIFEST-REFERENCE-MALFORMED has no precedent (measured: an asset category with an extra member reports nothing) and no note, that the fix closed the two shapes that code's published summary covers least while missing the two it names, and that REJECT is inferred across an asymmetry the specification draws deliberately in three separate places — §9.7, §7.3's open/closed lists, and PR #115's disposition: null precedent from a fortnight earlier.

Publishing a disposition is a one-way door under the append-only compatibilityPolicy, so the defect and every measurement are recorded in #120 for a specification decision rather than shipped on a premise the spec contradicts.

Numbers

Checks 366 (209 vectors + 157 fixtures)
Oracle selftest 52 drivers reaching all 37 refusal arms
Hash coherence 143 declared hashes across 123 document fixtures
test:document-verdict 76
errors.json unchanged, v0.14 / 86 codes
suiteVersion 0.2.2 to 0.2.3 (patch: added cases, no changed expectation)

Review

Three /review-fix cycles, twelve reviewer agents. Cycle 1 (guidelines, bugs, architecture, tests, errors, claims) raised roughly 36 findings; Cycle 2 (bugs, architecture, errors) returned every claim HELD and found nine more; Cycle 3 was a dedicated panel on the reader-fix slice, which had been written after Cycle 2 closed and so had never been reviewed — it returned five findings above the blocking threshold and is why that slice was reverted.

No finding in the landed work was a defect in the shipped reference reader — every one was in the checking machinery this branch adds, including three untrue comments and two cases where a new check reproduced the very silence it was written to remove. Three are worth naming because only mutation caught them:

  • the new hash gate could print a tick having compared zero fixtures;
  • a blake3 hash threw uncaught, killing the gate and both independent oracles with it;
  • the ratchet's AST walk descended into nested functions, producing an arm no driver could ever satisfy.

Test plan

  • All 32 CI-parity steps pass locally on the committed tree
  • Deleting any of the 37 confirm_clean arms fails the selftest (0 survived)
  • Inserting a new arm with no driver fails the selftest
  • Corrupting a non-clean fixture's asset-index, presentation or config-slot hash is caught, and was green everywhere before
  • Deleting the run-flush reset fails only the new test; 366/366 and both oracles stay green
  • The reverted slice leaves no residue: warn-citation-and-glossary-dangling round-trips byte-identically and the corpus is back to 157 fixtures

The four items left open on #112 shared one shape: a check that exists but
that nothing can prove is doing any work.

An arm of the document oracle's `confirm_clean` runs only on a CLEAN fixture,
and a fixture carrying the defect that arm looks for is by definition not
clean, so no corpus case ever reaches it with its defect present. Deleting any
one of the four arms B1b-3c-1a added left every gate green. The oracle gains a
selftest driving all 37 refusal arms from the malformed corpus, and — because a
table restoring today's coverage adds nothing that keeps tomorrow's arm honest —
the arms are enumerated from the function's own AST and the drivers traced, so a
new arm with no driver fails rather than passing quietly. Inserting one was
measured to leave every gate green before this.

`check:fixtures` gains a hash-coherence pass over every {path, hash} pair a
manifest declares. The fixture comparator is a subset check, so an unexpected
hash mismatch is tolerated outright, and on a case already expecting WARNING or
REJECT it cannot move the disposition either — so every hand-computed hash in
the corpus was unverified on any fixture that expects a finding. Corrupting one
non-clean fixture's asset-index hash was invisible to check:conformance,
check:fixtures, check:document-oracle and check:document-id together.

One fixture covers the Dublin Core array shape, which no case reached: §4.3.1
projects creator, subject and language as arrays, and every other DC part in the
corpus authors a scalar. Four verdict tests cover what the corpus cannot
express, including the negative control for the concatenation scan's run flush —
the existing fixture pins that a run is reported at a non-text element, but not
that the flush separates.

A fix for a related reader defect — a config-slot reference that declares a hash
and achieves no binding, reported by nothing — was written and then reverted from
this branch. A three-lens panel found the reuse of CDX-E-MANIFEST-REFERENCE-MALFORMED
has no precedent and no note, that the fix closed the two shapes that code's
published summary covers least, and that REJECT is inferred across an asymmetry
the specification draws deliberately in three separate places. Publishing a
disposition is a one-way door, so the defect and all the measurements are recorded
in #120 for a specification decision instead.

errors.json stays at v0.14/86; suiteVersion 0.2.2 -> 0.2.3, the patch position
being where added cases land pre-1.0.
@gvonnessi
gvonnessi force-pushed the conformance/b1b-3c-1a-remaining-coverage branch from b8080ce to ec5673f Compare August 28, 2026 20:34
@gvonnessi gvonnessi changed the title Close the remaining #112 coverage gaps and a config-slot binding escape Close the remaining #112 coverage gaps Aug 28, 2026
@gvonnessi
gvonnessi merged commit 991e830 into main Aug 28, 2026
2 checks passed
@gvonnessi
gvonnessi deleted the conformance/b1b-3c-1a-remaining-coverage branch August 28, 2026 20:39
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