feat(gate): read BORN-FALSE claims — an address this change's own diff moves - #9744
Merged
Merged
Conversation
…f moves `check-changeset-claims.mjs` covered WENT FALSE only and said so in its own output. This adds the second reading, over a corpus of its own: the prose this change publishes about ITSELF — the pull request body (from the event payload the job already receives) plus the changeset bodies this change adds. The coordinate is an unbound backticked LINE ADDRESS resolving to one tracked file this change touches, and the question asked of it is arithmetic rather than semantic: does this diff's own hunk map the cited base line somewhere else, or is the file one this change creates, so the number can only have been read from a tree that exists nowhere outside this pull request? An address whose own SENTENCE names the tree it was read from is never reported — that is the durable form both carded pull requests converged on, and a gate that reported it would teach authors to unbind. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
…trols The arithmetic cases use objectui#9496's own geometry, because that pull request published the figure independently of this tree: its body and the docblock it landed both state `:246`@`b8a006883d` = `:274`@head. A mapper that drifts by one fails there rather than reporting a clean branch. Two controls guard the instrument rather than the prose: a judge that lies fails the control suite instead of passing it, and a corpus that was read but spells no address is reported as neither clean nor a finding — one tick for "nothing to judge" and "everything checked out" teaches the reader to skim it. The gate's own footer inverted rather than moved: it used to name born-false as a class it cannot see, and now names the one shape still out of reach. ⇒ a count of the phrase across this landing reads 1 -> 1 and proves nothing, so the pin asserts the sentence, on a run where that footer actually prints. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
…posed Measured, ⛔ not anticipated. Mutating `line <= hunk.oldStart` to `line <` turned the section-6 pin red while ALL FOUR of the gate's own controls stayed green — so the gate would have printed "instrument fine" while reporting every stable citation at an insertion point as moved. A gate that manufactures findings on a report-only channel is how a channel gets muted. A fifth control reads the anchor line itself. git spells a pure insertion as "after old line N", so N is the last line it does not move. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
… live declaration Two root causes, four red assertions, three gates. 1. A renderer fixture spelled `.changeset/9088-rest-less-tuple-identity.md`, a declaration the tree actually carries. `scripts/markdown-test-inputs.mjs` offers only documents that EXIST, so the literal became a ledger candidate on the pre-version tree and would have had nothing to resolve to after `changeset:version` deleted it — reddening the release lane days later, in a job no reader of a pull request sees. Renamed to a `fixture-` spelling, which belongs to neither the generated `adjective-animal-verb` namespace nor this repository's issue-number-and-slug one. ⛔ No ledger entry is added, deliberately: with no resolvable document left the scanner stops seeing that file entirely, and an entry for a file the scanner no longer sees is itself a `stale-test` finding. 2. ⭐ `GITHUB_EVENT_PATH` is exported to every process on a runner, and the gate read it whenever `--pr-body` was absent. So in CI the gate under test picked up the real pull request body of the build that happened to be running and counted it as "the prose this change publishes about itself", in a temp repository that has nothing to do with it — off by exactly one body. The empty-corpus floor, whose whole job is to report that a run measured NOTHING, did not hold in the one environment that actually runs it. The env read stays — it is the whole reason this needs no new workflow — but it is now gated on a predicate about the TREE rather than about how the process was launched: the payload names `pull_request.head.sha`, and a tree that cannot resolve that commit is not the tree the event is about. Fails closed and prints why, ⛔ never silently. Pinned in both directions, and the test harness strips the variable for every case rather than for the two that reddened — the others survived it by luck, not by hermeticity. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9509
Clause-②: no — this change makes a gate see MORE. Nothing is relaxed: the went-false half keeps its exclusion of a change's own changesets verbatim, exit stays 0 on findings, and no context becomes required.
What was actually wrong, and where
scripts/check-changeset-claims.mjsprinted, in its own output, that a born-false claim was outside it entirely. objectui#9509 carded three same-day instances across two pull requests. I resolved all three against the merged trees before designing anything, and the card names the symptom's location, not the defect's:app.tsdocblock⇒
scripts/check-new-cross-file-line-citations.mjswould have caught 0 of 3, measured rather than assumed: its population ischangedPaths(), i.e. tracked files, and its five syntaxes all require a line address. Measured directly: the five files objectui#9496 changed carry the repaired, sha-bound spellings and not the born-false ones — the false prose was never in the tree. ⇒ the citation gate is the wrong home, which is the seat's own least-certain claim, falsified.check-changeset-claims.mjsis the right one for a reason that is mechanical rather than thematic: it is the only gate here that already runs onpull_requestand already delivers its finding onto the pull request, so the corpus where two of three instances live is reachable from it with ⛔ no new workflow, ⛔ no new required context, ⛔ no new permission and ⛔ no API call —GITHUB_EVENT_PATHis a file on the runner, read the waycheck-governed-queue-guard.mjsalready reads it.The mechanism
.changeset/*.mdbodies this change adds. ⛔ Not the tree at large; that population has a reader already.MOVED: this diff's own hunks map the cited base line elsewhere, or delete it.UNANCHORED: the file is one this change creates, so the number can only have come from a tree that exists nowhere outside this pull request — instance 1's shape, where the frame moved twice between revisions of one branch.Firing control, taken from the probed artefact
The controls run objectui#9496's real geometry — a 28-line insertion after old line 220 and a rewrite of old line 223, as
git diffreports it on the merged commit. That geometry is attested outside this branch: objectui#9496's own body and the docblock it landed both publish the figure:246@b8a006883d=:274@Head. A mapper that drifts by one fails the control rather than reporting a clean branch, and the number cannot be re-derived to match a wrong implementation.Five controls, both directions — ⛔ a suite that only ever fires proves nothing:
A control failure exits 1 in a gate that is otherwise report-only, and says why: a differential reader that reports zero because its differ broke is indistinguishable from prose with nothing wrong in it. Pinned as failable — a judge that lies fails the suite instead of passing it.
Run against the real artefact
The reader, pointed at objectui#9496's merged body and its own diff (stable across both the pull request's merge base and the squash parent):
10 addresses read · 7 reported · 3 silent. The 3 silent are exactly the section-2 and pins-list repairs three review rounds produced — the discrimination.
⭐ Of the 7, six are confirmed born false by byte-level content comparison in both trees, i.e. they are live instances that survived three review rounds including a by-hand audit of all 16 citations in that body:
imported-defaults.ts:221-228is thetuplearm and that:223is byte-for-byteconst rest = def.rest ? walk(def.rest) : undefined;. At the merged head those lines are the 28-line comment block the same diff inserted; the arm is at:249and:223was rewritten. This is instance 2's exact shape, in the one section the rounds never bound.registry-meta-carry-9102.test.ts:833:7— base:833is the assertion frame; that same line is:885at the head.:163,:295,:857:7.:966) I could not confirm either way and do not claim.Ablation — proven on disk, ⛔ never by an exit code
Mutating the insertion-point boundary (
line <= hunk.oldStarttoline <):c4915154fdf3cb9455ad5c4f2f2763948d8cbc90dccab53d35a1db4dcd45593913be81f558006937the-insertion-point-itself-does-not-moveFAILS reporting:220 -> moved (:248), 13 pins redc4915154fdf3cb9455ad5c4f2f2763948d8cbc90git diff HEADempty⭐ The first ablation of this change changed the change. Before the fifth control existed, that same mutation turned a unit pin red while all four of the gate's own controls stayed green — the gate would have printed "instrument fine" while silently reporting every stable citation at an insertion point as moved. The boundary control exists because the ablation found that, ⛔ not because it was anticipated.
grep -c 'line <= hunk.oldStart'reads 1 then 2 across the landing, and neither number is about the code — the second carrier is the comment explaining the ablation. The restore is proven by the blob hash and the empty diff, ⛔ not by that count.Verification
scripts/__tests__/check-changeset-claims.test.ts+scripts/__tests__/render-changeset-claims-comment.test.ts— 101 passed.check-changeset-presence,check-pre-install-import-graph,ci-cd-pipeline-doc,merge-queue-reporting) — 192 passed.check-control-bytesexit 0 over 7828 tracked text files; an independent control-byte scan of the five changed files finds none.check-action-ref-convention,check-lint-coverage,check-node-esm-load,check-pre-install-import-graph— exit 0.eslint . --no-inline-configover its own full population, 5050 files, at this head: 95 errors / 13207 warnings, 0 of them in the files this branch touches (targeted run over those four files: 0/0). The tree-wide totals are the pre-existing state, ⛔ not a reading about this change.check-required-check-setexit 2 (HTTP 401 for the rulesets API) andcheck-governed-queue-guardexit 1 (no event payload locally) are PREREQUISITE NOT MET, ⛔ not findings — recorded as NOT MEASURED.check-changeset-presence.mjsverdict on this diff, verbatim: "No source or published contract of a released package changed in this range, so no changeset is owed." ⇒ no changeset.Surface — declared wider than dispatched, and measured
The dispatch named two files. A gate's implementation and the tests asserting on its output are one surface, and delivery is part of that output: a born-false-only run must create the comment, or the one half nothing later will ever turn red lands in the job log objectui#9140 measured at zero answers out of four. So five files:
scripts/check-changeset-claims.mjsscripts/__tests__/check-changeset-claims.test.tsscripts/render-changeset-claims-comment.mjsscripts/__tests__/render-changeset-claims-comment.test.ts.github/workflows/changeset-presence.yml(one expression in an existing job)Census: all 12 open pull requests,
GET /pulls/{n}/filesfully paginated, 1807 filenames (floor asserted — a zero-length census aborts). Positive control:.github/workflows/ci.yml,lint.ymlandscripts/dependabot-merge-gate.mjsall resolve to #9584, so the membership test discriminates. ⛔ No governed surface is touched: none of the five paths matchesGOVERNED_SURFACES.⛔ What this does not do
pull_requestdoes not fire on that.🤖 Generated with Claude Code
https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
Generated by Claude Code