Repository navigation
fix(scripts): type-check-coverage stale-entry messages carry no card-ending keyword - #9898
Merged
os-justin merged 1 commit intoSep 18, 2026
Conversation
…ending keyword
`scripts/check-type-check-coverage.mjs` emitted a GitHub closing keyword
immediately before an interpolated issue anchor at BOTH of its stale-entry
ratchets — rule 2 (`DEBT`) and rule 6 (`TEST_DEBT`) — inside messages a
contributor is told to quote into a pull-request body. Quoting one ends the
anchor card silently, from a body whose author was being careful: GitHub's
parser does no sentence parsing, so hedging the surrounding sentence buys
nothing. The `DEBT` tail was a byte-identical twin of the one already replaced
in `scripts/check-lint-coverage.mjs`.
Repaired onto the form already landed on the sibling gates
(`check-lint-coverage.mjs`, `check-action-forward-parity.mjs`): the keyword
becomes "can be ended", and the anchor is spelled `objectui#` rather than a bare
`#`, so the reference cannot match the closing grammar at all. The instruction
survives in full. A banner at each ratchet states the rule for whoever words the
next entry.
Both ledgers are empty, so neither message is reachable in this tree — which is
why the shape survived, not a reason to leave it: each is one ledger entry away
from rendering, and the entry that reopens it is written by whoever will need to
quote the message.
`scripts/__tests__/check-type-check-coverage-closing-keyword.test.ts` is the
pin, one rendered leg per site. It drives the exported `collect()` +
`auditPackages()` over throwaway package trees with a seeded ledger row and
asserts on the text the gate really produced — this gate takes its tables as a
parameter, so no copy-the-gate-into-a-workspace harness is needed. Every leg
carries a control that must fire: that the seeded ratchet is the one that
reported, and that the regex catches the pre-repair wording.
Anchors in the source are written unresolved, as `${debt[name].issue}` and
`${spec.issue}`, exactly as the file carries them.
Part of objectui#9598 — Part 1 only. The card's Part 2 (a differential emitter
gate over everything `scripts/` prints) is NOT built here: the maintainer ruled
a new required gate is the human floor and stands by no further gate
development, so this branch adds no `check:*` entry point, no package.json
script, no workflow and no ratchet.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EpHzwH4wTy5sd7ibkD2yq
os-justin
marked this pull request as ready for review
September 18, 2026 14:29
os-justin
deleted the
claude/issue-9598-type-check-coverage-closing-keyword
branch
September 18, 2026 15:18
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.
Fixes #9598
Part 1 only. The maintainer's ruling on this card (batch #152 item 3, letter 1) authorised the two-site repair and refused Part 2: 「a new required gate is the human floor and the maintainer's standing direction is no further gate development」. This branch therefore adds no
check:*entry point, nopackage.jsonscript, no workflow, no hook and no ratchet. See What this pull request deliberately does not do below.scripts/check-type-check-coverage.mjsemitted a GitHub closing keyword immediately before an interpolated issue anchor at both of its stale-entry ratchets — rule 2 (DEBT) and rule 6 (TEST_DEBT) — inside messages a contributor is told to quote into a pull-request body. Quoting one ends the anchor card silently, from a body whose author was being careful: GitHub's parser does no sentence parsing, so hedging the surrounding sentence buys nothing. TheDEBTtail was a byte-identical twin of the one already replaced inscripts/check-lint-coverage.mjs.Repaired onto the form already landed on the sibling gates (
check-lint-coverage.mjs,check-action-forward-parity.mjs): the keyword becomes "can be ended", and the anchor is spelledobjectui#rather than a bare#, so the reference cannot match the closing grammar at all. The instruction survives in full. A banner at each ratchet states the rule for whoever words the next entry.Both ledgers are empty, and that is why the shape survived
DEBTandTEST_DEBTare both{}in this tree, so neither message is reachable here. ⛔ Dormant is not fixed: each is one ledger entry away from rendering, and the entry that reopens it is written by exactly the person who will then need to quote the message. An empty ledger is why this class has now needed four one-at-a-time repairs (objectui#9535, objectui#9595, objectui#9597 and this one) rather than a reason to leave the fourth standing.Instrument readings — and the two counting rules do NOT agree
Run on the file's whole text, before and after. PRIMARY is the collapsed instrument (
\nescapes to spaces, string-chunk concatenation joined, physical wrapping flattened); CONTROL is the naive single-line match the card warns can under-count.CLOSING_TRIGGERthe four landed pins share byte-for-byte (interpolated or literal anchor, optionalowner/repo/objectui/objectstackqualifier)Two readings worth stating plainly:
check-action-forward-parity.mjs's, not this file's. Primary and control agree at every cell. A third, looser probe — any keyword within 40 characters of any#in the collapsed text, which would catch a sentence split by variable concatenation — also returns 3 before, on the same three sites. There is no split emitter here.TEST_DEBTtable comment: the nounfiximmediately before a bareobjectstack-prefixed anchor (issue 4074) — a reference form GitHub does not resolve, in a source comment that reaches no rendered diagnostic. It matches the shape the landed pins' regex keeps out and nothing else. ⛔ Out of scope here and not touched: the ruling authorised two sites, and both are emitters. Recorded below and reported to the dispatching seat. This is the same class the objectui#9755 author recorded as "shape-only, lowest severity" rather than repairing.Rendered before / after — both sites
Rendered by driving the real exported
collect()+auditPackages()over throwaway package trees with a seeded ledger row, not by reading the template.Site 1 — rule 2, stale
DEBTentryNAME now has a "type-check" script — delete its DEBT entry so the gap cannot reopen+${debt[name].issue ?(and close #${debt[name].issue} if it is done): ""}.NAME now has a "type-check" script — delete its DEBT entry so the gap cannot reopen+${debt[name].issue ?, and objectui#${debt[name].issue} can be ended once that work is done: ""}.Site 2 — rule 6, stale
TEST_DEBTentryNAME type-checks its tests now — delete its TEST_DEBT entry so the gap cannot reopen+${spec.issue ?(and close #${spec.issue} if the list is empty): ""}.NAME type-checks its tests now — delete its TEST_DEBT entry so the gap cannot reopen+${spec.issue ?, and objectui#${spec.issue} can be ended once the list is empty: ""}.The pin — one rendered leg per site, red before and green after
scripts/__tests__/check-type-check-coverage-closing-keyword.test.ts. This gate already exportscollect(repoRoot)andauditPackages(packages, tables)— the audit takes its ledgers as a parameter — so each leg seeds a ledger row directly and asserts on the text the gate really produced. ⛔ No copy-the-gate-into-a-throwaway-workspace harness, the one objectui#9595's pin had to build.Every leg carries a control that must fire: that the seeded ratchet is the one that reported (
toHaveLength(1)plus a distinguishing phrase), and that the regex catches the pre-repair wording. Without them a ratchet that printed nothing and a regex that matches nothing read exactly like a clean message.RED, against the pre-repair gate. The repaired file was replaced on disk with its pre-repair blob taken from the merge-base commit, the substitution proved by
git hash-objectagainst that commit's blob (f6747edd…on disk, matching), and the marker counts flipped (can be ended once2 to 0, the pre-repair tail 0 to 2) before anything was run:The one passing leg is the control — it asserts the regex fires on the wording this card replaced, so it must be green in both states. Restoration was proved by state, not by an exit code:
git checkout HEAD -- PATH(namingHEAD, never the bare form that would take the mutation back out of the index at exit 0), then the on-disk hash back tob47a3c40…andgit diff HEADempty.GREEN, on this branch:
Verification
Run as a contributor runs them, with no flag that narrows what is reported.
pnpm lint:root(the root-level eslint that coversscripts/; ⛔ no--no-inline-config, no narrowing flag)pnpm type-check:scripts(tsc -p tsconfig.scripts.json)pnpm type-check:coverage(this gate, on the real tree)pnpm exec vitest run scripts/(the whole affected suite)pnpm check:control-bytes·check:new-line-citations·check:test-path-roots·check:vi-mock-specifiers·check:entry-guardnode scripts/check-changeset-presence.mjsnode scripts/check-governed-queue-guard.mjs --teston both pathspnpm type-check:scripts's coverage of the new pin is measured, not assumed:tsc -p tsconfig.scripts.json --listFileslists the new test file (1 hit), with an already-covered sibling pin as the positive control (1 hit).No changeset. The gate's own criterion says none is owed —
scripts/is not published source of a released package — and objectui#9755, the byte-identical repair on the sibling gate, landed with the same two-file shape and no changeset.What this pull request deliberately does not do
check:*script, nopackage.jsonscript registration, no workflow, no hook, no ratchet of any kind. The diff is exactly two files.${X.issue ? … : ""}truthiness guard is not touched. objectui#9596 is about that shape going silently falsy; thereXis a module-level anchor constant with its own pin, here it is a per-entry field on a ledger row. Different question, different card, no assertions added about it.DEBTratchet inscripts/check-lint-coverage.mjsstates in the present tense that the same shape still stands incheck-type-check-coverage.mjsandcheck-action-forward-parity.mjs. objectui#9755 already falsified half of that sentence and this branch falsifies the other half. It is readable as a historical note about that pull request, so it is left for the dispatching seat to judge rather than reshaped here.Acceptance notes
fixbefore a bareobjectstack-prefixed anchor in theTEST_DEBTtable comment. Non-resolvable reference form, source comment, no rendered diagnostic. Successor who would meet it: whoever next edits that ledger's prose.check-lint-coverage.mjsdescribed above. Successor: the next reader of that gate's banner, or whoever lands the fifth repair in this class.?; the tree has one. Transcription only, no bearing on the repair.🤖 Generated with Claude Code
https://claude.ai/code/session_012EpHzwH4wTy5sd7ibkD2yq
Generated by Claude Code