chore(devx): migrate the scripts/** line citations that name no tracked file to file-level anchors (#15809) - #16301
Merged
baozhoutao merged 5 commits intoSep 6, 2026
Conversation
…s, not just their count `judgeUntrackedLineAnchors: false` waives a citation that names no tracked file, and until now the only trace was a number on the green line. A number says a residual exists without saying where: it cannot be worked down, and a residual that MOVED reads exactly like one that shrank. `sweepCorpus` now returns `declined` beside `findings` and `counts` — one row per waived citation, carrying the file, the line, the citation text and a shape (`bare-filename` / `directory-qualified` / `continuation` / `tilde`). `declinedShape` classifies by how the citation was WRITTEN, never by the path it borrowed: a continuation and a tilde form inherit whatever path preceded them on the line, so classifying by path first would file them under a file their author never wrote. `check-scripts-symbol-anchors.mjs --list-unresolvable` prints those rows and a tally by shape. It is a listing, never a verdict — it exits 0 whatever it prints, exactly as `--list` does, and `runCheck()` remains the only failing arm. Pinned: three cases hold the enumeration equal to the counter, to the file/line/text a residual list needs, and to the shape classification (floor 26 → 29); four more hold each arm of `declinedShape` (floor 63 → 67). Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
…st carriers `check-durability-degradation-log-level` (23), `symbol-anchors` (15), `doc-line-anchors` (11) and `pr-labels` (8) carried more than half the citations that name no tracked file, and each shape gets the repair its own kind admits: - DATED CENSUS ROWS name the file as a file-level anchor and keep the number beside it as data, losing no digit — the `#15806` method. The durability gate's two seam tables gain a `try line` column of their own, and `objectql engine.ts` / `metadata-protocol protocol.ts` become the full tracked paths the gate's own output actually prints. One of them binds tighter still: `packages/objectql/src/engine.ts#cascadeDeleteRelations` is now a resolved symbol anchor. - ILLUSTRATIONS take the angle-bracket placeholder spelling `ANCHOR_GRAMMAR` already uses. `symbol-anchors.mjs` and `doc-line-anchors.mjs` are the two files that DEFINE what a line citation looks like, so every example in them was a citation of its own; they now exhibit the shape without writing one, and say why in a⚠️ line so a later author does not "fix" it back. - THIRD-PARTY SOURCES (`codelytv/pr-size-labeler`, `actions/labeler`) name the repo, the file and the pinned line as prose. No in-repo resolver could ever check them, and a pinned upstream line is provenance rather than a pointer. ⛔ No number is repaired or repointed anywhere in this commit: every digit that was in an anchor is still on the page, as data. Corpus reading: 96 → 39 unresolvable citations. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
… residual The rest of the population #15809 measured, one repair per shape: - TRACKED TARGETS the surrounding prose already names become file-level anchors, and where the prose names the symbol too they become symbol anchors the gate now resolves — `packages/objectql/src/plugin.ts#runGovernanceInventory`, `packages/plugins/plugin-audit/src/audit-writers.ts#resolveWriteLocale`, `scripts/check-system-context-census.mjs#UNENFORCED_TEXT_COUNTS`. A bare `engine.ts` was never ambiguous where the prose said which package. - THIRD-PARTY AND DEPENDENCY SOURCES (`@oclif/core`, `@changesets/pre`) name the package, the file and the pinned line as prose. Nothing in this tree can resolve them, and a pinned upstream line is provenance, not a pointer. - ILLUSTRATIONS take the angle-bracket placeholder spelling. ⛔ Again, no number is repaired or repointed: every digit is still on its page. The residual is 15 citations across six files, and every one of them is a file another lane holds OPEN — three by PR #16215, one by PR #16202, three by the in-flight #15776, one by #12511. NOT ONE is a genuinely ambiguous abbreviation.⚠️ `judgeUntrackedLineAnchors` therefore stays `false`. The fence this work was dispatched under flips it only when the residual is ZERO and a self-test pins the flip; flipping it over 15 citations in files this PR may not touch would make the gate permanently red for the length of somebody else's pull request — the exact shape the card argued against. `--list-unresolvable` now prints that residual, so the next author inherits a worklist rather than a count. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
…ripts-line-citations-migration
`--list-unresolvable` is the live instrument; a count written in prose is a dated record, and this file is the one arguing that a number in prose outlives the measurement it quoted. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
This was referenced Sep 6, 2026
baozhoutao
marked this pull request as ready for review
September 6, 2026 13:20
baozhoutao
enabled auto-merge
September 6, 2026 13:20
baozhoutao
deleted the
claude/issue-15809-scripts-line-citations-migration
branch
September 6, 2026 14:13
baozhoutao
pushed a commit
that referenced
this pull request
Sep 6, 2026
…vel anchors Second round of the scripts/** unresolvable-citation migration PR #16301 started. Two of the six held files freed since that PR landed -- check-docs-section-name.mjs and docs-audit/affected-docs.mjs (PR #16300), check-type-check-coverage.mjs (PR #16295) -- so their 7 citations migrate now by the same method: the file named as a file-level anchor, the number kept beside it as data, no digit repaired or repointed. - check-docs-section-name.mjs: concept.mdx:426, doc-pages.mdx:257 and forms.mdx:183 each resolve to exactly one tracked file under content/docs/** (forms.mdx is ambiguous by basename alone -- two files share it -- but only content/docs/ui/forms.mdx has a line 183 carrying the cited "sections": [/* ... */] shape). - check-type-check-coverage.mjs: engine.test.ts:2547/2577 resolves to packages/services/service-automation/src/engine.test.ts, named by the surrounding prose ("service-automation's note"). - docs-audit/affected-docs.mjs: three rest-server.ts citations resolve to packages/rest/src/rest-server.ts, the only tracked file of that name. The corpus residual (scripts/check-scripts-symbol-anchors.mjs --list-unresolvable) drops from 15 to 8, all 8 still held by open PRs (#16215, #16202) -- none an ambiguity. judgeUntrackedLineAnchors stays false per the #15809 fence (flips only at residual zero). Header prose updated to record both dated readings. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
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.
Part of #15809.
The card measured 128 live line citations in
scripts/**comment prose, ofwhich 96 named no tracked file and so were declined by the corpus registered in
PR #15806 (
judgeUntrackedLineAnchors: false). This migrates 81 of them by thatPR's own method, enumerates the rest, and leaves the flag alone. #15809 is not
closed here — the residual belongs to triage.
1. The enumeration came first
The corpus counted the declined citations and printed only a number, so nobody
could work the residual down and a residual that MOVED read exactly like one
that shrank.
sweepCorpusnow returnsdeclinedbesidefindingsandcounts— file, line, citation text and a shape — andprints them with a tally. It is a listing, never a verdict: it exits 0 whatever
it prints, exactly as
--listdoes, andrunCheck()is still the only failingarm.
Re-derived on this tree (the card's shape table was taken on
5315098df, beforethe corpus landed):
5315098dfbda7b7c83The total reproduces exactly; the split does not, which is why it was
re-derived.
declinedShapeclassifies by how a citation was WRITTEN, never bythe path it borrowed — a continuation and a tilde form both inherit whatever
path preceded them on the line, so classifying by path first files them under a
file their author never wrote.
23 rows — is
scripts/check-durability-degradation-log-level.mjs, NOTscripts/check-system-context-census.mjs(which carries 4). The 23 were free toedit and are migrated.
2. The migration
scripts/check-durability-degradation-log-level.mjsscripts/symbol-anchors.mjsscripts/doc-line-anchors.mjsscripts/pr-labels.mjsscripts/check-system-context-census.mjsscripts/check-docs-section-name.mjsscripts/check-runtime-services-index.mjsscripts/check-tenant-audit-census.mjsscripts/cross-package-test-inputs.mjsscripts/docs-audit/affected-docs.mjsscripts/check-cli-test-child-env.mjsscripts/check-dispatcher-error-vocabulary.mjsscripts/check-settings-bind-window.mjsscripts/audits/14096-tenancy-ledger-namespace-regexp-census.mjsscripts/audits/14423-unbound-declarations-before-count.mjsscripts/check-adr-links.mjsscripts/check-changeset-no-major.mjsscripts/check-console-injection.mjsscripts/check-doc-anchors.mjsscripts/check-engine-double-contract.mjsscripts/check-live-db-isolation.mjsscripts/check-overlay-whitelist-table.mjsscripts/check-platform-checklist.mjsscripts/check-type-check-coverage.mjsscripts/check-workflow-status-functions.mjsscripts/objectui-changeset-digest.mjsscripts/pm/check-half-states.mjsFour repairs, one per shape, all of them PR #15806's method:
beside it as data. The durability gate's two seam tables gain a
try linecolumn of their own, and a bare
engine.tsbecomespackages/objectql/src/engine.ts— never a guess, because the prose besideevery one of them already said which package.
gate now resolves:
packages/objectql/src/plugin.ts#runGovernanceInventory,packages/plugins/plugin-audit/src/audit-writers.ts#resolveWriteLocale,packages/objectql/src/engine.ts#cascadeDeleteRelations,scripts/check-system-context-census.mjs#UNENFORCED_TEXT_COUNTS.Resolved symbol anchors in the corpus: 21 before, 27 after.
scripts/symbol-anchors.mjs#ANCHOR_GRAMMARalready uses.scripts/symbol-anchors.mjsandscripts/doc-line-anchors.mjsare the twofiles that DEFINE what a line citation looks like, so every example in them
was a citation of its own; they now exhibit the shape without writing one, and
each says so in a
codelytv/pr-size-labeler,actions/labeler,@oclif/core,@changesets/pre) name the repo, the fileand the pinned line as prose. No in-repo resolver could ever check them, and a
pinned upstream line is provenance rather than a pointer.
⛔ Not one number is repaired or repointed. Every digit that was inside an
anchor is still on its page, as data — that is the whole of the #15806 method
and the reason it loses nothing.
3. The flag decision, and its fence
judgeUntrackedLineAnchorsstaysfalse.The fence this work was dispatched under: flip it only if the residual after
migration is ZERO and the corpus self-test pins the flip. The residual is 15,
so the fence does not open. Reading it row by row matters more than the number:
⭐ Every one of the 15 is residual by EXCLUSION, not by ambiguity. All six
files are held open by another lane right now — three of them by PR #16215, one
by PR #16202, three by the in-flight work on #15776, one by the in-flight work
on #12511 — and this card's file surface excludes them by name. Zero citations
were left behind because the prose did not say which file they meant.
That distinction is the whole decision. Flipping the flag today would make this
gate red for the length of somebody else's pull request, over citations this PR
was told not to touch — the permanently-red gate the card itself argued against.
Flipping it after those six files are migrated is a one-line change with a case
to pin it, and
--list-unresolvableis the worklist that gets it there.4. Corpus readings
bda7b7c83unresolvableLineCitationorigin/mainwas merged inmid-branch and brought
scripts/sync-release-index-currency.mjswith it. Thatfile adds no declined citation — the residual read 15 both immediately before
and immediately after the merge — so the 96 to 15 delta is this PR's alone.
5. Tests
The pin is exercised, not assumed. Three cases hold the enumeration equal to the
counter, to the file/line/text a residual list needs, and to the shape
classification (self-test floor 26 → 29); four more hold each arm of
declinedShape(floor 63 → 67).Ablation — mutation proven on disk, restore proven byte-identical to
HEAD,each leg anchored on a grep count of the text injected and the text removed:
Direction as predicted: turns red, and names the case. A first attempt at the
same ablation was a no-op —
perl -0piwith a\Q…\Eblock matched nothing andstill exited 0 — and was caught by the on-disk blob comparison rather than by
the run's colour, which is exactly why that check runs before the verdict is
read.
6. Gates
Derived on the final tree with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(54 commands over the 22-path change set, three-dot against the merge base) and
reconciled with
--ran:All 54 exit 0. The list is the derivation's own, not a hand-kept one, and
includes every gate whose family this diff touches — among them
check:durability-log-level,check:platform-checklist,check:doc-anchors,check:comment-mask-corpus,check:nul-bytes,check:cross-package-test-inputs,check:pm-dispatch-gatesand both self-tests of the two files carrying themechanism (
check-scripts-symbol-anchors.mjs --self-test,symbol-anchors.mjs --self-test).Every touched gate is a gate whose own plain run and
--self-testare in that54, and all of them pass. The edits are confined to
//and/* */commenttext; the one file whose header moved most
(
check-durability-degradation-log-level.mjs, 23 citations) readspackages/**TypeScript sources for its census and its own comments fornothing, and its verdict is unchanged.
The repo-wide scan ran too, not just the derived families:
pnpm lint(eslint . --no-inline-config) exits 0 with no output over thewhole tree. It ran at
5e66dc83b; the one commit after it is comment-only in asingle file, re-linted on its own at this head, also 0.
No changeset: this PR publishes nothing from any package — 22 files, all under
scripts/**, all comment prose plus one listing flag.skip-changesetapplied.⛔ No file under
content/docs/releases/is touched.🤖 Generated with Claude Code
https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
Generated by Claude Code