Skip to content

Commit c3ead55

Browse files
os-muskclaude
andauthored
pm gates: refuse a widening diff whose claim declares Clause-②: no (the mechanical half of the directional ruling) (#16604)
* wip(pm): widening-tell gate, self-test green Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018dxq7YqsLDMeZDZ5AzsgJX * wip(pm): wire C5 into --pair Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018dxq7YqsLDMeZDZ5AzsgJX * fix(pm): a binary change to a tell surface is UNREAD, not narrow `splitUnifiedDiff` wrote `additions: addedLines(patch).length` for every row, and `addedLines(null)` is empty — so a BINARY change stamped a count nobody took. `unreadFiles` skips a row that added nothing, so a binary edit to `packages/spec/api-surface/*.json` arriving through the local path reported `state: 'clean'`: the gate's own contract, declared and not enforced, inside the gate. The three states are now told apart by what the diff SAYS — a hunk gives the count, a `Binary files`/`GIT binary patch` marker gives `null` (UNKNOWN), and neither gives a real `0` (a mode-only change or a pure rename adds no line). `addedNothing` interprets both input paths in one place, so a MISSING count can never become a zero; GitHub's own `additions: 0` on a binary row is kept, because that reading was taken by something that can see the blob. The self-test pinned the two halves separately and never composed them, which is why it stayed green. Seven composed cases now drive splitUnifiedDiff into wideningRefusal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018dxq7YqsLDMeZDZ5AzsgJX * fix(pm): drop the no-path-population marker the widening-tell gate cannot honour The gate's CI command is its own --self-test, so on the marker's own second listed cause the declaration read true. dispatch-gates' live guard refuses it anyway the moment a family NAMES paths, and this one names 59: 9 from its module body (the registry table, the objectui mirror glob, two repo slugs, four fixture filenames) and 50 inherited from the two registers it imports on purpose, SUSPECT_TIER_GLOBS and REGEN_ARTIFACTS. Getting those out of a scanned position would mean hand-copying two registers this file imports precisely so it can never disagree with them - the drift check:pm-governed-prose exists to stop, and this gate's strongest property. So the marker goes and the derivation stands. The header now records what the derivation says, which part of it is right (packages/spec/src/**, api-surface/**, the three registries - the surfaces this gate polices) and which part is noise inherited from REGEN_ARTIFACTS, and why one cheap self-test in a MATCHED column is the smaller error than a marker sitting above a live population. The case that catches this sits at ~1534 of dispatch-gates' self-test and needs well over 540s to reach, which is why three local runs missed it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018dxq7YqsLDMeZDZ5AzsgJX --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent bc0ac1d commit c3ead55

4 files changed

Lines changed: 1391 additions & 17 deletions

File tree

.github/workflows/lint.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,19 @@ jobs:
975975
- name: Clause-② carrier checker self-test
976976
run: pnpm check:pm-clause2-carriers
977977

978+
# Widening-tell gate self-test (#16448) — the mechanical half of the
979+
# directional clause-② ruling (#16349), and the same split as every step
980+
# around it: the LIVE predicate is `--pair`'s C5 row, a verdict about ONE
981+
# pair's diff, so failing an unrelated PR's CI over it would punish the
982+
# wrong actor. Only the offline self-test runs here.
983+
#
984+
# This gate has no whole-tree production run at all — its input is a DIFF
985+
# supplied by its caller, never a file in the tree — so the `--self-test`
986+
# invocation is the only instrument its matching rules have, which is
987+
# exactly the family `check:self-test-wired` requires this step for.
988+
- name: Widening-tell gate self-test
989+
run: pnpm check:pm-widening-tells
990+
978991
# Governed-merges audit self-test (#9495) — same family, same split as
979992
# the half-state sweeper above: the live sweep enumerates the governed
980993
# merges since a date/ref for the PM round report — report-only by

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"check:declared-population-live": "node scripts/check-declared-population-live.mjs --self-test && node scripts/check-declared-population-live.mjs",
7676
"check:pm-half-states": "node scripts/pm/check-half-states.mjs --self-test",
7777
"check:pm-clause2-carriers": "node scripts/pm/check-clause2-carriers.mjs --self-test",
78+
"check:pm-widening-tells": "node scripts/pm/check-widening-tells.mjs --self-test",
7879
"check:pm-closed-card-sweep": "node scripts/pm/sweep-closed-cards.mjs --self-test",
7980
"check:pm-governed-merges": "node scripts/pm/check-governed-merges.mjs --self-test",
8081
"check:pm-governed-prose": "node scripts/pm/check-governed-prose.mjs --self-test && node scripts/pm/check-governed-prose.mjs",

0 commit comments

Comments
 (0)