Repository navigation
fix(check-adr-symbol-anchors): the verdict may not claim a census wider than the vocabulary it read - #18925
Conversation
The #13556 ruling deleted the ADR line-anchor class with no transition period. Three pointers to `security-plugin.ts` line 626 survived it as a bare `:NNN` continuation -- the path and the number split across different table cells, a shape the gate's vocabulary does not read. Sampled before deleting, which is what #13556's own basis was: `packages/plugins/plugin-security/src/security-plugin.ts` line 626 is today a JSDoc closing line inside the `SecurityReportSink` interface -- a logging sink type, not the read-filter fall-open the three sentences describe. The pointer is stale. Deletion alone would leave two of the three sentences without a referent, so those two take the symbol anchor the ADR's own table row already uses for that site (`#getReadFilter`, first cell of the same row); the third points at the row above it instead. Both substitutions resolve, so the gate's anchor count rises 2093 -> 2095 and the two new pointers are checked rather than merely shorter. Claude-Session: https://claude.ai/code/session_01AmH9bKvGoLjiY86Q4Z3og2 Co-authored-by: Claude <noreply@anthropic.com>
The second shape that survived #13556's no-transition deletion: the line number written as a markdown link-target fragment, `<path>.ts#L198`, where the gate's grammar reads only a backticked span and so sees neither the path nor the number. Sampled before deleting. Both fragments claim to point at `validateRecord` in `packages/objectql/src/validation/record-validator.ts`. Line 198 of that file today is a comment inside the `ValidationError` constructor; `validateRecord` is declared at line 1185. The pointer is 987 lines off and lands on unrelated code -- the same failure shape as the 4/4 sample #13556 ruled on. The path half of both links is correct and survives, so this is a pure deletion of the fragment: the links drop to the file-level target the gate's remedy text names as the second exit. Upgrading them to checked `path#symbol` anchors -- the idiom this same record already uses at :57 -- would be a prose change the ruling does not call for and is left to the maintainer. Claude-Session: https://claude.ai/code/session_01AmH9bKvGoLjiY86Q4Z3og2 Co-authored-by: Claude <noreply@anthropic.com>
A third spelling of the same class, found by widening the caliber past
the two literals the card measured: `L354/L371/L410/L765` written as
bare prose beside a file-level link, carrying no path of its own.
Sampled before deleting -- 4/4 stale. Those four lines of
`packages/spec/src/data/object.zod.ts` are today a comment about a
closed batch site, a comment about `where` guidance, `const nearMiss =`,
and a comment about author-time rejection. None is the "managed-by
buckets and toolbar lifecycle actions" the sentence cites them for; the
file's `lifecycle` block now sits at 818-1010 as an ADR-0057
retention/ttl/storage/archive policy.
The file-level link was already there and is kept, so the sentence's
claim that `lifecycle` is overloaded in that file stays checked and
stays true. ⛔ The prose is NOT repaired: whether the parenthetical's
specifics ("managed-by buckets", "toolbar lifecycle actions") still
describe that file is a separate defect and takes its own card, exactly
as this gate's header instructs.
Claude-Session: https://claude.ai/code/session_01AmH9bKvGoLjiY86Q4Z3og2
Co-authored-by: Claude <noreply@anthropic.com>
…er than the vocabulary it read The green line ended `0 line anchors survive.` -- unqualified, and measured false while it printed. Nine pointers of the class the #13556 ruling deleted were live in `docs/adr/**` in two spellings this corpus does not judge: the path-less bare colon continuation (three in one record, the path in a different table cell from the number) and the `L` pin, bare in prose and as a markdown link-target fragment (six across two records). The reading was right; the sentence spoke for the whole class instead of for what it read. So the repair is the CLAIM. `summaryLine()` now names the vocabulary it judged and states that the two path-less spellings are opt-in and off here. Widening instead was MEASURED and is not taken in this change: `pathlessLineCitations: true` on this corpus yields 17 findings across 6 records, 2 of them an ADR's dev-server ports -- correct prose whose only remedy is the maintainer-only exemption marker. The self-test's new battery holds the claim in three parts, and the middle one is the light-on-a-literal control: the corpus DECLARES the narrower vocabulary; the shared grammar really does see the wider one on the same text when asked (so the caveat is a measurement, not a hedge over a rule that matches nothing); and the sentence names both halves and can no longer end in the unqualified form. Flipping the declaration now forces the verdict to be re-stated in the same edit. Battery floor 17 -> 22. Claude-Session: https://claude.ai/code/session_01AmH9bKvGoLjiY86Q4Z3og2 Co-authored-by: Claude <noreply@anthropic.com>
维护者速读(终稿)席位 改了什么两件事,3 个文件、+83/−13。 一是删掉 9 个指向源码行号的旧指针,我从 diff 里重新数过:ADR-0020 6 个( 二是把门禁结语从「0 line anchors survive.」改成说清它究竟量了哪几种写法、哪两种没量。 门禁的判定逻辑一行没动,只动了它对外的说法,外加自测。 为什么改#13556 已裁决「ADR 行号锚」这一类无过渡期删除,依据是 4/4 抽样全部指向无关代码。但门禁的词汇表比那一类窄,于是两种写法活了下来:一种把行号藏在 markdown 链接的 fragment 里,一种把行号与路径拆在同一表格行的不同单元格里。门禁读不到它们,却仍然印「0 … survive」。 读数是真的,那句话不是 —— 这就是本卡的判据 (b)。一句印在绿灯里的假零,下一个人会据它认定这一类已经清完。 ⭐ 我自核了那个「烂化」是真的,没采信报告: 风险与代价(含回滚)很低。
席位意见我判 ACCEPT,并且认为这张 PR 的质量高于它的体量。 三个具体理由:
你要做的一个动作:确认并合并 #18925(等 CI 全绿)。 看的时候请重点只看一处:ADR-0096 那两句的指代替换读起来是否仍指同一个站点(把 ⛔ 这是受管面( Generated by Claude Code |
|
CI 现已全绿 —— 速读里那句「等全绿之后再合」的条件已满足。 席位
⇒ 本 PR 现在没有任何未完成或非绿的 check。⛔ 我仍然不合它 —— 受管面(
Generated by Claude Code |
…stack-ai#13556 fence (objectstack-ai#19022) Fixes objectstack-ai#18932 Clause-②: no Deletes the six stale line pointers that ADR-0021, ADR-0034 and ADR-0077 still carried after the objectstack-ai#13556 class removal — six pointers across five lines in three records. The prescription is **deletion**, not renumbering: the ruling retired this *class* of pointer, and all six were sampled as naming code that has nothing to do with the prose citing them. Note on spelling in this body: this repository's body sanitizer eats angle-bracket-shaped fragments, so every such fragment below is written in placeholder words. One substitution is load-bearing and is flagged inline. The byte-exact text is the diff. ## The five sites, each judged on its own Each pointer was removed so that the surrounding prose keeps every other fact it was carrying — in particular the referent (a path or a symbol name) survives at every site, so nothing needed a replacement referent. **1. ADR-0021 line 372** — removed `, L806 + L961`; `(**two** lists)` deliberately kept. ``` - **Registration touches 4 surfaces**, not 1: `kernel/metadata-type-schemas.ts`, `kernel/metadata-plugin.zod.ts` (enum + `DEFAULT_METADATA_TYPE_REGISTRY`, `loadOrder` LESS-THAN report/dashboard), `shared/metadata-collection.zod.ts` (`MAP_SUPPORTED_FIELDS` + `PLURAL_TO_SINGULAR`), `objectql/engine.ts` `metadataArrayKeys` (**two** lists). ```⚠️ `LESS-THAN` above stands for a single less-than character that is pre-existing, untouched prose. It is spelled out only to survive this body; the file itself is unchanged there. **2. ADR-0034 lines 42-43** — removed ` around L1811`. ``` `engine.transaction()` threads the open transaction into the driver options of the *top-level* write via `buildDriverOptions` (`engine.ts`, which even warns about this deadlock). But internal reads/writes performed **during** ``` **3. ADR-0034 line 57** — removed ` L561-563`. ``` savepoint on the parent transaction (`sql-driver.ts`). The gap is ``` **4. ADR-0034 lines 59-61** — removed `L548-600` and the comma that introduced it; the bullet keeps all four of its symbol referents. ``` - `driver-sql` already implements a **persistent, atomic sequence** (`SEQUENCES_TABLE` + `getNextSequenceValue` with `forUpdate` + seed-from-max). See "Autonumber (objectstack-ai#1603)" below — this is mostly already solved at the driver level. ``` **5. ADR-0077 line 51** — removed `, ~L3217`. ``` 2. **The flow path does not thread the transaction explicitly**, and ALS is fragile here: it does **not** survive `setImmediate`/deferred-promise boundaries (the documented sandbox-runner limitation in `engine.ts`). Any atomicity would be *accidental* (inline before-path only) and *untested* — not a guarantee an author may rely on. ``` ## Evidence Base for every reading below: `origin/main` = `64de4c5764` (the merge of objectstack-ai#18925), merged into this branch. The dispatch order was written against `43f4766889` and predicted "4 files before, 1 after (ADR-0020 remaining)"; objectstack-ai#18925 landed at 11:53:36Z and cleared ADR-0020, so the correct expectation is **3 files before, 0 after**. Both the corrected expectation and the reading below were taken first-hand on this tree. The probe is the shared grammar's own `PATHLESS_L_CITATION` regular expression, copied verbatim from `scripts/symbol-anchors.mjs` — the path-less L-pin spelling (optional tilde, the letter L, two or more digits, optional dash-range, word-boundary on both sides). It is not re-invented here. | leg | reading | |---|---| | **BEFORE** — base tree, whole `docs/adr/**` | **3 files / 6 matches**: ADR-0021 ×2, ADR-0034 ×3, ADR-0077 ×1 | | **AFTER** — this tree, whole `docs/adr/**` | **0 files / 0 matches** | | **LIGHT-ON** (same probe, same run, corpora this diff never touches) | `docs/audits/2026-08-partial-retirement-annotation-signal.md` = **6**, `docs/launch-readiness.md` = **3** | | **FORGED NEEDLE** | a fabricated pin reads **0** across `docs/adr/**`, and **1** in a scratch file where it was planted with the same probe | | **DARK** — `docs/adr/0047-object-ui-run-modes.md` | blob `b50b52863d` on `origin/main` and `b50b52863d` in this worktree — byte-identical, not in the diff | The two light-on corpora and the planted needle are what make the zero a reading rather than a non-measurement: the same probe, in the same run, read non-zero in three named places. ### Instrument reach radius, and a known target outside it The AFTER reading is a **zero**, so the radius is stated by form and a known target outside it is named — both measured, not asserted. **Inside the radius.** Content layer: the raw line text of every file under `docs/adr/`, read line by line. Form: an optional tilde, the letter `L`, two or more digits, an optional dash-range, with a non-word character required on both sides. Measured, this radius is *wider* than the gate's in two ways worth naming: an L-pin written inside a markdown link target (the hash-L-digits form that objectstack-ai#18925 dealt with) **is** read — measured, 1 match on a planted sample — and so is one written inside a code fence, which the gate deliberately skips as quoted material. So neither of those is a valid out-of-radius target here. **Outside the radius, by form.** The path-anchored colon spelling (a filename, a colon, digits), the path-less colon continuation (a bare colon and digits continuing a filename named earlier), and any single-digit L pin. Also outside, by population: every corpus that is not under `docs/adr/`. **The known target.** `docs/adr/0065-sdui-styling-model.md` line 96 carries a live path-anchored colon anchor into `packages/sdks/src/types/builder-block.ts` at line 42, tagged with the maintainer-only exemption marker. It is in the same corpus, the same file type and the same content layer as everything this PR measured — it differs from the deleted pointers **only in form**. Measured on that exact line: the L-probe reads **0**, the colon probe reads **1**. Across `scripts/*.mjs` the same asymmetry holds at scale — 127 colon-form targets present, the L-probe reads 0 on all 127. ⇒ The zero above is therefore a reading about the L-pin form in `docs/adr/**`, and ⛔ not a claim that no line pointer of any spelling remains anywhere. The colon form is judged by `check-adr-symbol-anchors`, which is green. **What the gate says, and why this diff is invisible to it.** The ADR corpus declares `pathlessLineCitations: false`, so `check-adr-symbol-anchors` never judged this spelling — before or after. Measured: the gate-visible colon form reads **0 before and 0 after** in all three records, and the gate is green on both trees. objectstack-ai#18925 (already landed) is what stopped its verdict line from *claiming* a census it had not taken; this PR removes the pointers that claim was measured false against. No gate script, corpus vocabulary or `pathlessLineCitations` switch is touched here. **Gates.** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 18 families on the merged tree; all 18 run, all exit 0, exit codes captured before any pipe and reconciled with `--ran`: *18 derived, 18 run, 0 NOT-MEASURED, 0 UNRUN*. One family (`check:doc-formula-expressions`) first exited **3 — PREREQUISITE NOT MET**, which is a refusal to measure and not a finding; after building `@objectstack/formula` and `@objectstack/lint` as its own output instructs, it exits 0. **Changeset — `skip-changeset`.** Per-path reading over the 70 non-private packages that declare a `files[]`: all three diff paths are `docs/adr/**`, none sits inside a published package directory, and none matches any `files[]` entry. Nothing this PR changes is shipped by any package. ## Acceptance notes Observed while working, deliberately **not** filed and **not** fixed here: - The blocker the card records is confirmed present and untouched: `docs/adr/0047-object-ui-run-modes.md` lines 48-49 carry two dev-server ports that the shared `pathlessLineCitations` grammar would read as line citations. That file is byte-identical here. Anyone widening the ADR corpus vocabulary still has to settle those two first. Successor: that future vocabulary-widening PR — it cannot avoid this file. - `docs/audits/2026-08-partial-retirement-annotation-signal.md` (6) and `docs/launch-readiness.md` (3) carry the same path-less L-pin shape outside `docs/adr/**`. Whether other corpora should be swept is a scoping question no one has asked; they are used here only as light-on controls. Successor: none today. ## Governance `docs/adr/**` is a governed surface. This PR stays **draft**; it is not merged, not queued, and auto-merge is not armed. Landing waits for the maintainer's approval. ## 维护者速读(草稿) **改了什么** —— 三份 ADR(0021 / 0034 / 0077)的散文里删掉 6 个指向源码行号的指针,分布在 5 行上。只删数字,每句话的路径名或符号名都留着,句子读起来完整。 **为什么改** —— objectstack-ai#13556 已经裁定「ADR 行锚点」这一类整体删除、无过渡期。objectstack-ai#18925 清掉了 ADR-0020 与 ADR-0096 里的,这 6 个当时在那张卡申报的文件面之外,所以留了下来。这 6 个都被抽样核过,指向的是今天完全无关的代码 —— 留着它们会把读 ADR 的人(和 AI)引到错的位置。 **风险与代价(含回滚)** —— 风险很低:纯散文删字,不动任何代码、门禁脚本或开关,任何包的发布内容都没有变(所以 `skip-changeset`)。回滚就是 revert 这一个 PR,没有数据迁移、没有生成物、没有下游依赖。唯一的信息代价是读者不再能从 ADR 直接跳到某一行 —— 而那正是本次要消除的东西,因为那些行号早就指错了。 **席位意见** —— **你要做的** —— `docs/adr/**` 是受管面,需要你本人的 approval 才能落地。请看一眼上面五处改后的整句,确认散文没有丢信息(尤其 ADR-0021 那句要保住「**two** lists」这个事实),然后决定是否 approve。 --- _Generated by [Claude Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_ Co-authored-by: Claude <noreply@anthropic.com>
Fixes #18899
Clause-②: no
check-adr-symbol-anchorsprinted0 line anchors survive.and that sentencewas false. This change deletes the surviving pointers inside the declared file
surface — every one of them sampled stale before it was deleted — and makes the
verdict stop claiming a census it does not take.
Caliber first, then the count
⛔ No count is inherited here, mine included. A line pointer is defined as a
token in an authored document that designates a position in a source file by
LINE NUMBER. The class was then enumerated by SPELLING — six of them — and each
regex was lit on a literal it must see before any corpus was read; the two
path-less spellings additionally got a negative control on the neighbours they
must refuse (an HTTP status, a URL port, a clock time, a lane label, an
identifier ending in a capital L before digits). Fenced blocks are skipped,
exactly as the extractor skips them, so quoted material is not counted as
authored.
docs/adr/**at the branch point, 139 records:anchor-exemptmarkers, which is why the gate was greenLpin as a markdown link-target fragmentLpin bare in prose (E is a subset of F)Two of D's five are ADR-0047's dev-server ports, which are not line pointers at
all, so the caliber's verdict is: 15 real line pointers across 5 records were
invisible to this gate — not 5, and not 2.
The card's 「未復現」 section, reproduced
The handed-over report claimed 12 fragments across ADR-0020×6, ADR-0021×2,
ADR-0034×2, ADR-0077×1, and the filing seat could neither reproduce the 12 nor
make the parts sum to it. At spelling F the measurement is 12 across exactly
those four records, distributed 0020×6 · 0021×2 · 0034×3 · 0077×1. So the
total was right, the 0034 subtotal was one short, and the class it
counted was the
Lpin rather than the narrower#Lfragment the filing seatmeasured at 2. ⛔ Neither reading was wrong; they were two calibers. Both are
reproduced above, from one instrument, with the light on.
The reading that decided deletion, not correction
#13556 ruled this class deleted with no transition period, on a 4/4 sample of
pointers landing on unrelated code. The card states plainly that it did not take
that sample. Taken here, on every pointer the caliber found — 15/15 stale:
security-plugin.ts626 (ADR-0096 ×3)getReadFilterread-filter fall-openSecurityReportSinklogging-sink interfacerecord-validator.ts198 (ADR-0020 ×2)validateRecordValidationErrorconstructor;validateRecordis declared at 1185 — 987 lines awayobject.zod.ts354 / 371 / 410 / 765 (ADR-0020 ×4)where-guidance comment,const nearMiss =, an author-time-rejection comment. The file'slifecycleblock now sits at 818-1010 as an ADR-0057 retention/ttl/storage/archive policyengine.ts806 + 961 (ADR-0021 ×2)metadataArrayKeyslistsmetadataArrayKeysis discussed at 2327, where a comment says it USED to be two listsengine.ts1811,sql-driver.ts561-563,sql-driver.ts548-600 (ADR-0034 ×3)SEQUENCES_TABLEis at 181engine.ts3217 (ADR-0077 ×1)setImmediatediscussion is at 4572 / 15700 / 15866The structural clue the card asked to be verified holds: ADR-0096's inherited
path does sit in the same table row as the bare number, in a different cell. That
is why the path-anchored pass cannot see it — there is no path adjacent to the
number to anchor on.
What this change does, and what it deliberately does not
Three deletion commits, one per distinct stale target, each carrying its own
sample in the message; then one commit on the gate.
ADR-0096 — deleting a path-less number leaves the sentence with no referent,
so two of the three take the symbol anchor the record's own table row already
uses for that site, and the third points at the row above it. Both substitutions
resolve: the gate's anchor count rises 2093 to 2095 and 2 of those are new
CHECKED pointers rather than merely shorter prose.
ADR-0020 — the path half of the links is correct and survives, so these are
pure fragment deletions dropping to the file-level target the gate's own remedy
text names as its second exit. ⛔ The prose is not repaired: whether ADR-0020's
parenthetical still describes
object.zod.tsis a separate defect and takes itsown card, exactly as this gate's header instructs.
The gate —
summaryLine()now names the vocabulary it judged and states thatthe two path-less spellings are opt-in and off here. The self-test holds the
claim in three parts, and the middle one is the control that makes the battery
worth running: the corpus DECLARES the narrower vocabulary; the shared grammar
really does see the wider one on the same text when asked; and the sentence names
both halves and can no longer end in the unqualified form. Battery floor 17 to 22.
⛔ Route (c), widening the vocabulary, is MEASURED and NOT taken
pathlessLineCitations: trueon this corpus yields 17 findings across 6records. Two of them are ADR-0047's dev-server ports: correct prose no author
can repair, whose only remedy is the maintainer-only exemption marker. Four of
the six records are outside this card's declared file surface. The alternative
route is worse:
unspannedAnchors: trueyields 8 findings, 6 of themfabrications — correct relative ADR-to-ADR markdown links reported as missing
FILES because a heading fragment reads as a symbol.
So the price tag is real and the decision is not this sentence's to make. What
the sentence owed was to stop reading as though the decision had already gone the
other way. ⛔ It also cannot be taken inside this fence at all: the vocabulary
lives in
scripts/symbol-anchors.mjs, shared by five corpora, and that file isoutside the declared surface. This change does lower the bill: the 17 becomes
8 once these nine pointers are gone.
Evidence
Gates —
dispatch-gates --repo objectstack-ai/objectstack --commandsderived37 families from the real three-path change set; all 37 run, all exit 0,
reconciled with
--rancarrying exit codes: "37 derived families accounted for —37 run, 0 NOT-MEASURED (a DERIVED zero — all 37 recorded an exit code and none of
them is 3)". One needed a second pass:
@objectstack/lint check:doc-formula-expressionsfirst exited 3 —PREREQUISITE NOT MET, which its own text declares is not a finding; after
turbo run build --filter=@objectstack/formula --filter=@objectstack/lintitexits 0.
Ablation, 4 legs, all on the final tree at
c38eead. Every leg proved itsmutation reached disk (anchor count dropped, blob hash moved) before the run was
read, and every restore was verified by blob-equals-HEAD plus an empty
git diff HEAD— not by an exit code:pathlessLineCitations: trueLeg b is the one that matters: without it, legs a and c would hold just as
well on a day when the wider grammar had stopped matching anything, and the new
caveat would be documenting a dead rule.
Lint, a declared narrowing rather than the farm run. Three readings, all at
c38eead: ① the examined population comes from eslint's own config, not aguess —
ESLint#isPathIgnoredanswerstruefor bothdocs/adr/**records(they are outside eslint's population entirely) and
falsefor the script;②
--format jsonreports 1 file linted, 0 errors, 0 warnings; ③ invariance —eslint.config.mjsstates in its own words that this repo "runs oneeslint.config.mjs, which never enables type-aware linting (noparserOptions.project, no typed@typescript-eslintrules) for ANY file", anda grep for that configuration finds only the comment saying it is absent, so no
verdict on an untouched file can move as a function of this diff. The repo-wide
eslint . --no-inline-configremains CI's run.Control bytes —
check:nul-bytesgreen, plus a direct scan of the touchedfiles for the non-NUL control bytes it does not cover: no matches.
Changeset:
skip-changeset, measuredNothing published moves. The root package is
private: true, and 0 of the 70public packages has a
files[]entry that escapes its own directory or namesdocs/adr. Measured at the byte level against the built output with a matchedpositive control: a grep for the exact text this diff changed
(
record-validator.tsplus the fragment, the four-pin list, the two:626sentences, the old verdict phrase) across every built
dist/exits 1, whilethe same grep shape fires on 168 files for a symbol that is published. One
near-miss worth naming: published
.d.tsfiles DO cite ADR-0020 by URL, so therecord's filename ships — its text does not.
Acceptance notes
⛔ Out of the declared file surface, so measured and reported rather than touched:
fence does not name — ADR-0021 ×2, ADR-0034 ×3, ADR-0077 ×1. All six sampled
stale above. Editing them would breach the fence and would widen the file
surface the claim comment declared, so they are left for a follow-up card;
the staleness sampling is already done above. Dedupe words:
L pin pathless ADR line pointer·0021 0034 0077 stale L citation·adr-anchors blind form remainder·pathlessLineCitations adr corpus.correct prose whose only remedy is a maintainer-only marker. Any widening card
has to decide that first. Dedupe words:
dev-server port read as line citation·pathless colon false positive 0047.toolbar lifecycle actions") still describes
object.zod.ts, whoselifecycleblock is now an ADR-0057 retention policy. The record's claim that
lifecycleis overloaded there is still true, so this is prose drift in thespecifics, not a false statement — and this gate's header forbids repairing
prose to clear it. Carrier: the next author of ADR-0020's naming section; no
PR is queued on it.
**Schema Migration FROM → TO:**) reads as a MENTION and is admitted with no rewrite #18494 and check-adr-0087-registration: findMigrationPrescription still reads a MENTION as a label through an identifier tail and across a hard wrap #18493 are held out of this round at the seat and are not addressedhere. [finding] ADR line anchors into
sql-driver.tshave rotted — 4 of 4 sampled resolve to unrelated code, and the ADRs read as if they still point at the mechanism they name #13556 · [finding] 61 stale FULL-path mentions in ADRs outside the #13556 census — path rot, a different class from line-anchor rot #14279 · [finding] 96 of the 128 line citations inscripts/**gate headers name no tracked file, so the new symbol-anchor corpus declines them by name #15809 · [finding] the shared symbol-anchor resolver refuses 8 anchors that name real declaration sites — an INLINE object-literal key, and a DATA identifier that heads a dotted string token #18101 are near neighbours and none folds in.维护者速读(草稿)
改了什么. 两件事。一是删掉九个指向源码行号的旧指针——三个在 ADR-0096、六个在
ADR-0020,删前逐个抽样,九个全部指向无关代码(最离谱的一个偏了 987 行,落在一个错误类的
构造函数里)。二是把门禁那句结语从「0 line anchors survive.」改成说清它究竟量了哪几种
写法、哪两种没量。门禁逻辑一行没动,只动了它对外的说法,以及三条防止这句话退回去的自测。
为什么改. #13556 已裁决「ADR 行号锚」这一类无过渡期删除,依据是 4/4 抽样全烂。但门禁
的词汇表比那一类窄,于是两种写法活了下来:一种把行号藏在 markdown 链接的 fragment 里,
一种把行号与路径拆在同一表格行的不同单元格里。门禁读不到它们,却仍然印「0 … survive」。
读数是真的,那句话不是——这就是本卡判据 (b)。一句印在绿灯里的假零,下一个人会据它认定
这一类已经清完。
风险与代价(含回滚). 风险很低。① 不发布任何东西:根包是私有包,70 个公开包里没有一个
的
files[]能伸到docs/adr或根scripts/,已用字节级 grep 配正控实测,故声明skip-changeset。② 本卡故意没有去扩宽门禁词汇表,因为实测代价摆在这里:打开那个开关会在 6 份 ADR 上红 17 条,其中 2 条是 ADR-0047 的开发服务器端口号——那是完全正确的散文,
作者无法修,唯一出路是维护者专属的豁免标记;另有 4 份 ADR 在本卡申报的文件面之外。换一条
路更糟:
unspannedAnchors会红 8 条,其中 6 条是把正确的 ADR 互链误报成「文件不存在」。⇒ 扩词汇表是一个带价签的决定,不该由一句结语替您做。 本卡把账单从 17 降到 8。
③ 回滚成本近乎零:四个 commit 各自独立,
git revert任意一个都不影响其余,删 ADR 指针那三个纯属文本删除。④ 唯一需要您过目的判断:ADR-0096 有两句删掉数字后会没有指代对象,
本卡让它们改用该 ADR 自己那张表里已有的符号锚(
#getReadFilter),没有新造事实;这两处因此从「不可检查的数字」变成了「门禁会检查的锚点」。
席位意见.
你要做的. ① 这是受管面(
docs/adr/**),CI 绿也不由 AI 座位合并——需要您亲手确认与合并。② 请重点看 ADR-0096 那两句的指代替换读起来对不对(是否仍然说的是同一个站点);其余
七处是纯删除,不改变任何论断。③ 如果您认为剩下那三份 ADR(0021 / 0034 / 0077)的六个指针
应当一并清掉,或者愿意为扩宽门禁词汇表付那 8 条红灯的账,请说一声——两件都已量好,另立卡
即可动手。
Generated by Claude Code