Uh oh!
There was an error while loading. Please reload this page.
fix(scripts): make the three refusal-shape gates state their registry's nature in author-facing text (#8576) - #8583
Conversation
…'s nature in author-facing text (#8576) All three refuse the ratchet-weakening remedy outright — the stronger shape under the #8435 convention — but each stated WHY only in a comment. An author who trips the gate was told "no" without being told "because this only ever shrinks". Mirrors one clause of each gate's own comment into its existing refusal string; no new message, no verdict changed, no ratchet touched. Two of the three consequently flip in the #8540 detector (PR #8575) from `excluded` to `refused`, which is the intended effect: the refusal limb's sample grows from one gate to three. The detector's hand-classified control corpus is re-read and updated to match, per its own C2/C3 audit cases. check-driver-memory-census.mjs does NOT flip, and is left exactly as it is: its refusal sentence carries no target inside the detector's 200-char offer window, and its governance wording sits outside the GOVERN vocabulary. That is a finding about the detector's grammar, not a defect in a correct gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqe56GnYFddggeAyfkZFVz
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
qq9340100
commented
Aug 13, 2026
ACCEPTed on substance by the Ruling on the interpretation you flagged — your reading is correct, keep itYou read "move one clause into the refusal string" as make it reach the author, not delete the maintainer-facing copy, and left each comment carrying its clause. That is right, and I want the reasoning on the record so nobody 'corrects' it later: The measured defect was 0 occurrences in author-facing text — never "the rationale is duplicated." Deleting the comment would fix nothing that was broken and would strip context from the reader who maintains the gate, which is a scope expansion with a real cost and no measurement behind it. ⛔ Do not make it a literal move. The two registry gates carrying byte-identical JSDoc wording, and therefore receiving the same sentence, is the right outcome for the same reason PR #8539 and #8549 mirrored rather than reworded: two voices for one rule become two rules by the next reading. Assumption B falsified, with a mechanism — and it sharpens my own descriptionI said earlier that the census gate fails to flip partly because its wording matches no governance pattern. Your measurement is more precise and the difference matters: the refusal grammar is never consulted at all. It stops at stage 1 — ⛔ You did not reword a correct gate to satisfy a detector. That was the one permission built into the dispatch and using it was the right call. Three things in the verification worth namingThe mutation you rejected and redid. Your first M1 attempt deleted whole lines, broke syntax, and would have tested a crash rather than the assertion. A passing-looking mutation that exercises the wrong failure is exactly the family this lane has been bitten by twice today — a no-op mutant reading as a clean result, and a regex gap class silently excluding a subset. Catching it by inspection rather than by luck, and reporting it rather than quietly redoing it, is the behaviour that makes the rest of the report credible. You observed both The stale prose comment. Fixing the control's Also noted: the Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#8576
All three gates named on the card already satisfy the #8435 convention in its stronger form — they turn the ratchet-weakening remedy down outright rather than marking it. What none of them did was say why. The shrink-only / governance testimony sat in JSDoc and header comments, where the maintainer reading the script sees it and the author who trips the gate does not. Measured at 0 occurrences in author-facing text for all three.
This changes reader-visibility only: one clause of each gate's own comment is mirrored into its existing refusal string. No new message, no verdict changed, no ratchet / ledger / baseline touched, and no gate converted to
⛔ MAINTAINER-ONLYmarking (refusing outright is the stronger shape per the #8540 triage ruling).The words are mirrored, not reworded — precedent from PR #8539 and PR #8549: one rule stated twice in two voices becomes two rules by the next reading. The comments keep their clause; what changes is that the author now reads it too.
What moved
check-type-source-resolution.mjs⛔ SHRINK-ONLY+ "entries are audited in both directions, so one that is no longer needed fails the gate and names itself for deletion"KNOWN_DIST_RESOLVED_TYPE_IMPORTScheck-test-source-alias.mjsKNOWN_UNALIASED_TEST_IMPORTScheck-driver-memory-census.mjsEffect on the #8540 detector (PR #8575), measured
check-type-source-resolution.mjsexcludedrefusedcheck-test-source-alias.mjsexcludedrefusedcheck-driver-memory-census.mjsexcludedexcluded(unchanged)The two flips are the intended effect: the refusal limb's sample grows from one gate to three, so a regression in it is no longer measured against a sample of one. Sweep counts move
1 → 3refused and73 → 71excluded.The detector's hand-classified control corpus is re-read and updated, not assumed — leaving it stale fails PR #8575's own C2/C3 audit cases by design, and both MISCLASSIFIED failures were observed live before the control was corrected.
The census gate did not flip, and is deliberately left alone
check-driver-memory-census.mjsnow states its ledger's governance in author-facing text, yet its verdict is unchanged, for two independent reasons that are each about the detector, not the gate:OFFER_WINDOW= 200 characters after the verb there is no declared-caps identifier, no.json/.mjs/.mtspath and noREGISTRY_NOUN. The measured window already truncates at 200 mid-word, so no appended clause can reach it.GOVERN_TESTIMONY's five patterns.Per the card's own constraint, a correct gate is not reworded to satisfy a grammar. Recorded in the control's
whyand raised as a finding instead.Tests
Each gate gains one named assertion, non-overlapping by construction, asserted on a violation the self-test already plants — these strings only ever print on failure, so none of this is a green-run diff.
Mutation-tested, direction predicted in writing first, every mutant verified real by byte-length and
git hash-objectbefore its result was read:⛔ SHRINK-ONLYfromcheck-type-source-resolution.mjsMISCLASSIFIED(refused → excluded)⛔ SHRINK-ONLYfromcheck-test-source-alias.mjsMISCLASSIFIED(refused → excluded)check-driver-memory-census.mjsThat third row is the honest asymmetry and is why the census assertion has to exist: nothing outside the gate's own self-test holds its reader-visibility.
Gates run green from the committed state:
check:type-source-resolution,check:test-source-alias,check:driver-memory-census,check:ratchet-remedy-authority(each runs--self-testthen the sweep), pluscheck:nul-bytesandcheck:type-check-coverage. Families re-derived against the actual changed paths withscripts/pm/dispatch-gates.mjs; nothing beyond the above was implicated.skip-changeset: rootscripts/tooling, releases nothing.Draft on purpose — no ready-flip, no enqueue, no auto-merge.
Generated by Claude Code