Skip to content

finding: the three refusal-shape ratchet gates state their registry's nature only in comments, so no author and no detector reads it #8576

Description

@qq9340100

Observation-class, filed unassigned from the #8540 dev seat (PR #8575). No gate is asked to be weakened and nothing here is a defect in a verdict — every gate named is correct, and each one already resolves the #8435 convention in its stronger form by turning the weakening remedy down outright.

The measurement

Building the farm-wide #8435 detector required deciding, mechanically, whether a registry an author is pointed at is a ratchet (adding an entry weakens it) or a declaration registry (adding the entry is the work). The discriminator is the gate's own testimony about that registry.

Measured against main = 6b441a842, counting shrink/governance testimony that appears in author-facing text (string literals) rather than in comments:

gate testimony in author-facing text
check-type-source-resolution.mjs 0
check-test-source-alias.mjs 0
check-driver-memory-census.mjs 0

All three carry it — clearly and at length — in JSDoc and header comments. check-type-source-resolution.mjs and check-test-source-alias.mjs both open a registry with a shrink-only banner; check-driver-memory-census.mjs explains its ledger's governance in its header. None of that reaches the person who trips the gate.

Why it is worth recording

Two consequences, and the second is the one that generalises:

  1. The A farm-wide detector is the only thing that makes the #8435 ratchet-remedy convention mechanically enforceable — and the farm now has two conflicting ⛔ tokens that must be reconciled first #8540 detector reaches these three only as excluded rather than refused — stage 2 declines them before the refusal grammar is consulted. Harmless for correctness (a gate that is not reached cannot be reported as violating), but it means the detector's refusal limb is exercised by exactly one gate today, so a regression in it would be measured against a sample of one.

  2. More importantly, the same asymmetry the check:engine-double-contract fires at CI time, not authoring time — four independent PRs tripped it on brand-new test files in one shift, and a pre-warning in the brief did not prevent it #8435 convention is about applies here one level down: a maintainer reading the script learns the registry only shrinks; the author who trips the gate does not. The refusal sentences themselves are author-facing and excellent (is not the fix, do not add it to … to make this green) — it is the reason that stays in the comment. An author told "no" without being told "because this only ever shrinks" is being asked to take the refusal on trust.

Possible shape (not decided here)

Move one clause of the existing comment into the existing refusal message — no new message, no verdict change, no ratchet touched. This is the same cheap, unconditional half that PR #8517 argued for on the marking side.

⚠️ Deliberately not proposed: making these gates carry ⛔ MAINTAINER-ONLY. Turning the remedy down outright is the stronger shape and the triage ruling on #8540 is explicit that it must never be pushed onto the weaker marking shape. This is about the refusal's reason being reader-visible, nothing more.

Related: #8435 established the convention; #8540 and PR #8575 are where this was measured. #8540 is not addressed here — it is delivered by PR #8575 on its own terms.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions