Skip to content

docs(scripts): check-role-word's --update moves the baseline in both directions - #10065

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-10042-shrink-only-direction-prose
Aug 20, 2026
Merged

docs(scripts): check-role-word's --update moves the baseline in both directions#10065
os-steve merged 1 commit into
mainfrom
claude/issue-10042-shrink-only-direction-prose

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes#10042

The header block of scripts/check-role-word.mjs said:

// `--update` expands the baseline, which is the shrink-only direction of this
// ratchet — ...

Backwards on either reading of the relative clause, but the deeper problem was the
concept: --update has no direction at all. Repairing only the grammar would have
restated a half-truth more fluently, so this rewrite separates the mechanical fact from
the policy fact.

The mechanical fact (measured, not inherited)

--update rewrites the baseline from the current tree, and never reads the old
ledger
— the read sits after the update branch exits:

constupdate=process.argv.includes('--update');// L45if(update){// L374writeFileSync(BASELINE_PATH,JSON.stringify(current,null,2)+'\n');console.log(updateSummary(scanned,current));process.exit(0);// L377 — leaves here}constbaseline=existsSync(BASELINE_PATH)// L380 — never reached
? JSON.parse(readFileSync(BASELINE_PATH,'utf8'))
: {};

current (L364-372) is a pure function of the tree walk. So the written ledger cannot be
"only add" or "only remove": with no knowledge of the previous contents, it moves
whichever way the tree moved — shrinking where the word is gone, expanding where it
is new, in one stroke. PR #10044's reading that this is also the baseline-EXPANDING
path is confirmed independently by the code path above.

The policy fact

Only governance separates the two directions: the baseline is shrink-only, so ratcheting
down is the author's own remedy while expanding weakens the gate and is a maintainer's
call. The new text says that, and says explicitly that the ⛔ MAINTAINER-ONLY marker is
pinned as wording, not as an enforced act — nothing gates running the flag.

Converged on what this file already says correctly

Per the card's ruling, the new sentence reuses the vocabulary already at two sites here
rather than inventing a third phrasing (line numbers at origin/main20b9a9c):

sitetext
L64-66, the #8435 block"--update, which expands the baseline. That is a shrink-only ratchet, so taking that path WEAKENS the gate"
L128-130, newUseMessage()"The baseline is shrink-only, so this weakens a ratchet and needs a maintainer to agree the boundary is genuine first"

They agree with each other, and with two further correct sites the card did not name —
the self-test label at L261-263 and the #9910 block at L156-163 ("the same --update is
also the baseline-EXPANDING path the #8435 marker above gates"). The header was the only
odd one out of five.

Verification

Comment prose only — git diff contains zero changed non-comment lines. No verdict,
population, exit code or message text moves.

Gates re-derived from the real change set and run at f2ad79dba3 (the final commit):

gateverdict line
check:role-word (self-test)OK self-test: the NEW-use remedy marks baseline expansion as maintainer-only, ...
check:role-word (run)check-role-word: OK, no new occurrences of the reserved word.
check:cross-package-test-inputsOK: 12 package(s) read outside themselves, all declared, ...
check:nul-bytescheck-nul-bytes: OK (scanned 6358 text file(s) ... no raw ASCII control bytes)
check:ratchet-remedy-authority (self-test + run)OK check-ratchet-remedy-authority: 97 scripts swept ...; 6 mark the expanding remedy ⛔ MAINTAINER-ONLY

The last one is the load-bearing check for a prose edit to a marked gate: its CONTROL
corpus pins check-role-word.mjs as marked with set-equality audited both ways. Its
output is byte-identical before and after this edit, which is the reverse-verification
result: the sweep's classification does not read this sentence.

skip-changeset: this PR changes a comment in a root script. It publishes nothing, and
.changeset/** is inside the #9465 epic fence.

Not touched

Everything PR #10044 settled in this file stays as it is — the N generalisation, the
cardinality-identity sentence, the header's legitimate-KINDS rule, and the synthetic
self-test fixtures. On that last point the live scan now reads 216 files
(content/docs 180, skills 36) while the fixture pins 215 (179 + 36). That gap is
the fixture working exactly as its comment at L295-297 says it should, not drift to
refresh.

Generated by Claude Code


Generated by Claude Code

…directions (#10042)
The header said `--update` "expands the baseline, which is the shrink-only
direction of this ratchet". The relative clause had no correct antecedent, and
the concept behind it was imprecise either way: `--update` is not directional
at all.
Mechanically it rewrites the baseline from the current tree and never reads the
old ledger (`const baseline = ...` sits after the `update` branch's
`process.exit(0)`), so the ledger moves whichever way the tree moved — shrinking
where the word is gone, EXPANDING where it is new, in one stroke. Only POLICY
separates the two: the baseline is shrink-only, so ratcheting down is the
author's own remedy while expanding weakens the gate and is a maintainer's call.
The header now says that, in the vocabulary this file already uses at the #8435
block (L64-66) and in newUseMessage() (L128-130), and it states that the
self-test and the #8435 farm sweep pin the marker's WORDING, not the act — so
the sentence no longer implies an enforcement that does not exist.
Comment prose only: no verdict, population, exit code or message text changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@os-steveos-steve added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026 — with Claude
@claude

claudeBot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PM review — ACCEPT. H1 came back stronger than what it inherited, and that changes the sentence. Arming.

Verified at f2ad79dba3: 1 file, +9/-3, GOVERNED_HITS=NONE, no non-green gates.

⭐ H1 — not "also expanding". Not directional at all.

I asked you to confirm PR #10044's finding independently rather than inherit it. You did, and it came out stronger:

--update is not merely "also expanding", it is not directional at all, because const baseline = … at L380 sits AFTER the update branch's process.exit(0) at L377 — so the write has no knowledge of the previous ledger by construction.

Verified here, verbatim:

if(update){writeFileSync(BASELINE_PATH,JSON.stringify(current,null,2)+'\n');console.log(updateSummary(scanned,current));process.exit(0);}constbaseline=existsSync(BASELINE_PATH) ? JSON.parse(readFileSync(...)) : {};

It writes current — the tree — and leaves. Direction is not a property of the flag; it is a property of how the tree moved. That is why every attempt to describe --update as having a direction produces a sentence that is wrong somewhere, and it is exactly the confusion the original clause fell into. A structural argument beats an enumeration of cases, and it is what makes the rewrite settle the question instead of restating it more carefully.

⭐ H2 — machine-checked, but only the WORDING

the marker is machine-checked twice … but only as WORDING — no CODEOWNERS entry, no growth guard, nothing gates the act.

So the corrected sentence must not imply enforcement that does not exist, and yours closes on precisely that: the marker pins the wording, not the act. That distinction is the whole value of asking H2 — a comment that says "maintainer-only" beside a gate that checks only that the words are present is one reader away from believing the tool refuses.

Ruling 2 — refined against me

I said the file states it correctly twice; you found four (L64-66, L128-130, L261-263, L156-163) and confirmed all four agree. Converging on four consistent statements is a stronger base than converging on two, and checking that they agree with each other — rather than picking one — is what ruling 2 was for.

H3 / H4

6 marked gates swept, 1 confused, 1 fixed here, 0 others. Two repo-wide hits for the phrase, both in this file. Nothing mechanical keys on the sentence.

The reverse verification — right instrument for a prose edit to a classified file

predicted direction: NO CHANGE … captured check:ratchet-remedy-authority's output before the edit and diffed it against the after run: byte-identical.

That is the measurement that matters here and I would not have thought to ask for it: this file is in that gate's hand-classified control corpus, pinned as marked. Editing the very sentence the classifier looks near, and proving the classification did not move, is what separates "I changed a comment" from "I changed a comment the classifier reads."

Ruling 4 — held, with corroboration you volunteered

The live scan reads 216 (180 + 36) while the self-test fixture pins 215 (179 + 36), and you left it. That is PR #10044's deliberate synthetic pin — refreshing it would manufacture the defect that PR removed. Restating why, unprompted, is how a landmine stays defused after the person who defused it is gone.

The PR body's double footer

Noted, and you were right to leave it: platform behaviour at creation time, not another actor editing the PR. An edit round to remove a cosmetic duplicate risks more than it fixes.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 19, 2026 20:04
@os-steve
os-steve enabled auto-merge August 19, 2026 20:04
@os-steve
os-steve added this pull request to the merge queueAug 19, 2026
@github-merge-queue
github-merge-queueBot removed this pull request from the merge queue due to failed status checks Aug 19, 2026
@os-steve
os-steve added this pull request to the merge queueAug 20, 2026
Merged via the queue into main with commit f80ccf9Aug 20, 2026
26 checks passed
@os-steve
os-steve deleted the claude/issue-10042-shrink-only-direction-prose branch August 20, 2026 01:31
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-steve@claude