Skip to content

chore(docs,scripts,ci): track the register's live view and cross-check it - #2080

Merged
dudarenok-maker merged 4 commits into
mainfrom
chore/scripts-register-twin-home
Aug 1, 2026
Merged

chore(docs,scripts,ci): track the register's live view and cross-check it#2080
dudarenok-maker merged 4 commits into
mainfrom
chore/scripts-register-twin-home

Conversation

@dudarenok-maker

@dudarenok-maker dudarenok-maker commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

The on-box acceptance register is two files: docs/testing/onbox-acceptance-register.md, and a hand-authored styled HTML page published to a fixed artifact URL. Only the markdown was in the repo — the live view lived in whichever session scratchpad last built it, so it could only be updated by an agent that still happened to have it, and was one cleanup away from unrecoverable.

The live view is now tracked at docs/testing/onbox-acceptance-register-live-view.html (920 lines). The name states what the file is rather than differing from the markdown by one character — that near-identity is the slip that let four consecutive publishes replace the styled page with raw markdown rendering (#2075). Its head comment says it is the publish source, that the markdown must never be published in its place, and why it deliberately isn't a complete HTML document (the publisher supplies the <!doctype>/<head>/<body> skeleton, so one here would nest).

npm run check:onbox-register now compares the two files. Owed total, per-group glance counts, each group header's own row count, and the row IDs group by group. That last one matters: the 2026-07-28 drift was a row missing on one side and a branch-only row on the other, and they cancelled in the total — a count-only check reads green on it. All three markup markers the parser depends on error when they stop matching, so a future restyle fails loudly instead of turning the comparison into a silent no-op.

Both docs surfaces that instruct an agent — CLAUDE.md step 3 and the register's own "Live view" section — now name the file to publish rather than only the URL to pass, and state what the check does not cover.

Wiring

Three places, because a check that doesn't run on the diff that breaks it is decoration:

  • onbox-register-check.yml path filter — a live-view-only edit must fire it;
  • verify.yml's hooks scope regex — same, for the test:hooks leg;
  • verify-cache.mjs's test:hooks extraFiles — the test reads both register files as text at runtime, so without them a register-only diff prints [cached] and the cross-check sits stale-green locally. Same trap already documented there for RELEASE_NOTES.md and bump-version.mjs.

The live view is .prettierignored: it is authored to be published verbatim, and Prettier splitting an element's text across lines breaks the checker's element-level patterns.

Review round 2 — 93763526

An independent adversarial pass found two confirmed silent-pass holes in the first commit and one doc overstatement. All folded, plus the cheap findings:

  • Section split missed modifier classes. The marker ended at the closing quote, so class="group is-blocked" and class="group is-soft" — the real file's last two sections — never matched: 7 blocks parsed for 9 elements. Their content folded into the preceding group's block, so the gtag filter never actually saw them (the comment claiming it did was false), a lettered row added to either would have been attributed to the wrong group, and a cosmetic modifier class on any other section made its whole row list read as extra rows. Now matches the whole class attribute.
  • Duplicate group letters were accepted on both surfaces. Map.set is last-writer-wins with no duplicate check, so a glance table listing B twice — wrong count first — passed, and a duplicated section rendered the group twice with nothing reporting it. The markdown side already guards this; both live-view parsers now mirror it.
  • checkLiveView dropped the unterminated-fence bail-out checkRegister deliberately has. A stray fence truncates the markdown, so the comparison demanded the deletion of five sections that were fine.
  • Row-level messages now name the section they compared — a row filed under the wrong group used to read as two contradicting errors with nothing saying where it sat.
  • Five error branches had no test and survived deletion. All 18 are now mutation-verified.
  • The Blocked-section test asserted a shape the real document does not have (its fixture used an unmodified class), so it passed for an incidental reason. It now pins the modifier-class handling itself.
  • CLAUDE.md claimed the checker cross-checks "oldest debt" — it reads the owed total, per-group counts and row IDs only. Both doc surfaces now say what is and isn't covered.

Review round 3 — 932fa85d

A second adversarial pass verified all seven round-1 fixes are real, and could not construct an edit that drifts the checked surfaces past the gate. It found one more silent pass of the same shape, plus two claims wider than the code:

  • Invalid row IDs were dropped, not reported. The shape filter discarded any num that wasn't <Letter><N> before comparing, so a live-view row numbered A31b, a32 or A&nbsp;32 vanished from the check entirely — the page carried a row the register did not, and the run stayed green. The markdown side rejects the identical violation loudly. Now mirrored.
  • Three parser edges hardened, each verified against the real committed page: the section marker no longer depends on attribute order (<section id="…" class="group is-blocked"> silently re-opened the fold the previous commit closed) and no longer matches siblings like grouping/group-nav; glance rows carrying an attribute are no longer invisible, which had let an added group row pass; and HTML comments are blanked before parsing, so commenting out a section reads as missing rather than passing, and a commented-out row is no longer counted as real.
  • "All 18 branches mutation-verified" was wrong — two survived: nothing fed checkLiveView a markdown without the glance heading, and the zero-sections test asserted .some rather than the exact list, leaving its early return unpinned. Both covered now.
  • The register claimed "an edit here that misses the live view fails CI". A wording-only edit does not — and that is the most common edit this file gets. Its edges are now spelled out rather than implied.

Test plan

32 new cases in scripts/tests/check-onbox-register.test.mjs (26 → 58 in that file; npm run test:hooks 824 pass, 0 fail), each mutating one aspect of a coherent fixture pair:

  • stale owed total; stale glance count; stale group-header count; missing gcount
  • a row in the register but not the live view; the reverse; both at once with counts still matching — the 2026-07-28 shape; a duplicated row; a row filed under the wrong section
  • a group missing from either glance table; a group section present on only one side; a malformed glance row; a group repeated in the glance table (wrong count first) or as a section
  • an unterminated fence bails out instead of condemning real sections
  • three vacuous-pass guards: renaming n owed / table.glance / section.group must error
  • a modifier-classed section is still parsed, and a modifier-classed Blocked section's rows never leak into the group above it — including with the class attribute written last
  • an invalid row ID is reported rather than dropped; a grouping decoy section is not mistaken for a group; a commented-out section reads as missing while a commented-out row is not counted; an added glance row carrying an attribute is still seen
  • and the real committed pair agrees — the only case that proves the parsers fit the real hand-authored markup

Mutation-verified: all 21 errors.push/early-return branches in checkLiveView neutralised in turn, suite re-run each time. No survivors.

Checklist notes: no regression plan (tooling only, no behaviour change); release notes skipped — process/CI change with no user- or operator-visible delta; on-box acceptance unaffected — this changes how the register is checked, not what it owes, and its counts are unchanged.

Closes #2079. Follows #2076 (wording fix) and #2075 (the incident).

dudarenok-maker and others added 4 commits August 1, 2026 18:14
…k it

The on-box acceptance register is two files: the markdown, and a
hand-authored styled HTML page published to a fixed artifact URL. Only
the markdown was in the repo — the live view lived in whichever session
scratchpad last built it, so it could only be updated by an agent that
still had it, and was one cleanup away from unrecoverable.

Track it as docs/testing/onbox-acceptance-register-live-view.html. The
name states what the file is rather than differing from the markdown by
one character, which is the slip that let four consecutive publishes
replace the styled page with raw markdown rendering (#2075).

check:onbox-register now compares the two: owed total, per-group glance
counts, each group header's own count, and the row IDs per group — so
2026-07-28's drift (a row missing on one side, a branch-only row on the
other, cancelling in the total) fails instead of reading green. The three
markers the parser depends on each error when they stop matching, so a
restyle cannot turn the comparison into a silent no-op.

Wired into the paths that actually carry the change: the workflow's path
filter, verify.yml's hooks-scope regex, and verify-cache's test:hooks
extraFiles — the last because the test reads both files at runtime, so
without it a register-only diff prints [cached] and sits stale-green.

The live view is prettier-ignored: it is authored to be published
verbatim, and reflowing markup the checker matches line-wise would break
both.

Closes #2079

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Independent review of PR #2080 found two confirmed ways the new check
could report green on the exact surface it exists to protect, plus a doc
claim wider than the code.

The section-split marker ended at the closing quote, so it missed the
real file's `class="group is-blocked"` and `class="group is-soft"`
sections — 7 blocks parsed for 9 elements. Their content folded into the
preceding group's block, which meant the gtag filter never actually saw
them (the comment saying it did was false), a lettered row added to
either would have been attributed to the wrong group, and a purely
cosmetic modifier class on any other section made its whole row list
read as extra rows. Match the whole class attribute instead.

Both parsers used Map.set on a letter with no duplicate check, so a
repeated group kept whichever row came last: a glance table listing B
twice, wrong count first, passed. The markdown side already guards this;
mirror it on both.

Also: checkLiveView now honours the unterminated-fence bail-out that
checkRegister deliberately has — without it a stray fence made the check
demand the deletion of five sections that were fine — and the row-level
messages name the section they compared, so a row filed under the wrong
group no longer reads as two contradicting errors.

Five branches had no test and survived deletion; all 18 are now
mutation-verified. The Blocked-section test asserted a shape the real
document does not have (its fixture used an unmodified class), so it
passed for an incidental reason; it now pins the modifier-class handling
itself.

CLAUDE.md claimed the checker cross-checks "oldest debt" — it reads only
the owed total, the per-group counts and the row IDs. Both doc surfaces
now say what is and is not covered.

Refs #2079

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng them

Round 2 of review found one more silent pass of the same shape as the
first two, plus two claims wider than the code.

The row-ID shape filter discarded any `num` that was not `<Letter><N>`
BEFORE comparing, so a live-view row numbered `A31b`, `a32` or
`A&nbsp;32` vanished from the check entirely: the page carried a row the
register did not and the run stayed green. The markdown side rejects the
identical convention violation loudly (`### A19b`). Collect and report
them instead, mirroring invalidRowHeadings.

Three parser edges hardened while here, each verified against the real
committed page: the section marker no longer depends on attribute ORDER
(`<section id="…" class="group is-blocked">` silently re-opened the fold
the last commit fixed) and no longer matches sibling names like
`grouping`/`group-nav`; glance rows carrying an attribute are no longer
invisible, which had made an ADDED group row pass; and HTML comments are
blanked before parsing, so commenting out a section reads as missing
rather than passing, and a commented-out row is no longer counted.

Two branches survived the last commit's mutation drill, so "all 18 are
now mutation-verified" was wrong: nothing fed checkLiveView a markdown
without the glance heading, and the zero-sections test asserted `.some`
rather than the exact list, leaving its early return unpinned. Both now
covered — 21 branches mutated, no survivors.

The register also claimed "an edit here that misses the live view fails
CI". A wording-only edit does not, and that is the most common edit this
file gets. Its edges are now spelled out rather than implied.

Refs #2079

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dudarenok-maker
dudarenok-maker merged commit 31005ce into main Aug 1, 2026
15 checks passed
@dudarenok-maker
dudarenok-maker deleted the chore/scripts-register-twin-home branch August 1, 2026 09:05
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ops — track the on-box register's live view in the repo and cross-check it against the markdown

1 participant