Skip to content

Commit ebacad8

Browse files
committed
tooling: record the authorised cross-file move in the remedy-authority gate
The #8435 convention asks who may take a registry-growing remedy on a shrink-only ratchet, and the answer has always been "a maintainer, per instance". One class of act is now authorised generally: a cross-file move in the per-file line ratchet, while the destination's raise is covered by the named sources' net decrease, the map-wide total does not increase, and the raised entry cites the ruling. The exception is written in comment space, because author-facing text describing a registry-growing act would make this gate an instance of the convention it enforces. Two self-test assertions hold it there: one that the phrase never reaches an author-facing message, one that the amended ratchet is still outside this non-recursive walk — so the exception stays honestly documentary, and a wider walk reds here instead of admitting a remedy class in silence. No new verdict class: a fifth class with a population of zero is enforcement nobody has. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
1 parent 0db8578 commit ebacad8

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

‎scripts/check-ratchet-remedy-authority.mjs‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,49 @@
1616
// precedents are check-type-source-resolution.mjs, check-test-source-alias.mjs,
1717
// check-adr-links.mjs and check-driver-memory-census.mjs.
1818
//
19+
// ── The ruled EXCEPTION: an authorised cross-file move (2026-09-03) ─────────
20+
//
21+
// The disjunction above asks WHO may take a registry-growing remedy, and on a
22+
// shrink-only ratchet the answer was always "a maintainer, per instance". One
23+
// class of act is now authorised generally instead of one PR at a time.
24+
// Maintainer ruling, 2026-09-03, adopting option A of item 5 in the skills
25+
// optimization programme's third decision batch (#14685, comment 5520452691) —
26+
// verbatim and untranslated: 「同意」; the text it adopts:
27+
//
28+
// the per-file line ratchet admits a cross-file move in one PR when the
29+
// destination's allowance rises by no more than the source's net decrease and
30+
// total lines do not increase, with the ruling cited in the ratchet comment;
31+
// `check:ratchet-remedy-authority`'s self-description gains this exception
32+
//
33+
// So: a cross-file MOVE in the per-file line ratchet is NOT a maintainer-only
34+
// remedy while all three conditions hold — the destination's raise is covered by
35+
// the named sources' net decrease, the map-wide total does not increase, and the
36+
// raised entry cites that ruling. The scope is exactly the act the ruling names,
37+
// in the gate the ruling names. A raise failing any condition is an ordinary
38+
// raise and belongs to a maintainer as before, and no other ratchet in this farm
39+
// gains anything: the reason a move is not a weakening is that the corpus SHRANK
40+
// on net, which is a property of the act, not of the author.
41+
//
42+
// ⚠️ TODAY THE EXCEPTION IS DOCUMENTARY, and recording that is half the point of
43+
// writing it here. The corpus walk is a NON-RECURSIVE readdir of `scripts/` (see
44+
// corpusFiles), and the gate the ruling amends lives one directory down, in
45+
// scripts/pm/ — it has never been in this sweep, so no verdict of this gate
46+
// moves. A self-test assertion pins that, so a wider walk reds HERE and makes
47+
// the class a decision someone takes rather than one that lands in silence.
48+
//
49+
// ⛔ NO NEW VERDICT CLASS. `marked` / `refused` / `unmarked` / `excluded` stay as
50+
// they are. A fifth class for "authorised by standing ruling" would have a
51+
// population of zero in this corpus, and an unreachable class is a claim of
52+
// enforcement nobody has — the same defect this file's control corpus exists to
53+
// prevent, one level up. If the walk ever reaches a gate offering this act, the
54+
// honest first move is to read that gate's own verdict and record it in CONTROL,
55+
// the way every instance in this file arrived.
56+
//
57+
// ⛔ THIS SECTION IS COMMENT, never a string literal — the header warning above,
58+
// applied to itself. It describes an act that grows a registry, so in
59+
// author-facing text it would make this gate an instance of the convention it
60+
// enforces and flip its own verdict off `excluded`.
61+
//
1962
// WHY A SWEEP AND NOT A SHARED MODULE. #8519 proposed a shared helper module as
2063
// the enforcement route. It is not one: a module is reachable only from gates
2164
// that choose to import it, so it standardises the gates that already agreed and
@@ -1265,6 +1308,29 @@ function selfTest() {
12651308
+ 'nothing, and a dead declaration prints as the same silence as declaring nothing)',
12661309
!ROOT_DIR_WATCH_HINTS.some((h) => h.includes('{')));
12671310

1311+
// ── (21) The ruled cross-file-move exception (2026-09-03) ───────────────
1312+
//
1313+
// Two assertions, and both are about THIS FILE rather than about the ratchet
1314+
// the ruling amends: where the exception is written down, and whether it is
1315+
// doing anything yet. Neither can be held by the run — a header section runs
1316+
// green whatever it says, which is exactly how a documented exception drifts
1317+
// into a claimed one.
1318+
const selfSrc = readFileSync(join(SCRIPTS_DIR, SELF_FILE), 'utf8');
1319+
// ⛔ The phrase is ASSEMBLED, never spelled, for the reason the ADD hoist above gives in
1320+
// its own case: a literal spelling would put the phrase into THIS file's author-facing text
1321+
// and falsify the assertion below by the act of making it.
1322+
const EXCEPTION_PHRASE = ['cross-file', 'MOVE'].join(' ');
1323+
expect('the ruled exception is recorded in COMMENT space only — written into author-facing text '
1324+
+ 'it would describe a registry-growing act, and this gate would then read as an instance of '
1325+
+ 'the convention it enforces, which is what assertion (17) catches',
1326+
selfSrc.includes(EXCEPTION_PHRASE)
1327+
&& !authorFacingMessages(selfSrc).some((m) => m.includes(EXCEPTION_PHRASE)));
1328+
1329+
expect('the ruled exception is documentary today: the amended line ratchet lives one directory '
1330+
+ 'down and this walk is non-recursive, so a wider walk reds HERE rather than admitting a new '
1331+
+ 'remedy class in silence',
1332+
!corpusFiles().includes('check-skill-line-ratchet.mjs'));
1333+
12681334
if (failures.length > 0) {
12691335
for (const f of failures) console.error(` x self-test: ${f}`);
12701336
console.error(`\ncheck-ratchet-remedy-authority --self-test: ${failures.length} failure(s).\n`);

0 commit comments

Comments
 (0)