Skip to content

Commit 1bdbf82

Browse files
claude[bot]claude
andauthored
feat(scripts): resolve the repo's issue-number citations against the board it names (#18223)
Part of #17512 ⚠️ Deliberately `Part of`, and the dispatch asked for a closing keyword. One half of the card is undelivered and is the seat's to rule on — see **The half this does NOT deliver**. A merge that closed the card here would close it while nothing sweeps the surfaces the card is about. One word flips it back if the seat disagrees. Clause-②: no Reason: this is a gate ADDITION and widens no acceptance set. The diff is one new `scripts/check-issue-citations.mjs` plus one new root-manifest `check:*` key; no existing gate's rule, threshold, ledger, exemption list or population is touched, and nothing that used to be refused is now admitted. ## What this adds `scripts/check-issue-citations.mjs` — extracts `#N` citations from a declared surface set and resolves each against this repository's board. | mode | what it does | verdict | |---|---|---| | default (diff-scoped) | judges only the citations **this change adds**, against the merge base | exit 2 on a finding | | `--census` | the whole declared surface | report-only, always exit 0 | | `--probe-cause` | adds the web-endpoint probe that separates transferred from deleted | — | | `--list` | extraction only, no network | — | | `--self-test` | offline; 56 cases over 6 batteries with a per-battery floor | exit 1 on a breach | | — | the board could not be read | exit 3, never a quiet pass | ## Re-measured on today's tree, before anything was written The card was measured 2026-09-10. Re-measured 2026-09-14 against `2d3d1c969`: | number | 2026-09-10 | 2026-09-14 | carrier today | |---|---|---|---| | 16785 | 404 | **404** | the `dataset-compiler.ts` scope note is GONE; the number now survives only in a changeset that already records it as resolving to nothing | | 16685 | 404 | **404** | still cited from `content/docs/releases/v17/17-4.mdx:408` (a published page), `measure-result-type.ts:115` and `aggregate-field-type-compatibility.ts` | | 14313 · 14832 · 14366 | 404 | **404** | unchanged | Controls, same call, same token: 16099, 16737, 17444, 17560, 17242, 15809 all **200**. ⭐ **The card's own control has partly decayed, and that is the sharpest reading here.** The card cited 16783 / 16784 / 16786 / 16787 — the immediate neighbours of 16785 — as all resolving, proving a hole in a dense sequence. Today only **16784** answers 200; **16783, 16786 and 16787 answer 404**. Three numbers stopped resolving in four days, with no change to this repository. ## The surface is ~500× the five instances Enumerating the whole board (159 cursor pages) and judging every citation offline against it: ``` allocation frontier 18,219 the highest number ever minted here resolvable 15,834 holes 2,385 13.1% of every number this repo ever minted ``` and through this gate's own `--census --json`: ``` 33,750 citations judged across 2,357 files 28,359 resolve 1,410 resolve as a PULL REQUEST, not an issue 1,196 cross-repo — UNJUDGED, never a finding 2,785 UNRESOLVABLE: 103 sites / 71 distinct on the release pages 2,682 sites / 439 distinct in package docblocks ``` A second instrument written before the gate existed (a scratch scan with the same projection) answered 2,782 on the same tree minutes earlier; the two agree to within the three citations the frontier moved by while they ran. **Those two readings together decide the gate's shape.** A tree-wide blocking verdict is refused for two reasons, not one: 2,785 findings is the permanently-red gate this repo retired, and — worse — the predicate is **not a function of this tree**. 16783 / 16786 / 16787 prove a still tree goes red because somebody else deleted an issue. So the default verdict is **diff-scoped**: the half of the class an author owns, which cannot red on a still tree and which stops the debt growing. The 2,785 standing sites are a `--census` reading, not a verdict. ## The four 404 causes, kept apart ⛔ The card's hardest constraint. Each arm has its own decision procedure, and none of them is a guess. | cause | how it is decided | measured live? | |---|---|---| | `cross-repo-unjudged` | the citation NAMES another repo (`owner/repo#N` or `repo#N`) — never resolved, ⛔ never a finding | ✅ `objectui#4356` stayed silent in the live ablation | | `never-issued` | the number is beyond the allocation frontier | ✅ `#18888` against frontier 18221 | | `transferred` | the web endpoint still redirects out of this repo (the API does not keep that redirect) | ⛔ **NOT MEASURED** — no positive specimen exists on this board; exercised only by the self-test stub | | `deleted` | minted, absent from the board, and the web endpoint 404s too — named as the residual class | ✅ 16785 under `--probe-cause` | Without `--probe-cause` the last two do not separate and the finding carries `allocated-but-absent`, which is a refusal to guess rather than a third cause. Every unresolvable instance re-probed on 2026-09-14 (16785, 16783, 14366, plus twelve sampled at random from the census) answered 404 on **both** endpoints, so no citation measured here was transferred — and this gate's silence is ⛔ not evidence that none ever was. ## Both directions, measured live on this branch The ablation ran against the live board, on the committed implementation, with the mutation proven on disk before the reading was taken and the restore proven by blob hash afterwards. ``` leg 0 tree clean at HEAD, diff-scoped run exit 0 "no issue citations added" mutate one docblock line in a declared surface blob f318190 -> bd2007413 (marker count 0 -> 1) leg 1 diff-scoped run with --probe-cause exit 2 1 deleted, 1 never-issued, 1 cross-repo-unjudged [deleted] ...aggregate-field-type-compatibility.ts:8 #16785 [never-issued] ...aggregate-field-type-compatibility.ts:8 #18888 leg 2 git checkout HEAD -- THE_PATH blob restored to f318190, git diff HEAD empty diff-scoped run exit 0 "no issue citations added" ``` ⛔ A first attempt at this ablation wrote nothing to disk (a `perl -i` invocation that swallowed its argument and still exited 0). The on-disk marker count caught it and the run was declared void rather than re-rolled quietly; the reading above is from the run that landed. ## The scope contract, written down The card rules that the hard part is scope, so it is a table with a reason per row rather than a habit. **Declared** — start where the damage is measured: - `content/docs/releases/**/*.mdx` — the published release pages; 16685's carrier. - `packages/**/src/**/*.ts` and `.tsx`, **comment prose only** (through `scripts/symbol-anchors.mjs#commentProse`, so a gate's own fixtures and string literals are blanked and line numbers survive) — 16785's carrier. **Deferred, and the table is applied as a hard EXCLUSION rather than kept as prose** (the first draft declared it and swept the files anyway — 5,102 sites instead of 2,785 — which is why `surfaceFor` now checks the deferred globs first): - `**/CHANGELOG.md` — 27,978 citations, generated release prose, and the surface the card means by 「会被 changelog 引用淹没」. - `scripts/**` — #15809's lane. ⛔ Not folded; the card is explicit that folding the siblings fails the fix. - `docs/adr/**` — a governed surface with its own anchor corpus; a citation finding there would force a governed-surface PR over a number somebody else deleted. - `.changeset/**` — consumed and deleted at release. - `packages/**/*.test.ts` and siblings — the next candidate widening, held back so the first installation is judged on the surfaces the card measured damage on. Three grammar narrowings, each measured rather than assumed: a two-digit floor (all 133 one-digit `#N` tokens in the declared surfaces are ordinals — `Prime Directive #9`, `acceptance #5` — and none names an issue), a six-digit ceiling (zero such tokens exist, which keeps hex colours out), and `NON_CITATION_HEADS` for numbering systems that are not the board's (`Directive #14`, `batch #127`, `re-charter #26` — 405 sites). ## The half this does NOT deliver — the seat's ruling, not an oversight ⛔ **No workflow invokes this file.** `.github/workflows/**` was out of the dispatch's file surface, and a census of the root manifest's 160 `check:*` keys found **every one of them named by a workflow**, directly or through its alias — there is no precedent here for a gate that CI does not run. The manifest carries `check:issue-citations`, which runs the `--self-test` and nothing else (the `check:pm-half-states` shape, for the same reason: the live modes need a board and a credential). So today this is a tool a seat runs, and `scripts/pm/check-half-states.mjs` states what that is worth: 「an alarm added to a script nobody runs is still silence」. The two homes it wants are in **different lanes**, which is the substance of the ruling being asked for: 1. **the diff-scoped verdict** belongs in `lint.yml`'s `Lint & Repo Gates` job — per PR, already holds a `GITHUB_TOKEN`, and the verdict is a fact about the diff; 2. **`--census`** belongs in the patrol lane (`half-state-patrol.yml`) — scheduled and report-only, which is the only honest posture for a reading a third party can change between runs. Neither is installed. A follow-up card owning `.github/workflows/**` can install both; this branch cannot. ## Tests - `node scripts/check-issue-citations.mjs --self-test` — 56 cases, 6 batteries, per-battery floor plus a roster-size floor and a verdict handshake. Batteries: `grammar` (14), `causes` (12), `transport` (7), `scope-contract` (12), `diff-scope` (6), `live-corpus` (3). The `diff-scope` battery builds a throwaway git repository and asserts the green direction and the red direction on the same tree; `causes` provokes all four 404 arms including the two the live tree has no specimen for; `transport` asserts the two board strategies answer board-identically over one stubbed transport. - `node scripts/pm/dispatch-gates.mjs --commands` → 36 families, all run, **36 run / 0 NOT-MEASURED / 0 UNRUN** (`--ran` reconciled with exit codes). Four exited 3 (PREREQUISITE NOT MET, no `dist/`), were re-run after a full build under the shared verify lock, and all four then exited 0. - `pnpm lint` (full repo, `eslint . --no-inline-config`) — exit 0, no narrowing to declare. Run on `061ab1ac1`. - `pnpm build` under `scripts/pm/os-verify-lock.sh` — 73/73 tasks successful. ## changeset: none, measured No publishable package's `files[]` can ship `scripts/` (0 of 70 publishable manifests carry an entry that could), and the root manifest is `private: true`. Negative control: the new file's `CITATION_SURFACES` appears in 0 built `dist/` trees. Positive control, same instrument: `AGGREGATE_FIELD_TYPE_COMPATIBILITY` appears in 10. Nothing published moves, so `skip-changeset`. ## Acceptance notes Noted, not filed — out of scope here, and each names who would meet it: - **The `#N` citation debt is a 2,785-site class, not a five-instance one**, and this branch repairs none of it. The carriers of 16685 that are still live (a published release page and two `packages/spec` / `service-analytics` docblocks) are deliberately untouched: the disposition pattern the card records is to strike or annotate in place with the reason, never to guess a replacement number, and picking three sites out of 2,785 by hand is arbitrary. Successor: whoever the seat gives the wiring ruling to, since the census is the input to that decision. - **The `/issues` list endpoint refuses `page` beyond a depth** on this repository ("Pagination with the page parameter is not supported for large datasets") and GitHub's own `Link` header answers in the `repositories/{id}/...` form, which this session's proxy refuses. Both are handled here (`normalizeNextUrl`), and any future board enumerator in this tree hits the same two walls. Successor: none today — no other script in this tree enumerates the whole board. - **`--census` costs 159 requests and grows with the board.** Fine on a schedule, wrong per PR; that asymmetry is the reason the two lanes above are named separately. --- _Generated by [Claude Code](https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2445b27 commit 1bdbf82

2 files changed

Lines changed: 986 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"check:watch-hint-literal": "node scripts/check-watch-hint-literal.mjs --self-test && node scripts/check-watch-hint-literal.mjs",
7878
"check:declared-population-live": "node scripts/check-declared-population-live.mjs --self-test && node scripts/check-declared-population-live.mjs",
7979
"check:pm-half-states": "node scripts/pm/check-half-states.mjs --self-test",
80+
"check:issue-citations": "node scripts/check-issue-citations.mjs --self-test",
8081
"check:pm-clause2-carriers": "node scripts/pm/check-clause2-carriers.mjs --self-test",
8182
"check:pm-widening-tells": "node scripts/pm/check-widening-tells.mjs --self-test",
8283
"check:pm-prior-rulings": "node scripts/pm/check-prior-rulings.mjs --self-test",

0 commit comments

Comments
 (0)