Skip to content

docs(types): re-anchor the dead tracker citations in packages/types/src to the commits that decided them - #20673

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20594-types-dead-citations
Sep 29, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20594-types-dead-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20594
Clause-②: no

What changed

This is stage 4 of the domain:cli lane of the dead-citation sweep: packages/types/src/**. Every comment or docblock site in scope that cited a tracker number answering 404 now cites, in ruling C+D's form C (comment 5749154545 on #19123), the commit in this repository's history that decided what the line describes, and says in its own words what that commit decided. PR #20533 is the method; PR #20624 (runtime), PR #20632 (rest) and PR #20656 (cli) are the landed stages this follows. The card stays open for the form-D stage and the rest of the lane, so this PR says Part of.

That is 83 comment sites on 83 lines in 17 files, covering 12 numbers: the census's 52 (all of them) and 31 more in test comments, which the census defers. Each rewritten line cites one of 12 distinct commits. No ADR or ruling-record file records any of these twelve decisions, so every anchor is a commit.

Only comments changed. Every touched file keeps its line count (94 lines out, 94 in, over 17 files), so no line citation into these files moves. Eleven of the 94 lines held no dead site; each is the other half of a sentence that had to change: thrown-http-error.ts:316-319, node.ts:1103, :1429, :1447, :1452, :1476, and node.test.ts:449, :2420 (see "Wordings to check").

No citation number is added. Over the 94 line pairs, every tracker number on an added line was already on the line it replaces (per-pair check: 0 added), and no PR number stands on an added line. No code token moves (see the guard below). No site was left: no dead comment site in scope lacked a deciding commit, and no open PR touches packages/types/src.

One file outside packages/types/src: a patch changeset for @objectstack/types, in PR #20632's form and level.

Census: packages/types, before and after

Instrument. The gate's own node scripts/check-issue-citations.mjs --census --json, read-only and unchanged, run with the fleet token. Its surface is comment prose in packages/**/src/**/*.ts with string literals blanked, and it defers *.test.ts. The count is its allocated-but-absent findings under packages/types/. Both runs enumerated the whole board (185 pages), so neither read a truncated board.

reading tree board whole-repo allocated-but-absent types sites lines files numbers
before base 6bff748bbd, run 2026-09-29T15:31:59Z to 15:41:36Z enumerated, 185 pages, frontier #20663, 18,490 numbers 1,510 52 52 7 11
after head 686a4c60cb, run 2026-09-29T16:04:17Z to 16:12:39Z enumerated, 185 pages, frontier #20671, 18,498 numbers 1,458 0 0 0 0

The before count equals the card's 52 at f11b5f20a2: no drift. The whole-repo drop is 52, exactly this diff's 52 sites, and the whole-repo resolving count rises by one (32,882 to 32,883): the live #12751 that index.ts:4 now spells so the grammar reads it. Both runs read this worktree, the base and then the base plus this one commit, so no other change entered either count.

Supplementary instrument, the whole scope. The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported extractCitations (whole-file and comment-prose projections) and classifyCitation over every .ts file under packages/types/src (42 files), against a board from the gate's own probeBoard. The lit controls #20594, #19123 and #20656 answered 200 and are on both boards; the dead controls #11671, #10514 and #14828 answered 404 and are on neither.

reading tree board citations dead src comment test comment src string test string
before, 15:34Z 6bff748bbd probed, frontier #20661 622 101 52 31 1 17
after, 16:04Z 686a4c60cb probed, frontier #20668 540 18 0 0 1 17

Its src-comment column equals the census's 52, site for site (the two site lists are identical), which is the control on the second instrument. The drop of 82 citations is the 83 dead sites removed plus one live number the grammar now reads: index.ts:4 spelled [#11343/#12751], whose second half the grammar skips after a slash, and now reads [commit c0714eb5d / #12751] like its module doc, so the live #12751 is judged (resolving src comments 273 to 274). Resolving pull requests (20), cross-repo citations (14) and the other resolving counts are unchanged. A separate scan for slash-joined pairs in packages/types/src found six (#11343/#12751, #3878/#3899, #7525/#8016, #4728/#4825, #8621/#8622, #5352/#5367); every second half answers 200, so no dead number hid behind a slash here.

Per-number table

Sites and files are the dead comment sites in scope at the base, test sites counted in brackets. strings kept counts string-literal sites, which are tokens and stay as they were. Every anchor was read in its message or its diff, not only its subject: it is the commit that made the change the line describes.

number comment sites / files rewritten strings kept anchor
#8824 1/1 (1 test) 1 0 8ac232306
#9934 5/4 (2 test) 5 2 79c46da90
#10943 10/2 (4 test) 10 2 46d34ab7c
#10944 1/1 1 0 e598b1cbc
#11343 3/3 (1 test) 3 1 c0714eb5d
#12281 1/1 1 0 0783d7b80
#13197 5/2 (2 test) 5 2 56c093c4d
#13279 8/5 (2 test) 8 0 6a180e42d
#13324 15/3 (7 test) 15 5 4cda78c9b
#15044 8/2 (3 test) 8 1 088f761e5
#15045 21/2 (8 test) 21 1 288fe9c34
#16657 5/2 (1 test) 5 4 5a95b0e93
total 83 83 18 12 distinct commits

Every cited sha matches exactly one object (git rev-parse --disambiguate, count 1 for each of the 12), is a commit, has one parent, and is an ancestor of the base (merge-base --is-ancestor, exit 0 for all 12). The checkout is not shallow (--is-shallow-repository false); the control leg f5a9bc2f3 (2026-08-10, older than the oldest anchor, 8ac232306 of 2026-08-15) exits 0 and the negative control (this branch's own 686a4c60cb, not on main) exits 1.

Anchors reused from earlier stages, so each number carries one anchor across the tree: 79c46da90 for #9934 (stages 1 and 2, the spec lane), 46d34ab7c for #10943, e598b1cbc for #10944 and 288fe9c34 for #15045 (stage 3), 0783d7b80 for #12281 (stage 1), 56c093c4d for #13197 (stage 2, the spec lane), 6a180e42d for #13279 (stages 1 and 2, plugin-sharing) and c0714eb5d for #11343 (plugin-auth).

New anchors, and how each was found:

Wordings to check

Mechanical guard: no code token moves

The check compares the TypeScript parser's leaf tokens (TypeScript 6.0.3, JSDoc nodes excluded, comments being trivia) of each touched file at base 6bff748bbd against the working tree at 686a4c60cb, over all 17 touched files, and lists EVERY differing token, not only the first. Controls mutate the head text in memory only, so nothing on disk moved for them.

  • Real run: 31,911 base tokens, token counts equal in every file, 0 differing tokens (exit 0).
  • Comment-insertion control (a new line comment in node.ts): 0 differing tokens (exit 0).
  • Code-insertion positive control (a declaration prepended to node.ts): the count differs and a difference appears at token 0 (exit 1).
  • String positive control (one character changed inside the kept undeclaredMessage literal at node.ts:383): exactly 1 differing token, a StringLiteral at token 672 (exit 1).

So H2 holds by the token guard. The emitted dist is not byte-identical, because the docblocks ship, which is why the changeset is patch. Line balance: every touched file is +N/−N and every line count is equal at base and head (17 files). A raw scan of the 18 changed files for control bytes finds none (its positive control, a scratch file holding a U+0001 byte, matches).

Changeset

This change ships bytes, so a patch changeset for @objectstack/types is included, in PR #20632's form and level: 「Comments only: no error code, refusal text, type, export or runtime behaviour changes.」

Measured on the built package: files[] is dist, README.md and CHANGELOG.md. After the build, the rewritten docblocks reach dist: 0783d7b80, 79c46da90, 5a95b0e93 and c0714eb5d are in dist/index.d.ts and index.d.mts, 4cda78c9b in all four index files, 6a180e42d in index.js and index.mjs, and 46d34ab7c and 288fe9c34 in dist/node.d.ts and node.d.mts. The positive control, the unchanged sentence 「sanitisation REGIME is the condition, not one of its two outcomes」 of the 0783d7b80 docblock, is in dist/index.d.ts beside it; a negative control phrase appears nowhere. Of the twelve dead numbers, only #10943 remains in dist, twice, and both are the kept operator-facing string at node.ts:383 (see Acceptance notes).

Gates (head 686a4c60cb)

This host has no flock, so os-verify-lock.sh ran in its declared unlocked mode. Its disclosure, verbatim, from each locked run at this head:

os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 2s · declare it in the PR body · pnpm --filter @objectstack/types exec vitest run --project repo --maxWorkers=2
os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 5s · declare it in the PR body · pnpm --filter @objectstack/types exec vitest run --project local --maxWorkers=2
os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 2s · declare it in the PR body · pnpm --filter @objectstack/types typecheck
os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 28s · declare it in the PR body · pnpm --filter '@objectstack/types...' build
os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 46s · declare it in the PR body · pnpm lint
os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 93s (1m33s) · declare it in the PR body · pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=4

origin/main did not move after the branch was cut: git merge origin/main answered 「Already up to date」 at 6bff748bbd, so the base is the merge base and nothing needed rebuilding. origin/main has since moved to 6c11ef9ecb (PR #20663: two pages under content/docs/automation, read 16:13Z). It touches nothing this diff or its gates read, so the branch was not merged again and every reading here stays at 686a4c60cb.

  • Build: the dependency closure (@objectstack/types...: spec then types) and then the whole workspace (71 tasks, 71 successful). check-dts-emitted finds 2 of 2 declared declaration files. The build left the tree clean.
  • Tests: --project local: 22 files, 685 tests pass. --project repo: 1 file (driver-error-classification.callers.test.ts, touched here), 7 tests pass. 22 + 1 is all 23 test files in the package, so every touched test file ran.
  • Typecheck: pnpm --filter @objectstack/types typecheck exits 0. tsc --listFiles counts 42 src files under tsconfig.json, all 23 test files among them, so every touched test file is type-checked.
  • Lint: the repo-wide pnpm lint (eslint . --no-inline-config) exits 0 at 686a4c60cb (2026-09-29T16:01:23Z to 16:02:09Z). Not narrowed.
  • Citation judging: node scripts/check-issue-citations.mjs --base origin/main exits 0: 5 citations judged across 7 files (4 resolve, 1 cross-repo). These are the live numbers that stay on rewritten non-test lines. It defers *.test.ts, so the per-pair count over the whole diff covers the rest: 0 numbers added.
  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at 686a4c60cb derived 61 families. All 61 ran and exit 0, and --ran over a record carrying each exit code reads 「61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero). Among them: check:doc-authoring, check:nul-bytes, check:issue-citations (self-test), check:published-files, check:dts-closure, check:dual-build-cjs-loads, check:type-check-coverage and check:type-check-debt.
  • Artifact rosters: all 36 non-self-test roster rows that run without a pull request exit 0 at 686a4c60cb, the four whose rosters share a directory with this diff among them (check-changeset-fixed, check:authz-resolver, check:error-code-casing, check:filter-alias-parity). The other three, check-closing-target-claim, check-partof-closing-keyword and check-single-claim-paths, need a pull request's context; they are run against this PR once it exists and reported on the card. The 18 checker-health-only rows were not run.

Hypotheses (measured first)

  • H0 holds. The filtered census answers 52 dead sites at 6bff748bbd (52 lines, 7 files, 11 numbers), equal to the card's count at f11b5f20a2: no drift.
  • H1 holds, with no exceptions. After the rewrite the filtered census answers 0 dead sites for packages/types/. No site is left for an open PR or an unfound anchor: the claim's read and this stage's read of the open PRs' file lists (15:40:08Z, 7 open PRs) found none touching packages/types/src (the Version Packages PR touches only packages/types/CHANGELOG.md and package.json). A second read before this PR was opened (16:13:18Z, 11 open PRs) found the same.
  • H2 holds, by the token guard above: 0 differing parser leaf tokens over the 17 touched files, with the comment control at 0 and the code and string controls each turning red.

Acceptance notes

Deviations

  • Eleven lines beyond the dead sites are the other half of a rewritten sentence (listed under What changed), and the six lines at thrown-http-error.ts:315-320 move from the future tense to the present, because the claim they carried stopped being true when 0783d7b80 landed (see Wordings to check).
  • The anchors were researched in this session, not delegated; every one was checked against its commit's message or diff.
  • Commit trailers are AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), and the pre-push trailer check passed on every push; the harness's attribution reminder asked for a model-named trailer and a different PR footer, which AGENTS.md overrides.

Generated by Claude Code

…rc to the commits that decided them

Every comment and docblock site under packages/types/src that cited a
tracker number answering 404 now cites the commit in this repository's
history that decided what the line describes, and says in its own words
what that commit decided. Comments only; every touched file keeps its
line count. A patch changeset ships because the docblocks reach dist.

Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/types, touching 5 documentable anchor(s). ⚠️ 4 changed file(s) yielded no anchor (packages/types/src/email-verified.ts, packages/types/src/index.ts, packages/types/src/response-envelope.ts, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

⛔ 1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17/17-4.mdx (via createHostImporter (symbol, a top-level function))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 4 changed file(s) yielded no anchor (packages/types/src/email-verified.ts, packages/types/src/index.ts, packages/types/src/response-envelope.ts, …) — pages documenting those are invisible to this run
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 3 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from ecd053b11c9c02415ea1f9771581d82cdbec6a5a — the merge of head 686a4c60cb76ea289772fe8e33d6a1be9208a9c0 into base 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ecd053b11c9c02415ea1f9771581d82cdbec6a5a && git checkout ecd053b11c9c02415ea1f9771581d82cdbec6a5a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607 686a4c60cb76ea289772fe8e33d6a1be9208a9c0 && git checkout -B drift-repro 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607 && git merge --no-ff 686a4c60cb76ea289772fe8e33d6a1be9208a9c0

node scripts/docs-audit/affected-docs.mjs --json 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 6c11ef9ecbf3e99f4d8f45f81073eafc5eae3607 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 686a4c60cb76ea289772fe8e33d6a1be9208a9c0
Local-runs: none

PR #20673 (draft, base main, one commit 686a4c60cb, parent 6bff748bbd), stage 4 of card #20594 (packages/types), judged against ruling C+D form C (5749154545 on #19123) as the card body and stages 1 to 3 (PR #20624, PR #20632, PR #20656) apply it. Inputs: the card body and all 15 comments (one page of 100; page 2 empty), the PR body, its file list (18 entries on page 1, page 2 empty), the net diff (Accept: application/vnd.github.diff, 829 lines, 18 diff --git headers), the check-runs on the head, and, because the brief asks for them, the 12 anchor commits through the commits and compare APIs and the head tree's 42 packages/types/src/*.ts blobs through the git trees and blobs APIs. Every read went through gh api. Nothing was built, run or re-run; two scratch scripts analysed the fetched diff text and the fetched blobs only.

① Derived judgments

Accept set and public surface: nothing moves. Every one of the 198 changed lines (104 added, 94 removed) outside the new changeset begins with a comment prefix (*, //, /**); a mechanical scan of the diff finds 0 non-comment changed lines. No code token, string literal, error message, identifier or test assertion moves. The emitted dist changes only in docblock bytes, which is why a changeset is owed (see ②). Judged right.

(1) Comment-only, and the two tense moves. node.ts (30 pairs) and thrown-http-error.ts (7 pairs) were read whole in the diff; every other hunk was read too (the diff is 18 files, all read). Both moved tenses are now true:

  • thrown-http-error.ts:315-320 now says commit 0783d7b80 "reads the 'declared' limb of this same function" and "landed separately, after its own measurement-first step". 0783d7b80's packages/runtime/src/dispatcher-plugin.ts patch imports serverFaultProvenance from @objectstack/types and gates on serverFaultProvenance(thrown) === 'declared'; its message says "the door now reads serverFaultProvenance". The old future tense ("the shape it will read") was false once that landed on 2026-08-30. Right.
  • node.ts:1447-1452 now calls the relative-specifier base "the policy question commit e598b1cbc settled for serve (it refuses a relative plugins: [...] entry rather than silently re-basing it)". e598b1cbc (2026-08-22T22:15:06Z) adds relativePluginSpecifierRefusal and the section "The relative branch is REFUSED, not resolved" to serve.ts; 46d34ab7c (22:55:01Z) wrote the old lines 40 minutes later. "Open policy question owned by A relative plugins: ['./local-plugin.js'] entry resolves against the CLI's own directory, so an app-relative plugin path can never work #10944" was already false when written. Right.

(2) Anchors. All 12 shas answer the commits API, each has exactly one parent, and compare/SHA...main answers ahead with behind_by 0 for all 12 (ahead_by 1661 to 5305). Sampled 20 rewritten sites in 13 files (8 of them test files), each checked against the commit's subject and its patch, not only its subject:

  • error-leak.test.ts:180 → 8ac232306: subject ends (#8824); patch replaces the MySQL reachability claim with a COVERAGE statement and pins it. Supported.
  • driver-error-classification.callers.test.ts:10, :20, :24-25 → 4cda78c9b: patch adds readObject to isMissingTableError, excludedByReadObject, and the [#13324] markers, in packages/metadata/src/utils/schema-sync-errors.ts (the file 6a180e42d later renamed into packages/types). Supported.
  • driver-error-classification.targeted-table.test.ts:7, :184 → 4cda78c9b: "the residual it left behind" and "the narrowing it made". Supported by the same patch.
  • driver-error-classification.ts:7, :134, driver-error-classification.test.ts:7, error-leak.test.ts:141, unique-violation.ts:122, index.ts:51 → 6a180e42d: the commits API lists both files as renamed from packages/metadata/src/utils/schema-sync-errors(.test).ts, and the message says the resolver had to ask isMissingTableError from core. Supported.
  • driver-error-classification.ts:608 (the card's control site, was pre-#13324) → "the behaviour before commit 4cda78c9b". Supported.
  • driver-error-classification.ts:657, :661, :670, driver-error-classification.operator-text.test.ts:4 → 5a95b0e93: patch adds operatorFacingErrorText, DECLARED_DATABASE_FAULT_CODE = 'DATABASE_ERROR' and RAW_STATEMENT_FAULT_SENTENCE; message says "Fourth prose round on Raw-exec consumers that surface error.message as an operator-facing detail now read the composed DATABASE_ERROR sentence — read cause there (follow-up to #16019) #16657". Supported.
  • email-verified.ts:4, email-verified.test.ts:4, index.ts:4 → c0714eb5d: this commit touches no file under packages/types (its files are plugin-security, plugin-auth, a changeset and a pinned ledger). Its bootstrap-platform-admin.ts patch is where the predicate was decided: it adds isEmailVerified with the docblock "fail-closed ALLOW-LIST over the representations a driver may hand back for the sys_user.email_verified boolean column (JS true, SQLite 1, and their stringified forms)", the sentence the types module now carries, and its message says "Fixes [security] 围墙提权只按未验证邮箱匹配 —— #11184 落地后仍存在一条更窄的同形路径:抢在 owner 之前用其邮箱注册即可被提权 #11343". The live feat(auth): walled deployment's declared owner is email-verified at operator-provisioned creation (extends #11343 to production walled boots) #12751 stays beside it as the move into this package. The anchor is the deciding commit, which is what form C asks for. Supported, with that note.
  • node.ts:46, :368, :1381, :1428 (the card's control site), :1443, node.test.ts:217, :222, :446, :594 → 46d34ab7c: patch adds HostImporterOptions.fallbackImport and renames the test case from "falls back to the importing package's own resolution when the host does not declare" to "the DEFAULT fallback is this package's own resolution", which is exactly what node.test.ts:217 now says the case "used to be called". Supported.
  • node.ts:635, :660, :891, :925, :1507, node.test.ts:1566, :2175, :2419-2420 → 088f761e5: patch adds declaredManifestName and packageRootOf(resolvedFile, manifestName) and the BOUNDARY: test; message says "Part of packageRootOf matches the declaration KEY, so an aliased dual-published package silently loads its require build on the succeeding (#13330) path #15044". Supported.
  • node.ts:296, :678, :718, :743, :753, :1032, :1102-1103, :1151, :1176, :1242, :1246, :1261, :1474, :1476, node.test.ts:1478, :1881, :1910, :1987, :2053, :2077, :2160, :2317 → 288fe9c34: patch adds unverifiable-location, NAMELESS_DECLARATION_PREFIXES, declarationNamesNoPackage and the heading "the location sub-case REFUSES correctly and EXPLAINED itself wrongly"; message says the second axis is "deliberately not built here" (so "left unbuilt" at node.ts:1476 is that commit's own words) and that accepting the directory "would trade a wrong REMEDY for a wrong LOAD" (the substance of the quote at node.test.ts:2160). Supported.
  • response-envelope.ts:164, response-envelope.test.ts:250, thrown-http-error.test.ts:3, thrown-http-error.ts:154, :258 → 79c46da90: subject names userMessage and (#9934); patch adds declaredUserMessage and ThrownHttpError.userMessage. Supported.
  • unique-violation.ts:126, :192, :200, unique-violation.test.ts:48, :77 → 56c093c4d: patch adds 'UNIQUE_VIOLATION' to the codes set and the docblock bullet; subject (#13197). The "added by" wording at :126 keeps the original sentence's ambiguity (the limb, not the ledger entry, is what this commit added; the ledger file is not in its file list), so nothing is newly claimed. Supported.
  • thrown-http-error.ts:315 → 0783d7b80 and node.ts:1447 → e598b1cbc: see (1). Supported.

No wrong or unsupported anchor found. Form C's first preference, an ADR or ruling record: a grep of docs/adr for the 12 numbers finds only #12281, at ADR-0112 line 152, which says the prose axis "is #12281, a separate card ... deliberately not applied here". That defers the decision; it does not record it. The commit anchors are right for all 12.

(3) Numbers. Over the 94 line pairs: 12 numbers appear on removed lines only (#8824 #9934 #10943 #10944 #11343 #12281 #13197 #13279 #13324 #15044 #15045 #16657, 83 occurrences, the dev's 83), all 12 answer 404 by REST probe; 9 numbers stand on both sides with equal counts (#4728 #4825 #6347 #8621 #8622 #12751 #13330 #17046, all 200, and objectui#5210, cross-repo, unchanged); 0 numbers appear on added lines only. No 200 number was removed or rewritten; none was added. The 12 anchor shas appear only on added lines (288fe9c34 x21, 4cda78c9b x14, 46d34ab7c x10, 6a180e42d x8, 088f761e5 x8, 79c46da90 x5, 5a95b0e93 x5, 56c093c4d x5, c0714eb5d x3, 8ac232306, e598b1cbc, 0783d7b80 x1 each); none on a removed line.

(4) Line counts. From the file list, every one of the 17 modified files has additions equal to deletions (4/4, 1/1, 3/3, 1/1, 16/16, 1/1, 1/1, 2/2, 2/2, 17/17, 30/30, 1/1, 1/1, 1/1, 7/7, 2/2, 4/4; 94/94), and the diff's hunk headers agree. The 18th file is the new 10-line changeset. Right.

(5) See ②.

(6) Part of, and nothing left behind. Line 1 of the body is Part of #20594, line 2 Clause-②: no; no closing keyword anywhere; the check-run Part-of PR must not also close its card is success. The head tree's 42 .ts blobs under packages/types/src were read: a crude comment census finds 8 of the 12 dead numbers still present at 18 sites, and every one is a string literal, none a comment: 16 describe/it titles in 7 test files, the REMEDY string at driver-error-classification.callers.test.ts:281, and the operator string at node.ts:383. That is exactly the 18 the dev reports as form D. Zero comment sites carrying a dead number remain, so 52 to 0 with none left holds on the surface this stage owns. The card's two control sites (driver-error-classification.ts:608, node.ts:1428) now read "before commit ...". Of the 117 distinct numbers in the head tree, 109 answer 200 and the 8 that answer 404 are the string-literal sites above.

Check-runs on 686a4c60cb, read 2026-09-29T16:34:34Z: 33 check-runs, 33 names, newest per name: 29 success, 3 skipped (Build Docs, Console Pin Gate, Packed-tarball smoke (opt-in)), 1 still in progress (Test Core (5/6)), 0 failure. Among the successes: Check Changeset, Lint & Repo Gates, Build Core, all four Type Check rows, TypeScript Type Check, Temporal Conformance, Dogfood Regression Gate and its three shards, Dogfood Verify CLI, Part-of PR must not also close its card, The card this PR closes must claim this branch, both single-claim guards. No verdict is inferred for the one running shard.

② Semver level

.changeset/types-provenance-anchors.md names one package, '@objectstack/types': patch, in PR #20632's form ("Comments only: no error code, refusal text, type, export or runtime behaviour changes."). patch is right: the docblocks reach dist (index.d.ts, node.d.ts and the .js files carry the rewritten prose), so bytes ship and skip-changeset would be wrong; nothing exported, typed or behavioural changes, so minor would be wrong. Check Changeset is success. Clause-②: no on line 2 of the body is right: 0 non-comment changed lines, no accept set moves, and no Clause-②: yes appears anywhere. Right.

③ Boundary flags

Implemented-by: claude/issue-20594-types-dead-citations
Reviewed-by: local_1d2a197c-c20e-4e90-9be8-413d4d432289

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 29, 2026 16:39
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 00f045d Sep 29, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20594-types-dead-citations branch September 29, 2026 16:59
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 tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant