Skip to content

docs(platform-objects): re-anchor the dead tracker citations to the commits and ADR that decided them (stage 7 of #20595) - #21477

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20595-platform-objects-citations
Oct 2, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20595-platform-objects-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20595
Clause-②: no

What changed

Stage 7 of the domain:engine lane of the dead-citation sweep: packages/platform-objects/**, comment and docblock prose only, per the claim (5961679986). Stages 1 to 6 landed as a7d9768ec, d150c3039, 4bf4e7e70, 13a24ece2, db0cf2231 and 85986144c. #20595 stays open: the other half of this lane is the packages this stage does not touch (core 40, metadata-core 19, drivers/driver-turso 14, drivers/driver-mongodb 9, formula 4, metadata-fs 2 on the census after this stage, 88 in all), plus the test-string sites the card carries for a widened stage.

Every comment or docblock site in the package that cited a tracker number answering 404 is rewritten in ruling C+D's form C (record 5749154545 on #19123): the ADR when one records the decision, otherwise the commit in this repository's history that made it. That is 42 sites on 42 lines in 28 files, covering 12 numbers:

No comment-id citation stands in the package (see Census).

Anchors: 11 numbers by commit, 1 by ADR, 0 by words alone. 12 distinct shas. #11374 is split by subject: 3954fb7df (the identity columns' bounds, the route-A rule platform-keyed-text-bounds.test.ts once pinned, and the deliberately unbounded sys_verification.value, 15 sites) and 4805b5619 (sys_import_job.created_by, the route's last column, 1 site). 10 numbers reuse the anchor another lane or stage already used for them (for #11374, its 15-site half); 3 anchors were measured here: cb954f170 (#11351), 74fb2f7a8 (#19249) and 4805b5619 (#11374's one-site half). 0 reused anchors were overridden.

Only comments changed. Every file keeps its line count (42 lines out, 42 in, plus the changeset), so no line citation into any of them moves. No code token moves (the guard below). No citation number is added: on every changed line the numbers on the new text are a subset of those on the old (the only numbers on + lines are #3653, #11701, #12069 and #15989, each already on its line and each answering 200).

A patch changeset: 26 of the 27 rewritten non-test lines are in the published dist (the .d.ts keeps JSDoc on exported members, and esbuild keeps the field comments inside the object literals), and dist is not byte-identical with the base text (see Changeset).

H0: the package and its size

The gate's own node scripts/check-issue-citations.mjs --census --json at base 7e7e64b13 (the before run below), allocated-but-absent per remaining domain:engine package:

package before after this stage
core 40 40
platform-objects 27 0
metadata-core 19 19
drivers/driver-turso 14 14
drivers/driver-mongodb 9 9
formula 4 4
metadata-fs 2 2
metadata-protocol, objectql, metadata, drivers/driver-sql, drivers/driver-memory, drivers/driver-sqlite-wasm, plugins/plugin-pinyin-search 0 each 0 each

The lane total goes 115 to 88. core (40) is larger than platform-objects; the claim records the PM's stage-order call (two in-flight cards in this batch write packages/core), so this stage took platform-objects, which the re-measure finds non-empty.

Census: platform-objects, before and after

Instrument (A1). The gate's own node scripts/check-issue-citations.mjs --census --json, read-only and unchanged. The count is its allocated-but-absent findings under packages/platform-objects/.

reading tree board whole-repo allocated-but-absent sites lines files numbers
before base 7e7e64b13, run 21:26:33Z to 21:30:05Z enumerated, 193 pages, frontier #21468, 19,289 records (newest number read before and after the run: #21468) 230 27 27 18 8
after e5d9a5d85, run 21:43:18Z to 21:46:37Z enumerated, 193 pages, frontier #21470, 19,291 records (newest before and after: #21470) 203 0 0 0 0

The whole-repo drop is 27, and the two finding sets differ by exactly the 27 rows of this package, removed; none was added. resolves (35,315), resolves-as-pull-request (2,381) and cross-repo-unjudged (1,229) did not move. The head's later commit is the changeset, outside the census surface.

Supplementary instrument, the whole package. The census reads neither test files nor strings nor files outside src. A second reading runs the gate's own exported extractCitations (whole-file and comment-prose projections) over every tracked file in the package (158) and classifies each citation with the gate's classifyCitation against one board enumerated by the gate's enumerateBoard (193 pages, frontier #21468, 19,289 records, 21:31:03Z to 21:34:29Z), the same board for both readings. Every one of the 12 numbers in the population was then read on its own over the issues endpoint (21:35Z): all 12 answer 404; the lit controls #5286 and #12624 answer 200, and so do the four numbers that stay on changed lines (#3653, #11701, #12069, #15989).

reading citations dead src comment outside-glob comment tsconfig.scripts.json test comment test string src string changelog
before, 7e7e64b13 1,410 69 27 2 1 12 5 1 21
after, e5d9a5d85 1,368 27 0 0 0 0 5 1 21

The citation count drops by exactly the 42 rewritten sites. The live counts did not move (src comment: 329 resolve, 10 as pull requests, 4 cross-repo; test comment: 273, 18 and 10). A third, raw reading (every # followed by 2 to 6 digits, whatever surrounds it) counts 1,418 before and 1,376 after: also a drop of 42. The one src string row is not a citation: it is the hex colour '#475569' at src/apps/setup.app.ts:45, which the grammar's six-digit ceiling admits and the classifier reads as never issued; the census blanks strings and never sees it.

Comment ids. No comment-id citation stands in the package: every ten-digit run under packages/platform-objects (its CHANGELOG.md aside) is a translation source hash or a phone-number example inside a string, and an issuecomment / discussion_r grep finds no line (exit 1). The same ten-digit grep over packages/metadata-protocol finds 15 lines (control).

Per-number table

census counts census sites, outside the three sites outside the census glob, test the test-comment sites. Every sha matches exactly one commit (git rev-parse --disambiguate, count 1) and is an ancestor of the base 7e7e64b13 (git merge-base --is-ancestor, exit 0 for all 12; the clone was unshallowed first, see Acceptance notes). The + lines carry exactly these 12 nine-hex spans and no other. Each commit names the number it replaces: 6 in the message and the diff (3954fb7df, 4805b5619, d6e80b28b, 2c86fe3ea, 801296050, 74fb2f7a8), 6 in the diff alone (09b4f4e4e on 16 added lines, 4d25d22d4 14, cb954f170 9, 945e91a13 6, 5529a374e 3, e170b0ae5 1); ADR-0104's addendum names #15041 in its Provenance paragraph. git blame at the base puts 29 of the 42 sites on their anchor; the other 13 were written by a commit that cites the number as an earlier decision (for example dccbcec2e citing #10165's null predicate, 428f9b24a citing the #11513 posture as precedent, 945e91a13 moving #11374's rule out of a test file), and in each case the anchor is the commit that made the change the sentence credits to the number. source says whether another lane or stage already used this anchor for this number (reused) or it was measured here (measured).

number census outside test anchor kind source what it decided
#8676 1 0 0 d6e80b28b commit reused (the dogfood lane, cf684c98e) flag sys_account.password and previous_password_hashes internal
#8715 0 0 1 2c86fe3ea commit reused (the spec lane, a51920f5f) retire ApiKeySchema: sys_api_key has one declaration, the platform object
#10165 1 0 3 801296050 commit reused (stages 3 and 4; the plugin-auth lane) lifecycle.ttl.onlyWhen with the canonical null predicate, and the two refines refusing it beside rotation and archive; its message records the maintainer's 2026-08-20 ruling (option A)
#11351 0 1 0 cb954f170 commit measured put the packages' scripts/ i18n-extract directories in a tsc program; it wrote this tsconfig.scripts.json
#11374 14 0 2 3954fb7df (15 sites) commit reused (the plugin-audit lane, 4dfff176b, for the same route-A sentence) sourced maxLength bounds on the unbounded keyed identity columns (route A); its message records the 2026-08-24 ruling and that sys_verification.value stays deliberately unbounded; it created the package pin that carried route A's rule
#11374 (1 of the 14) 4805b5619 (1 site) commit measured the route's last column, sys_import_job.created_by (「#11374 route A, last column」)
#11513 2 0 1 e170b0ae5 commit reused (the runtime lane, a186aea99) lock package-declared permission sets at the save door and clone to customize; its message records the 2026-08-24 ruling, and its diff carries both the activate/deactivate row-state carve-out and 「an ordinary org-owned set with no upgrade linkage」
#11671 5 1 1 09b4f4e4e commit reused (the services lane's pointer 5914040746; the cli lane) record which source revision a generated translation leaf was filled from (the squash of PR #12557), correcting the false 「this hole cannot occur there」 note
#11757 2 1 2 4d25d22d4 commit reused (the plugin-auth lane, 4d04b6be3) retire the sys_scim_provider platform object
#12147 0 0 1 945e91a13 commit reused (the plugin-audit and plugin-security lanes, for the same heading) the class-level keyed-text-bounds gate over every *.object.ts, superseding the per-package pins
#14817 1 0 0 5529a374e commit reused (the cli lane, 4edb61449) put the three shipped platform record pages under an i18n gate; its message records that they author everything under slots.* as inline locale maps
#15041 1 0 0 ADR-0104's 2026-09-05 addendum ADR reused (stages 3 and 4) the media family's column holds the bare sys_file id; item 2 of its Sequencing is #15989, the card this sentence also names
#19249 0 0 1 74fb2f7a8 commit measured declare the sys_user set_user_manager row action (「Part of #19249」); it wrote this test file

No ADR or ruling record decides any of the other 11 numbers: git grep over docs/adr and scripts/adr-anchors finds none of them except #11513, which ADR-0126 names only as precedent (「the landed #11513 posture」, the same dead number) rather than recording its ruling; e170b0ae5's message records that ruling verbatim, so the commit is the anchor.

Wordings to check

Most rewrites swap a tag in place ([#N] to [commit SHA], (#N) to (commit SHA), #N's X to commit SHA's X, in #N / before #N to in commit SHA / before commit SHA). These say more than the tag:

Sites left

  • In comments (src, test, outside the glob): none.
  • String literals: 5 test-string sites, 3 numbers, 3 files (describe and it titles, assertion arguments): #8715 2 (sys-api-key-single-declaration.test.ts:23, :51), #19249 2 (sys-user-set-manager-action.test.ts:76, :141), #10165 1 (sys-session-lifecycle.test.ts:60). Every one of the 3 is in this stage's table. Strings are outside this stage's surface. Non-test strings cite none (the hex colour above is not a citation).
  • Files the claim excludes: the ten *.generated.ts files carry no citation at all at the base, and object-lifecycle-panel-echo-decisions.test.ts carries 22, none dead, so nothing is carried from them.
  • Outside src: the release-owned CHANGELOG.md names dead numbers on 21 sites (16 numbers); left. package.json, tsconfig.json, tsconfig.test.json, test-typecheck-debt.json and LICENSE cite no dead number.

Mechanical guard: no code token moves

The guard (stages 2 to 6's) compares base 7e7e64b13 against the tree at e5d9a5d85 over all 28 touched files, with TypeScript 6.0.3; tsconfig.scripts.json is parsed with ts.parseJsonText:

  • Reading 1: the parser's leaf nodes, from a forEachChild walk. Comments are trivia there, and JSDoc is never visited. A leaf that is not itself a token is re-scanned with trivia skipped.
  • Reading 2: the full token stream in parser context, from a getChildren walk, JSDoc nodes skipped. String, template and numeric literals are compared in full on both readings.

Results:

  • Real run: 21,090 base tokens, 0 files with a token change (exit 0).
  • Comment control (「Upstream hard cap」 to 「Upstream HARD cap」, sys-device-code.object.ts): 0 files changed (exit 0).
  • Positive control, an identifier (HAND_AUTHORED_SECTIONS to HAND_AUTHORED_SECTIONSX, source-hash.ts): DIFFER on both readings (exit 1).
  • Positive control, a string literal ('Provider ID' to 'Provider IDX', sys-account.object.ts): DIFFER on both readings (exit 1).
  • Positive control, a numeric literal (maxLength: 64 to 65, sys-api-key.object.ts): DIFFER on both readings (exit 1).
  • Positive control, a JSON value ("rootDir": "." to "./", tsconfig.scripts.json): DIFFER on both readings (exit 1).

Each mutation went through scripts/ablation-replace.mjs (wrap mode, anchor hit 1 to 0, blob changed) under a shell trap that restores by absolute path from HEAD. Each restore was proven equal to its HEAD blob (e98db7d7591b, 67b0e306ca60, e5196ab7b57c, e889bb45f2ef, 288105dc3e6b), with git diff HEAD empty and a clean tree afterwards.

Changeset: patch (dist measured)

files[] is dist, README.md and CHANGELOG.md, and the package is not private. In one script under the shared verify lock (VERDICT command-exit 0, held 243s), at e5d9a5d85: the workspace was built first (turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2, 71 of 71 tasks, 14 cached), then the package's own build (tsup plus check-dts-emitted) ran three times:

  • Leg 1, the head text: 66 dist files hashed. Of the 27 rewritten non-test lines, 26 appear verbatim in dist; the one that does not is identity/index.ts:48, a comment between two export statements.
  • Leg 2, the base text put back in the 18 non-test touched files (18 of 18 proven equal to their base blob): 18 of the 66 files differ from leg 1 (index.js / .mjs; apps/index .d.ts / .d.mts / .js / .mjs; audit/index.js / .mjs; identity/index .d.ts / .d.mts / .js / .mjs; metadata-translations/index.d.ts / .d.mts; plugin.js / .mjs; system/index.d.ts / .d.mts), and scripts/ablation-dist-preflight.mjs finds the base marker 「and [finding] check:i18n verifies key presence, not that an untranslated leaf still matches the source string it was filled from — and the drift is sticky #11671 is its」 in 2 built files (apps/index.d.ts, apps/index.d.mts; exit 0).
  • Leg 3, after the proven restore (18 of 18 equal to their HEAD blob, git diff HEAD empty, porcelain empty): all 66 files are byte-identical to leg 1, and the preflight's --absent reading exits 0 with a clean tree, so the build is deterministic and the difference is the rewrite.

So the rewrite ships, and .changeset/20595-platform-objects-provenance-anchors.md declares a patch for @objectstack/platform-objects, comment text only, with the claim's Clause-②: no line. The changeset commit touches no file under packages/platform-objects.

Gates (head f45b9e60f)

  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at f45b9e60f (29 paths against merge base 7e7e64b13, 100 changed lines) derived 63 commands. All 63 ran, each exit code captured before any pipe: 63 exit 0. --ran reports 「63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero) and exits 0. The PM's lead derivation (49 commands, tree 713b0fa7) is a subset: the extra 14 come from the test and tsconfig paths (6) and the changeset (8).
  • Named readings: node scripts/check-issue-citations.mjs exits 0 (「every citation this change adds resolves (or is a declared cross-repo reference)」: 2 judged across 18 files, both resolve); pnpm check:issue-citations exits 0 (self-test, 173 cases, 9 batteries); pnpm check:doc-authoring exits 0 (the sibling-package prose-id baseline holds, no growth); pnpm check:i18n exits 0 (all bundles in sync); pnpm check:nul-bytes exits 0 (9,807 files, no raw control bytes), and a control-byte grep over the 29 changed files finds none (exit 1).
  • Tests and typecheck, under the verify lock, at f45b9e60f (VERDICT command-exit 0): pnpm --filter @objectstack/platform-objects test: 59 test files pass (59), 949 tests pass (949); pnpm --filter @objectstack/platform-objects typecheck (tsc --noEmit, tsc --noEmit -p tsconfig.scripts.json, then check:test-typecheck: 「1 file(s) / 3 error(s) / 2 pinned signature(s) held」) exits 0. tsc --listFilesOnly puts all 59 tracked test files in tsconfig.test.json's program, the 18 changed non-test src files in tsconfig.json's, and scripts/i18n-extract.config.ts in tsconfig.scripts.json's.
  • Lint, as a proven narrowing: eslint with inline config disabled, over the 27 touched .ts files plus dist/index.js as the control: 28 results, 0 errors and 1 warning, the control's ignore notice; none of the 27 is reported ignored. tsconfig.scripts.json alone answers 「File ignored because no matching configuration was supplied」 (not an eslint target). eslint.config.mjs never enables type-aware linting (its lines 327 and 328 say so), so a comment edit cannot move the verdict on an untouched file. The repo-wide pnpm lint is CI's run.

Acceptance notes


Generated by Claude Code

claude added 2 commits October 2, 2026 21:43
…ommits and ADR that decided them

Comment and docblock prose only: 42 sites on 42 lines in 28 files, covering
12 tracker numbers that answer 404, now cite the commit in this repository
that decided them (11 numbers) or ADR-0104's 2026-09-05 addendum (1). Every
file keeps its line count; no code token moves.

Claude-Session: https://claude.ai/code/session_01DDZNkDVwPQnevTFcYE47H3
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

10 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ⚠️ 8 changed file(s) yielded no anchor (packages/platform-objects/src/apps/translations/setup.translation.ts, packages/platform-objects/src/apps/translations/source-hash.ts, packages/platform-objects/src/identity/index.ts, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

What this run could not see
  • 8 changed file(s) yielded no anchor (packages/platform-objects/src/apps/translations/setup.translation.ts, packages/platform-objects/src/apps/translations/source-hash.ts, packages/platform-objects/src/identity/index.ts, …) — pages documenting those are invisible to this run
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • 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 aa4632235ba571ef800b95e6bc18d00a30aa1d57 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 7e6c012508e6aedf1ece4415d172b1a1a19d8dfe — the merge of head f45b9e60f69a6edb8a27657e424df92788734fc3 into base aa4632235ba571ef800b95e6bc18d00a30aa1d57, 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 7e6c012508e6aedf1ece4415d172b1a1a19d8dfe && git checkout 7e6c012508e6aedf1ece4415d172b1a1a19d8dfe
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin aa4632235ba571ef800b95e6bc18d00a30aa1d57 f45b9e60f69a6edb8a27657e424df92788734fc3 && git checkout -B drift-repro aa4632235ba571ef800b95e6bc18d00a30aa1d57 && git merge --no-ff f45b9e60f69a6edb8a27657e424df92788734fc3

node scripts/docs-audit/affected-docs.mjs --json aa4632235ba571ef800b95e6bc18d00a30aa1d57

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

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Oct 2, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 2, 2026 22:47
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 2, 2026 22:47
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit 48fa7a3 Oct 2, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20595-platform-objects-citations branch October 2, 2026 23:29
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.

2 participants