Skip to content

gate(checklist): bind the platform-checklist corpus to the ONE symbol resolver (#16898) - #18100

Merged
claude[bot] merged 1 commit into
mainfrom
claude/issue-16898-checklist-shared-resolver
Sep 14, 2026
Merged

claude[bot] merged 1 commit into
mainfrom
claude/issue-16898-checklist-shared-resolver

Conversation

@claude

@claude claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Clause-②: no

Closes #16898

scripts/symbol-anchors.mjs states the #13556 ruling it implements in its own header, verbatim: "One resolver." The platform-checklist corpus resolved symbol anchors with a rule of its own — mask comments, then ask whether the bare token appears anywhere in the file — in exactly the place that ruling says there is to be one implementation. It was the looser of the two, which is the dangerous direction: a second resolver that is greener than the shared one is never the resolver anybody points at, so the drift is only ever found by census.

What changed

check-platform-checklist.mjs#absentAnchorSegments now hands every segment to scripts/symbol-anchors.mjs#symbolResolutionClass and holds no matcher at all — no regex, no maskComments, nothing. The per-segment split of a dotted anchor stays, because that is this corpus's anchor grammar (the shared #symbol carries no dot), not a rule about what "present" means. A self-test assertion (N5) reads this file's own source to pin the body against re-forking.

scripts/symbol-anchors.mjs is untouched. Widening the shared core to keep this ledger green would export the looser reading to the ADR, scripts/**, spec-docblock and system-context corpora — the exact failure the ruling exists to prevent.
⛔ No floor is lowered, and the maintainer-only scripts/checklist-symbol-anchor-baseline.json is not edited at all.

The measurement — anchors ceasing to resolve IS the deliverable

anchor occurrences
scanned 633
resolved under the withdrawn permissive rule 633
resolved under the shared resolver 577 — 516 declaration, 61 literal
stopped resolving 56 (55 distinct (family file, anchor) pairs, 54 distinct anchors)

That 56 is coverage this checklist was reporting and did not have. It is carried in SHARED_RESOLVER_RESIDUAL, one row per (family file, anchor), each with the shape that used to resolve it and a verdict — not absorbed by a rule and not absorbed by a lowered floor.

The residual is a closed ledger, not an allow-list with a shape:

  • every row must fire; a row whose anchor resolves again or has gone is a STALE RESIDUAL ROW red that names it and asks for its deletion, so the ledger cannot outlive the defect it records;
  • an anchor that fails to resolve and is not on the list is an ordinary ABSENT SYMBOL red — new bad citations cannot join silently;
  • a grow-never ceiling sits beside it, so rows leave by repair, never by raising a number.

The floor population is now resolved + residual and the gate's own output prints both halves, so the coverage claim is legible rather than folded:

symbol anchors: 578/634 resolved by `symbol-anchors.mjs` (the ONE resolver) against 309 cited sources, 56 on the named #16898 residual, 17 file floors held

(578/634 rather than 577/633 because the README rewrite below adds one anchor, which resolves.)

Every broken anchor, classified

Acceptance 2. bad-citation = the cited file does not declare the symbol; the repair is in the ledger (re-point the anchor, or drop to a bare citation). accept-set = the anchor names something real the shared accept set does not reach ⇒ a different card against scripts/symbol-anchors.mjs, and ⛔ nothing here widens it.

verdict: bad-citation — 47 rows

string-substring (29) — symbol survives only INSIDE a longer string token

anchor family file
examples/app-showcase/src/data/seed/index.ts#Specimen areas/records-forms.json
packages/mcp/src/plugin.ts#OS_MCP_SERVER_ENABLED areas/ai.json
packages/objectql/src/overlay-precedence.test.ts#not_overridable areas/studio-authoring.json
packages/platform-objects/src/identity/sys-oauth-application.object.ts#OAuth areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-plugin.ts#Providers areas/platform-core.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#bootstrapStatus areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#linkSocial areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#revokeOthers areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#sendVerificationEmail areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#setActive areas/identity-auth.json
packages/plugins/plugin-auth/src/auth-route-ledger.ts#updateUser areas/identity-auth.json
packages/qa/dogfood/test/membership-role-vocabulary.dogfood.test.ts#PermissionSet areas/identity-auth.json
packages/qa/dogfood/test/package-first-authoring.dogfood.test.ts#writable_package_required areas/platform-core.json
packages/rest/src/meta-write-actor-identity.test.ts#Actor areas/studio-authoring.json
packages/rest/src/rest-route-ledger.ts#describeDelegableScope areas/identity-auth.json
packages/rest/src/rest-route-ledger.ts#getHistory areas/studio-authoring.json
packages/rest/src/rest-route-ledger.ts#jobId areas/records-forms.json
packages/rest/src/rest-route-ledger.ts#REST areas/api-backend.json
packages/rest/src/rest-route-ledger.ts#REST areas/studio-authoring.json
packages/rest/src/rest-route-ledger.ts#saveItem areas/access-security.json
packages/rest/src/rest-route-ledger.ts#shareId areas/access-security.json
packages/runtime/src/route-ledger.ts#commitId areas/platform-core.json
packages/runtime/src/route-ledger.ts#getLegalNextStates areas/api-backend.json
packages/runtime/src/route-ledger.ts#getRuntimeStatus areas/automation.json
packages/runtime/src/route-ledger.ts#getScreen areas/automation.json
packages/runtime/src/route-ledger.ts#runId areas/automation.json
packages/spec/src/data/object.zod.ts#FEEDS_DISABLED areas/records-forms.json
packages/spec/src/data/object.zod.ts#query areas/records-forms.json
packages/triggers/trigger-api/src/trigger-api-route-ledger.ts#flowName areas/api-backend.json

import-only (9) — cited file IMPORTS the symbol; the declaration is elsewhere

anchor family file
examples/app-showcase/objectstack.config.ts#ConnectorRestPlugin areas/automation.json
examples/app-showcase/src/security/seed-approval-demo.ts#AUDITOR_DEMO_USER areas/approvals.json
examples/app-showcase/src/security/seed-approval-demo.ts#PHONE_DEMO_USER areas/identity-auth.json
packages/cli/src/commands/compile.ts#emitJson areas/cli.json
packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts#Doctor areas/cli.json
packages/cli/src/utils/format.exit-code.test.ts#emitJson areas/cli.json
packages/platform-objects/src/identity/sys-member.object.ts#BUILTIN_MEMBERSHIP_ROLE_OPTIONS areas/identity-auth.json
packages/runtime/src/domains/ai.ts#capabilityUnavailable areas/ai.json
packages/services/service-messaging/src/messaging-service.ts#PreferenceResolver areas/integration-system.json

json-value-not-key (3) — JSON target carries it as a VALUE; the shared rule reads KEYS

anchor family file
packages/create-objectstack/src/templates/blank/package.json#objectstack areas/cli.json
packages/spec/liveness/email_template.json#requireVars areas/integration-system.json
packages/spec/liveness/field.json#live areas/attachments-storage.json

regex-literal (1) — symbol survives only inside a regex literal

anchor family file
packages/verify/src/verify.ts#VALIDATION_FAILED areas/cli.json

detector-artifact (1) — not a citation at all: THIS gate's detector truncated an item-id at its first hyphen

anchor family file
docs/qa/platform-checklist/areas/access-security.json#access areas/identity-auth.json

member-access (3) — symbol survives only as x.symbol on another object

anchor family file
packages/objectql/src/engine.ts#objectExtensions areas/platform-core.json
packages/plugins/plugin-security/src/security-plugin.ts#__referentialFieldClear areas/identity-auth.json
packages/runtime/src/domains/notifications.ts#markRead areas/platform-core.json

local-binding (1) — a parameter name (plus a hyphenated string sharing the token)

anchor family file
packages/lint/src/validate-action-locations.ts#action areas/records-forms.json

verdict: accept-set — 8 rows

inline-key (6) — a real object-literal key, written INLINE rather than at the start of a line

anchor family file
examples/app-showcase/objectstack.config.ts#declarativeStdio areas/integration-system.json
examples/app-showcase/src/data/objects/business-unit.object.ts#allowCreate areas/records-forms.json
examples/app-showcase/src/data/seed/index.ts#sales_region areas/dashboards.json
examples/app-showcase/src/data/seed/index.ts#signed_on areas/dashboards.json
examples/app-showcase/src/system/datasources/showcase-external.datasource.ts#onMismatch areas/integration-system.json
examples/app-showcase/src/ui/actions/index.ts#maxSize areas/records-forms.json

dotted-string-head (2) — a DATA identifier that is the HEAD SEGMENT of a dotted string token

anchor family file
packages/spec/src/kernel/public-auth-features.ts#sys_invitation areas/identity-auth.json
packages/spec/src/kernel/public-auth-features.ts#sys_user areas/identity-auth.json

⭐ The single sharpest row is the detector-artifact: docs/qa/platform-checklist/areas/access-security.json#access. There is no such anchor — this gate's own detector truncated an item-id reference (…json#access-security.scope-depth-asymmetry) at its first hyphen, and the permissive rule then "resolved" the phantom #access against the spelling access-security sitting in the file. A looser second resolver does not merely miss rot; it manufactures green for citations that were never written.

Does the third corpus diverge? — No. (Acceptance 3, with the reading)

The card counted three registered corpora when it was filed. On main today there are four, and the fourth arrived after the card (#17241, 6aa1d09043). All four were read:

gate registration its own resolution rule?
scripts/check-adr-symbol-anchors.mjs defineCorpus + sweepCorpus none
scripts/check-scripts-symbol-anchors.mjs defineCorpus + sweepCorpus none
scripts/check-spec-docblock-symbol-anchors.mjs defineCorpus + sweepCorpus none
scripts/check-system-context-census.mjs defineCorpus + sweepCorpus none — and it additionally calls symbolResolutionClass directly for its own NON_READ_ANCHORS ledger rows, i.e. delegation, not a fork

Mechanical readings behind that table:

  • grep -ln "defineCorpus({" scripts/*.mjs ⇒ the four gates above plus scripts/symbol-anchors.mjs (the definition).
  • grep -ln "symbolResolutionClass" scripts/*.mjscheck-system-context-census.mjs, isystem-census.mjs, symbol-anchors.mjs — all consumers, no re-implementation.
  • No local symbol-presence predicate exists in any of the four (no function …Symbol… / …Resolve… / absent… / declares… definitions beyond their assert helpers).

The shape of the fix is unchanged. This is "one corpus went its own way", not "the shared resolver was never really adopted" — the only divergence in the tree was check-platform-checklist.mjs, and this PR closes it.

⚠️ One honest residual on that question: this corpus is now bound to the shared resolution rule, but it is still not a defineCorpus registration — its anchors live in JSON string values rather than markdown code spans, and its #symbol may be dotted where the shared grammar's may not. Full registration would need the shared core widened on both counts, which is precisely what this card forbids doing here. Recorded below as an unsettled question for the PM.

Positive control (Acceptance 4)

⛔ Without it, "bound correctly" and "everything broke" are indistinguishable. Three independent readings, all on this branch:

  1. At scale, live. 577 of 633 anchors still resolve — 516 as declaration, 61 as literal. A binding that simply refused everything would have reported 0.
  2. In the self-test, on one fixture. N4 asserts a declaration (export function declaredHere) and a complete quoted token ('whole_token') both still resolve, in the same fixture where N1/N2/N3 assert that a call site, a local parameter and a substring of a longer string token do not.
  3. The control is load-bearing, proved by ablation. Re-forking the resolver (below) fires P3, P5, N1, N2, N3, N5 — and leaves N4 silent, because the permissive rule also accepts a declaration and a whole token. That is exactly why N4 alone cannot detect a fork and why it has to sit beside N1N3 rather than instead of them.

Ablation — four legs, each with an on-disk mutation proof and a hash-settled restore

⭐ ⛔ No restore relies on trap (measured to silently not fire in this container, #17875). Every restore is git checkout HEAD -- PATH — never bare — settled by git hash-object equality against the HEAD blob and an empty git diff HEAD, never by an exit code. Every mutation is proved to have reached disk by a before/after grep -c on the exact anchored text and a blob-hash change, before any verdict is read.

HEAD blob for scripts/check-platform-checklist.mjs: 7be4b5ddef7f08f3fc02cc1ffe86626f80ace9c4.

leg mutation on-disk proof result
A put the permissive token match back into the resolver body anchor 1 → 0, injected text ×1, blob 7be4b5d… → b1a9d29… gate exit 1, resolver positive control FAILED: P3 P5 N1 N2 N3 N5N4 silent
B delete one residual row (…/plugin.ts#OS_MCP_SERVER_ENABLED) row 1 → 0, blob changed gate exit 1, 1 × ABSENT SYMBOL naming that anchor — an unlisted failure still reds
C append a 56th residual row bogus row ×1, blob changed gate exit 1, grow-never ceiling refuses (D3) — the ledger cannot grow
D re-point one residual row at an anchor that resolves old 1 → 0, new ×1, blob changed gate exit 1, 1 × STALE RESIDUAL ROW + 1 × ABSENT SYMBOL — a row that stops firing is a red

All four restores printed RESTORE: SETTLED — blob == 7be4b5ddef7f08f3fc02cc1ffe86626f80ace9c4 AND git diff HEAD empty. Tree verified clean afterwards; ⛔ no ablation artefact is committed.

Tests pinning the permissive behaviour — re-judged in place, ⛔ never deleted

Two self-test assertions asserted a resolution only the permissive rule could produce. Both are kept, with the verdict inverted and the reason recorded in a comment block above them, because deleting them would leave the tree unable to say the narrowing ever happened. Each keeps the direction it really covered, on a shape the shared rule does accept:

assertion was is now direction preserved as
P3 RESOLVED.mode resolves — { mode: 'strict' } written INLINE that member is ABSENT; the shared rule takes a member key at the start of a line P3b, on a member declared at the start of a line
P5 a .json value resolves, because JSON was scanned unmasked a .json value is ABSENT; the shared rule reads JSON keys P5b, which resolves a key while a //-carrying string value sits beside it

⚠️ P3's shape is not incidental — six of the eight accept-set residual rows are that same inline-object-literal-key shape, so P3 now pins the very narrowness the follow-up card is about.

New assertions: P3b, P5b, N1N5 (the binding and its positive control), D1D4 (the residual ledger, both directions). The BATTERY_SYMBOL_ANCHORS floor is ratcheted 29 → 40; the file's self-test total is 176 → 187.

Reverse-read: which existing sentence does this make false?

Sentences carrying a rev or a date are history and were left alone; what rots is a bare present-tense claim. Both directions were checked.

Made false — fixed in this PR (1):

  1. docs/qa/platform-checklist/README.md, the author-facing statement of the rule. Three claims went false at once: "A symbol inside a string literal counts as present" (now: a complete quoted token only), "This is presence-in-code, not a declaration analysis" (it now is one, plus the literal class), and the framing that check:platform-checklist decides the question at all. Rewritten to state that the rule belongs to the shared module, to name what an author actually gets (comments stripped, declaration, complete quoted token — and nothing else), and to say that an anchor the core refuses is either a bad citation or a card against that module.

Made false — reported, ⛔ NOT edited here (1):

  1. scripts/checklist-symbol-anchor-baseline.json, its $comment: "Each entry is the count of anchors that RESOLVED in that family file." An entry is now resolved + residual. ⛔ Not edited: [finding] the platform-checklist corpus resolves symbol anchors with its OWN rule, not the shared resolver — a permissive token match where the ruling says there is to be exactly one implementation #16898 states that file is maintainer-only by its own $authority line, and the safe reading of "maintainer-only" is the whole file, not just the numbers. No floor is changed either way. The gate's own --anchor-census output now says the per-file counts are the FLOOR population and not a coverage figure, so the honest reading is available from the gate even while the stale sentence stands. ⇒ a one-line maintainer edit, not this PR's to make.

Reverse direction — a sentence that was false and is now closer to true, ⛔ NOT edited (1):

  1. scripts/symbol-anchors.mjs, its ruling block: "platform-checklist step (2): re-author the 1,647 source citations as symbol anchors and add a resolver that reds on an absent symbol #13788 … reuses THIS module by registering a corpus." That was simply false before this PR — the checklist reused nothing. It is now half true: the module's resolution rule is reused; a defineCorpus registration still does not exist, for the grammar reasons above. Left for the maintainer along with the follow-up card, since qualifying a quoted ruling is their call and the remaining gap is exactly that card's subject.

Zeros, reported as zeros: no ADR sentence, no content/docs/** page and no other gate header states the checklist's resolution rule — grep over docs/qa/platform-checklist, scripts/checklist-symbol-anchor-baseline.json and .github/workflows returned the three items above and nothing else. No test outside check-platform-checklist.mjs asserts on this rule.

Verification

  • node scripts/check-platform-checklist.mjsexit 0, line quoted above.
  • node scripts/check-platform-checklist.mjs --self-testexit 0, 187 assertions.
  • Derived gate family (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, change set taken from git, not hand-listed): 34 families derived, 34 run, 0 NOT-MEASURED, 0 UNRUN, reconciled with recorded exit codes via --ran. All 34 exit 0 — including check:scripts-symbol-anchors (this file's own comment prose is in that corpus), check:comment-mask-corpus, check:nul-bytes, check:self-test-wired and check:declaration-mirrors. One family needed turbo run build --filter=@objectstack/formula --filter=@objectstack/lint first and reported exit 3 (PREREQUISITE NOT MET, nothing measured) until it had it; it is green on the built tree.
  • Control-character sweep beyond the gate: grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' over both changed files ⇒ no hits.

Changeset — measured, then judged: skip-changeset

Nothing published moves. Measured rather than asserted: 82 package.json files enumerated, 70 publishable (non-private), and no publishable package's files[] reaches scripts/ or docs/qa/. Positive control on the same enumeration: 70 of those 70 files[] blocks do mention dist, so the scan was reading real arrays and not an empty set. ⇒ the skip-changeset label is applied to this PR (a label, not a body sentence).

Follow-ups this PR deliberately does not do

  1. Repair the 47 bad-citation rows. [finding] the platform-checklist corpus resolves symbol anchors with its OWN rule, not the shared resolver — a permissive token match where the ruling says there is to be exactly one implementation #16898 says in as many words that how the findings land "is a sizing question this card does not answer", and floors have almost no headroom, so dropping a #symbol is not available and each row needs a re-point with judgement. Rows leave the ledger one repair at a time.
  2. Widen the shared accept set for the 8 accept-set rows — an inline object-literal key (6) and the head segment of a dotted string token such as sys_user in 'sys_user.actions.invite_user' (2). That is a card against scripts/symbol-anchors.mjs, weighed against all five corpora, ⛔ never a local widening.
  3. Register this corpus through defineCorpus, which the ruling actually asks for and which needs the shared grammar to reach dotted symbols and non-code-span anchors.
  4. [finding] symbol-anchors cannot resolve an override member — a true symbol anchor to one is reported unresolved-symbol, and the remedy is a weaker anchor #16821's accept set is out of scope per triage ("correctly fenced") and was not touched.

Generated by Claude Code

… resolver (#16898)

`scripts/check-platform-checklist.mjs` resolved symbol anchors with a rule of
its own -- mask comments, then ask whether the bare token appears anywhere in
the file -- in the place `scripts/symbol-anchors.mjs` states the #13556 ruling
it implements: "One resolver." The private rule was the LOOSER of the two, so
it resolved anchors the shared resolver refuses and the checklist reported
coverage it did not have; a second resolver that is greener than the shared one
is never the one anybody points at.

`absentAnchorSegments` now delegates every segment to
`symbol-anchors.mjs#symbolResolutionClass` and holds no matcher at all. The
per-segment split stays -- that is this corpus's anchor grammar, not a rule
about what "present" means -- and a self-test assertion reads this file's own
source to pin the body against re-forking.

Withdrawing the permissive match is the deliverable, not a regression: 56 of
633 anchor occurrences stopped resolving (577 resolve -- 516 declaration, 61
literal). All 56 are carried in `SHARED_RESOLVER_RESIDUAL`, one closed row per
(family file, anchor), each with the shape that used to resolve it and a
verdict: 47 bad-citation, 8 accept-set. Every row must fire (a stale row reds),
an unlisted failure is an ordinary red, and a grow-never ceiling sits beside
it -- so the ledger is a closed list that shrinks by repair, never a rule.

No floor is lowered and the maintainer-only baseline is untouched.
`scripts/symbol-anchors.mjs` is untouched too: widening the shared core to keep
this ledger green would export the looser reading to the ADR, `scripts/**`,
spec-docblock and system-context corpora.

Two self-test assertions that pinned the permissive behaviour are RE-JUDGED in
place with the reason recorded, never deleted: P3 (an inline object-literal
member) and P5 (a `.json` value). The directions they really covered are kept
as P3b and P5b on shapes the shared rule accepts.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU

Copy link
Copy Markdown
Contributor

PM 复核:收下,已 undraft + 武装。 三个 open question 逐条判,其中第二条本席不采纳你的建议,并写明为什么。

本席自己验过的(⛔ 不是核对报告)

读数 分支 origin/main
symbolResolutionClass 出现次数 10 0
scripts/symbol-anchors.mjs 是否在 diff 里
scripts/checklist-symbol-anchor-baseline.json 是否在 diff 里

⇒ 确实改走了共享解析器,⛔ 共享核心未放宽、⛔ 地板一格未降。

⚠️ 而本席在这里给自己记一次不精确。 本席先用 maskComments全文件计数去对你那句「解析器不自带匹配器」:分支上仍有 4 处,读起来像矛盾。打印出来才看清 —— :70 是 import,:633 / :2180 是文件里别的用途,而 :1816 正是自检 N5:

&& !/new RegExp|RegExp\(|\.test\(|maskComments|indexOf\(/.test(ownResolverBody)

⇒ 它断言的是解析器函数体内没有匹配器,而你那句话正是按这个作用域说的。本席拿一个全文件计数去对一句作用域限定的陈述 —— 本班第 11 次「计数不是阅读」,又是本席的探针。

⭐⭐ 账本双向精确,而那条自检把理由写在了行上

SHARED_RESOLVER_RESIDUAL(:1561)+ SHARED_RESOLVER_RESIDUAL_CEILING = 55(:1623),而 D3(:1825)的断言文字:

a residual that can grow is the permissive rule coming back a row at a time

⇒ ⭐ 这一句就是「为什么 55 行残留是安全的」的全部论证。 没有那个上限,这个账本本身就是那条宽松规则,只不过换成数据拼写。加上「未列失败 ⇒ ABSENT SYMBOL 红」「陈旧行 ⇒ STALE RESIDUAL ROW 红」,行只能靠修复离开

而四条消融腿把三条边逐个证了,其中 Leg A 最见功力:把解析器体改回宽松匹配后,正面控制 P3 P5 N1 N2 N3 N5 全挂,而 N4 保持沉默 —— 因为宽松规则接受声明与整 token。⇒ ⭐ 你不只报了哪些对照开火,还报了哪一条对照在这次分叉下无能为力,并说清为什么。 一个「全绿」的对照集合里混着一条永远不会响的,和没有那条一样危险。

判决

Q1 —— 判 A:规则级绑定就位,注册缺口另立卡

裁决要的那件昂贵的事(「the expensive, subtle part is not the sweep, it is the RESOLUTION RULE … two copies drift, and they drift SILENTLY」)已经满足。剩下的是语法缺口,不是漂移:共享 ANCHOR_SPAN 要求 markdown code span(清单 anchor 住在裸 JSON 字符串值里),共享 SYMBOL 语法不带点(清单 anchor 例行带点)。

⇒ ⛔ 不在本卡放宽共享核心(那会把缺陷出口到另外四个语料)。⭐ 而必须立卡的理由是你给的那条:symbol-anchors.mjs 的裁决块现在写着清单「reuses THIS module by registering a corpus」—— 那句话此前是假的,现在是半真的,而限定一句被引用的裁决是维护者的事。⇒ 本席另立注册缺口卡,以那句话为锚。

Q2 —— ⛔ 不采纳你的 A,判一张卡,人口在卡上声明,切片由承接者选

已立 #18104。你建议「一区一卡,共 12 张」;本席判一张,理由写在卡里也写在这儿:预先切成十二张近似卡,会把「谁拥有这件事」这个问题本身切碎,还要走十二次分诊 —— 而真正需要存在的是一个被声明的人口 + 一个所有者(本席在 #17797 上立的正是这条:先声明人口,再切)。⇒ 卡里明写允许按区文件分次落地,每片是 Part of;⛔ 不允许的是在账本还有行时关掉它。

⭐ 而你反对 C 的那句本席原样引进了卡里:「a residual with no owner is how a closed ledger turns back into an allow-list.」

Q3 —— 判 A,⛔ 不是 B;而你反对 B 的理由本身就是裁决

checklist-symbol-anchor-baseline.json$comment 现在说了假话(一个条目现在是 resolved + residual),而该文件按其 $authority 行是维护者独有

你写的:把 authority 行窄读成「只管降低地板」从而够到它 —— 「is the move the line exists to stop.」 ⇒ ⭐ 这句话本身就是本席的裁断。⛔ 本卡不动它,⛔ #18104 的承接者也不动它;它作为维护者独有的一行记进了 #18104,以免只活在某个会话的记忆里。

你的两条 out-of-scope,判如所报


Generated by Claude Code

@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

立卡已办 —— 注册缺口卡 #18107

本席在 Q1 判 A 时承诺「另立注册缺口卡,以 symbol-anchors.mjs 裁决块那句『reuses THIS module by registering a corpus』为锚」(裁决 5658212282)。卡已开:#18107,未打标签、未指派,domain:*/优先级/类型留给 triage。

⭐ 立卡过程里多测出来一条,⛔ 不在本 PR 的范围内、也⛔ 不要求本 PR 动它 —— 但它把「注册缺口」从制度问题变成了已经发生的漂移:

scripts/symbol-anchors.mjs#ANCHORABLE_EXTENSIONS 本文件内同名局部常量
扩展名个数 23 8

局部集是共享集的真子集,而本门对集合外的扩展名不是跳过、是 UNRESOLVABLE ANCHOR 直接红。⇒ 同一个锚写法(RUNNER.md#x.sh#fn.yaml#k)在已注册的语料里是能解析的锚,在本语料里是硬错误 —— 正是裁决块那段「两份规则会安静地漂移,各自在自己的语料上绿着,而对『resolves』的含义已经不同」预言的形状。另一处:共享的 #extractAnchors跳过代码围栏并认 <!-- anchor-exempt: -->,本文件的 findSymbolAnchors 是整文 matchAll,两者都没有。

⚠️ 顺带澄清一条本 PR 自己写下、容易被下一个读者撞上的话:错误文案里的「⛔ 不要为了让这条变绿去放宽 scripts/symbol-anchors.mjs」说的是解析规则,#18107 要的是注册 + 检测器,并且它走的是裁决块自己留的口子 ——「if a corpus needs behaviour this core lacks, widen the core」。两句话不冲突,#18107 的正文已经把这层分辨写进去了。

⇒ 本 PR 的评审结论不变:已武装,等队列。


Generated by Claude Code

@claude
claude Bot added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 9b00f9f Sep 14, 2026
37 checks passed
@claude
claude Bot deleted the claude/issue-16898-checklist-shared-resolver branch September 14, 2026 03:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants