Uh oh!
There was an error while loading. Please reload this page.
docs(scripts): the published-README baseline's $comment describes its contract instead of a seed count - #9764
Conversation
…tract, not a seed count (#9649) The block claimed the file was "seeded from the five instances #9532 measured". It shipped with 16 entries (PR #9546) and has since shrunk to 0 through #9602, #9615 and #9581, so the sentence was wrong on day one and the gap kept changing meaning as the ledger shrank. Rewritten to state the contract rather than a number: what an entry is (one known instance still awaiting repair, debt not exemption), that the count is read from `entries` and never asserted in prose, that `entries: []` is the success state rather than a corrupt or deletable file, and that absence from the file means measured-and-clean rather than unscanned -- which is what the plugin-audit negative control now says for every package. No baseline entry is added, removed or edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
✅ PM ACCEPT — #9649 / PR #9764Verified independently: 1 file ⭐ H1 — answered decisively, and the answer became the fixThe file cannot be deleted, and I confirmed the mechanism myself at if(!existsSync(abs)){thrownewError(`${BASELINE_REL} is missing; ${SELF} cannot tell debt from a new defect.`);}constparsed=JSON.parse(readFileSync(abs,'utf8'));if(!Array.isArray(parsed.entries))thrownewError(`${BASELINE_REL}: \`entries\` must be an array`);Absence is a hard "cannot verify" refusal — exit 1, never a clean pass. And the only shape constraint anywhere is That is the pair of facts that makes this card's answer non-obvious: the ledger is empty and mandatory. I asked "if it must exist, say why — nobody has written that down," and you put it in the second paragraph. The The rewrite is right on every constraint: contract, not count; the old sentence kept as the worked example of why counts do not belong in prose; empty stated as the success state with an explicit do-not-delete. ⭐ And the negative-control catch is the best thing here
A correct, deliberately-written note that became an instance of the very defect being fixed, because the file around it changed state. Nobody would find that by reading the card. Keeping the control but re-framing it — rather than deleting it or leaving it — preserves the guarantee (absence from the file never means unscanned) while removing the dependence on a populated ledger. That guarantee matters operationally: #9581's dev proved by positive control that plugin-audit is scanned, not skipped. Its silence is measurement. With the ledger now empty, the prose had stopped saying so. H3 — one other hit, and it is the same shape one ledger over#9766: H4 — filed rather than built, and it is #9747's shape exactly#9767: with the ledger empty, the gate's green line always ends "0 of the findings are call sites" — a ratio over an empty set, in the clause whose job is to say "clean, not unmeasured." That is precisely the ambiguity #9747 is about — a gate reporting On the gate not runThe scanning half is build-dependent (reads every workspace package's built type entry, and refuses rather than skips when Naming an unrun gate with its reason, its bound, and proof the tree was contended is the standard I want; it is now the norm across this lane's reports today. Verdict: ACCEPT. Arming once the two running gates converge. Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
…READ, not a ratio over an empty set (#9767) With the ledger at `entries: []` -- the success state PR #9764 recorded -- the green line ended `0 of the findings are call sites`: a ratio over an EMPTY SET, printed by the one clause whose whole job is to say "clean" rather than "unmeasured". It is #4690's ambiguity in output rather than in a verdict: "I scanned 60 documents and found nothing" and "I scanned nothing" rendered byte-identically, and the call-site half is the half most likely to quietly stop matching, being a text scan over prose. Each half now states its INPUT VOLUME, which no clean tree can make vacuous: 0 known instance(s) still in scripts/published-readme-exports.baseline.json. Import half: 283 documented symbol(s) checked against the exports their package publishes. Call-site half: 8 documented `X.y(...)` call(s) checked, on 225 import-bound name(s). A zero in "0 documented call(s) checked" is an alarm a reader can act on; a zero in "0 of the findings are call sites" said nothing at all. The ledger clause is kept verbatim -- "N known instance(s) STILL in <file>" carries the shrink-only direction in "still" -- and with a NON-EMPTY ledger it keeps the call-site split the old clause carried, now with the denominator that clause never printed: `2 known instance(s) still in <file> (1 of the 2 at a call site)`. The counts come from an accumulator `analyzeDocument` fills as it works: the same pass, no second scan. What the gate CHECKS, the population it reads, its baseline handling and its exit codes are unchanged; `analyzeDocument` still returns a plain array of findings, so every existing pin holds. Pinned in --self-test next to the remedy pin and for the same reason (the counts are interpolated, so a source scan proves nothing about the message): the rendered body for a scanned tree, the non-empty-ledger split with its denominator, and the regression itself -- a tree that read hundreds of claims and a tree that read nothing must not print the same body. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
Fixes#9649
The baseline's
$commentclaimed the file was "seeded from the five instances #9532measured". It shipped with 16 entries and has since shrunk to 0, so the sentence
was wrong on day one and its gap kept changing meaning as the ledger shrank. This rewrites
the provenance prose to state the file's contract and never a count.
Measured on
origin/main, one row per commit that touched the file:1c6da6eaff01c0ee2d890b38f04cd455c83bNo baseline entry is added, removed or edited. The diff touches only the
$commentarray; the
"entries": []line is unchanged (git diff -U0 | grep entriesshows no+/- on it).
What the new prose says
exemption. How many there are is deliberately not written down, with the reason stated
inline (the old sentence is quoted as the worked example) and the instruction to read
the count from
entries. Provenance survives, countless: seeded by PR ci: a published README's symbol claims are checked against the package's built exports #9546 from whatFive more published service READMEs document a
.configure()entry point and classes that exist nowhere in the repo — the same defect class as #9517, unfixed by it #9532 measured, reconciled down by every repair since. Written so it stays true on thenext shrink, and on a re-grow.
entries: []is what a fully repairedtree looks like, and the file must survive it. See H1.
kept, because it is correct and load-bearing, but re-framed. Its old framing ("the
sixth instance ... is deliberately ABSENT") drew a contrast against a populated ledger;
with
entries: []everything is absent, so the contrast had collapsed into exactly thedefect this card is about. The fact is preserved (repaired by PR docs(plugin-audit): the published README stops documenting an API, a row shape and an action vocabulary that do not exist (#9517) #9531 ahead of the gate,
reported clean by the PR that added the gate) and generalised: absence means measured and
clean, never skipped — which is the single most useful sentence to a reader of an empty
ledger.
H1 — can the file be deleted now that it is empty? No, and that is the reason the block should carry
Read from the loader, not assumed.
scripts/check-published-readme-exports.mjs:649-657:Deleting the file is a hard failure, not a clean pass — the third of the PM's three
options, a "cannot verify" refusal.
run()callsloadBaseline()unconditionally(line 794) on every path that is not the already-fatal unbuilt early return, and the
program wrapper (lines 1218-1224) catches the throw and renders it as
✗ check:published-readme-exports — ...with exit 1. So the empty ledger is a legalterminal state whose file is still required, and #9581's dev is right that no non-empty
assertion exists anywhere: the only shape constraint is
Array.isArray(parsed.entries).That reason was nowhere in the file; it is now the second paragraph of the block.
H2 — is the
$commentload-bearing to any tooling? No — it is prose for humansgrep -rn '\$comment'overscripts/,.github/and the package sources returns threehits and none of them reads this file:
packages/spec/scripts/build-spec-changes.ts:104writes a
$commentinto its own generated artifact,packages/drivers/driver-memory/src/memory-filter-vocabulary-refusal.test.ts:205lists$commentamong Mongo-ish operators the filter vocabulary must refuse, andscripts/check-engine-double-contract.mjs:80mentions a sibling baseline's$commentina source comment. Nothing parses it.
Worth stating because one candidate consumer looks like it should be one and is not:
scripts/check-ratchet-remedy-authority.mjsenforces the ⛔ MAINTAINER-ONLY authoritytoken of #8435, but its sweep glob is
scripts/*.{mjs,mts}and it reads string-literalcontent of gate sources, never JSON ledgers. The token is kept in the block anyway — it
is true, and it is what a maintainer reads before touching an entry — but nothing would
have gone red if the rewrite had dropped it. So the rewrite is written as documentation
for a human, at the length that needs.
H3 — sibling ledger sweep: one more carries the same defect
Every JSON ledger under
scripts/, read for a provenance/state claim and checked againstwhat the file currently holds:
durability-degradation.baseline.jsonentries: []startup-registry-verdict.baseline.jsonentries: []where-matcher-conformance.baseline.jsonfiles: {}engine-double-contract.baseline.jsondurability-read-invention.baseline.jsonreviewed-legitimate(a), not a (b)query-options-erasure-baseline.jsondriver-memory-census.ledger.jsonerror-status-unpinned-baseline.jsonnote, contract only, no counti18n-coverage-baseline.json,role-word-baseline.json,slot-lookup-baseline.json$commentat allSo the pattern is real but small: 1 of 12 siblings carries a drifted claim, and two
already document an empty ledger the way this card asks for — which is why the rewrite
borrows their shape rather than inventing one. Fixed here: only this file.
H4 — what the gate prints when the ledger is empty
The success branch (lines 824-829) prints, verbatim:
Judgement: the first clause reads correctly at zero — "0 known instance(s) still
in ..." carries the shrink-only direction in the word "still", and zero reads as "none
left" rather than "nothing scanned", because the header line immediately above it reports
the population that was actually read. The weak half is the second clause:
memberCheckscounts call sites among all findings, so on a clean tree with an empty ledger it always
prints
0 of the findings are call sites— a statistic about an empty set, which is theone place a reader could hear "the call-site half measured nothing". That is the #4690
ambiguity one layer down, and it is a real but small defect in a line that is otherwise
fine. Not built here: it changes gate output, which needs its own self-test pin, and
this card is scoped to the
$comment. Filed as a finding instead.Verification
Local gates re-run on the final commit,
7ab69e6b4:node -e require(...)on the ledger — parses;entries: 0, 40 comment linespnpm check:nul-bytes—check-nul-bytes: OK (scanned 6237 text file(s) ... no raw ASCII control bytes)(plus its 75-assertion self-test)node scripts/check-published-readme-exports.mjs --self-test— green (extraction, scoping, resolution and both analysis directions pinned)pnpm check:cross-package-test-inputs—All 33 self-test cases passed. OK: 12 package(s) read outside themselves, all declaredDerived with
node scripts/pm/dispatch-gates.mjs scripts/published-readme-exports.baseline.json,which names exactly
check:cross-package-test-inputsandcheck:published-readme-exports.The scanning half of
check:published-readme-exportsis build-dependent (it reads everyworkspace package's built type entry, and refuses rather than skipping when
dist/isabsent) and was not run locally — a full workspace build for a JSON comment change is
not a proportionate local cost, and CI runs it once on a built tree. The change cannot
reach the scan: it alters only
$commentstring content, and the loader's sole contract onthis file (
Array.isArray(parsed.entries)) is verified above.Nothing publishes — a comment in a
scripts/ledger — so no changeset;skip-changesetapplied.
Generated by Claude Code
Generated by Claude Code