Skip to content

feat(scripts): count the changeset bodies check-changeset-claims cannot reach - #9410

Merged
os-try-charles merged 2 commits into
mainfrom
claude/issue-9140-changeset-claims-blind-spots
Sep 14, 2026
Merged

os-try-charles merged 2 commits into
mainfrom
claude/issue-9140-changeset-claims-blind-spots

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Part of #9140 — this delivers ONE of the card's two defects and deliberately leaves the other open. It does not close the card.

Which defect this delivers

#9140 separates two things, and they have different fixes:

defect delivered here
(a) blind spot — a WENT-FALSE shape the gate cannot see partly — made measurable, ⛔ not closed. See "why not closed".
(b) delivery — the gate fired four times and changed nobody's behaviour no — every option is a policy choice. See "left open".

Reproduction first — the card's measurement, re-run on this branch's base

Base 9ba7e9c3a2. Each falsifying merge re-run on its own parent..merge range, node scripts/check-changeset-claims.mjs --base MERGE-CARET --head MERGE (MERGE-CARET spelled in words: the caret is the parent operator):

falsifying merge pending changeset it falsified gate named it
c5fbe0b99 .changeset/5293-view-sort-order-spelling.md yes
adbda1bed .changeset/7165-grid-dependent-values.md no
d3499b315 .changeset/7655-chatbot-registration-authoring-faces.md yes
ad66d79a1 .changeset/7727-conditional-formatting-record-scope.md yes
0601af1ad .changeset/8934-chatter-feed-affordance-only.md yes

⇒ the card's finding reproduces exactly: 4 of 5 named, the 5th invisible. Every run exited 0.

⚠️ One correction to the card. Its second table's absolute span counts do not reproduce under the gate's own namedFiles() — I read 1 / 0 / 4 / 4 / 2 where the card reads 1 / 10 / 16 / 3 / 0. Different instrument (the card counted spans "containing a slash or ending in a source extension", undeduped; namedFiles() requires both and dedupes). The finding is unaffected and reproduces: the one the gate could not see is the one — uniquely — with zero.

Why the coordinate was NOT widened

I measured the widening rather than assuming it. The cheapest in-idiom candidate stays inside the gate's existing machinery: treat a backticked span equal to the stem of exactly one tracked file as naming that file (ObjectGridpackages/plugin-grid/src/ObjectGrid.tsx). Same instrument, same unambiguous-resolution filter, no symbol table.

Re-measured over the 25 most recent first-parent commits on my base, paragraphs per commit:

coordinate median mean max
file named unambiguously (current) 1 3.8 25
+ stem, symbol-only bodies (candidate) 0 5.3 34
union 1 8.6 59
(header's already-rejected runner-up) 8 12.6 56

The first row reproduces the header's own row (median 1 / mean 4.2 / max 23) — my instrument agrees with theirs, which is what makes the other rows comparable.

The union's tail exceeds the runner-up the header rejected. And the crux is worse than the aggregate suggests:

  • .changeset/7165-grid-dependent-values.md enters through exactly one spelling: ObjectGrid.
  • At that merge's base, ObjectGrid is backticked by 41 of 759 pending changesets.

⇒ seeing that one true positive means asking the seat to re-read up to 41 paragraphs on every commit that edits the grid. That is the release-time wall in a smaller costume — the exact shape the header rejected on a measurement — on a channel that half one of #9140 just measured at zero for four. Widening is a readability-budget decision, it is genuinely open, and ⛔ I did not take it. The header records the trade; the numbers stay on the card.

What this PR does instead

--audit now counts the population the diff-mode check can never reach for any diff: bodies that publish a CHANGELOG paragraph but spell no name the gate can resolve — either naming no file at all (symbol-coordinated, the 5th's shape) or naming only files that resolve to none or to many. --audit --blind lists them.

The card established that population by counting backticked spans by hand, once, on one card. It is now re-derived on every run — AGENTS.md rule #9 applied to the gate's own blind spot.

The gate's coordinate, its findings and its report-only nature are unchanged; --audit's existing lines are unchanged.

Left open — for whoever revisits this

Verification

  • scripts/__tests__/check-changeset-claims.test.ts — 28 passed (3 new).
  • Firing negative control: a symbol-only body is counted in the blind population; the same body with one resolvable file name added leaves it (silent drops by exactly 1, with both runs pinned to the same publishing population so neither side can be reading nothing).
  • The blind spot is pinned as a limit: the diff-mode gate stays silent about a symbol-only body even when the change edits the file that body is about — with a control in the same run showing the gate was not simply silent about everything.
  • Ablation (committed first, mutation proved on disk by blob hash, restored byte-identically): deleting the silent counter turns 2 of the 3 new tests red; restore verified by an empty git diff HEAD and a matching blob hash.
  • check-changeset-claims / -no-major / -fixed / -overwrite / check-control-bytes / check-changeset-presence: all exit 0.
  • eslint on the 2 changed files: 0 errors, 0 warnings (narrowed from the 4935 files eslint's own config selects; no type-aware linting is configured, so this diff cannot move the verdict on any untouched file). tsc -p tsconfig.scripts.json: exit 0, and --listFiles confirms the new test file is in that program.
  • Changeset declares no bump (empty frontmatter): tooling and tests only, nothing is released.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

…ot reach

objectui#9065 was five WENT-FALSE changeset claims at once. Re-running
check-changeset-claims on each falsifying merge's own range splits two ways:
it named four of the five, and was blind to the fifth.

The fifth's body names no file at all -- it coordinates itself by symbol -- so
no diff can make the diff-mode check speak about it. That was established by
counting backticked spans by hand, once, on one card.

--audit now counts that population: bodies that publish a CHANGELOG paragraph
but spell no name the gate can resolve, plus those whose every name resolves to
none or to many. The size of the blind spot is therefore re-derived on each run
rather than written down (AGENTS.md rule #9).

The coordinate is NOT widened and the gate stays report-only. The one spelling
that would bring the fifth instance into the census is the stem of a principal
component's file name, which a large fraction of the pending queue backticks;
admitting it lands in the same volume band the header's own measurement already
rejected. That trade is recorded in the header and left open on objectui#9140.

Tests pin the counter in both directions, including a firing negative control
-- the same body with one resolvable file name added must leave the blind
population -- and pin the blind spot itself AS A LIMIT.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
@os-try-charles
os-try-charles marked this pull request as ready for review September 14, 2026 07:29
@os-try-charles
os-try-charles added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit c5cd9c0 Sep 14, 2026
37 checks passed
@os-try-charles
os-try-charles deleted the claude/issue-9140-changeset-claims-blind-spots branch September 14, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants