Skip to content

docs(metadata-core): re-anchor the dead tracker citations to the commits and ADR that decided them (stage 9 of #20595) - #21525

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-20595-metadata-core-citations
Oct 3, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-20595-metadata-core-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20595
Clause-②: no

What changed

Stage 9 of the domain:engine lane of the dead-citation sweep: packages/metadata-core/**, comment and docblock prose only, per the claim (5964472656). Stages 1 to 8 landed as a7d9768ec, d150c3039, 4bf4e7e70, 13a24ece2, db0cf2231, 85986144c, 48fa7a381 and c205b6c35. #20595 stays open: the other half of this lane is the packages this stage does not touch (drivers/driver-turso 14, drivers/driver-mongodb 9, formula 4, metadata-fs 2 on the census after this stage, 29 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), in the form #20234 applies it to the spec tree: the ADR when one records the decision, otherwise the commit in this repository's history that made it. That is 30 sites on 29 lines in 14 files, covering 12 numbers:

No comment-id citation is dead here: the package's one comment id, ruling 5865890672 on #20390 (artifact-forward-conversion.test.ts:486), answers 200 (see Census).

Anchors: 10 numbers by commit, 1 by ADR, 1 by repository qualifier; 10 distinct shas. 9 numbers reuse the anchor another lane or stage already used for them, and #6111 takes stage 6's respelling. Measured here are b5a239815 (#12930) and, for #16864, the ADR-0087 passage this sentence needs (the spec lane anchored the same number to ADR-0087 for a different sentence; see the table).

Only comments changed. Every file keeps its line count (29 lines out, 29 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 #10101 twice and #7894, each already on its line and each answering 200, and the objectui#… references, which are cross-repository).

A patch changeset: 13 of the 20 rewritten non-test lines are in the published dist (the .d.ts keeps JSDoc on exported members), 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 c205b6c35 (the before run below), allocated-but-absent per remaining domain:engine package:

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

The lane total goes 48 to 29. metadata-core is the largest remaining package and reads 19, as at stage 8's head census (a4c483901), so the stage went ahead.

Census: metadata-core, 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/metadata-core/.

reading tree board whole-repo allocated-but-absent sites lines files numbers
before base c205b6c35, run 02:14:44Z to 02:18:05Z enumerated, 194 pages, frontier #21521, 19,342 records 163 19 19 9 11
after fcee5ffe3, run 02:32:19Z to 02:35:31Z enumerated, 194 pages, frontier #21521, 19,342 records (newest number read before and after the run: #21521) 144 0 0 0 0

The whole-repo drop is 19, and the two finding sets differ by exactly the 19 rows of this package, removed; none was added. resolves (35,468) and resolves-as-pull-request (2,388) did not move; cross-repo-unjudged went 1,244 to 1,247, the three census-surface objectui#6111 respellings.

The head's later commits are the changeset and one merge of main. The census was run a third time at the head 99f2cfdf0 (02:45:55Z to 02:49:05Z, 194 pages, frontier #21524, 19,345 records, newest #21522 before and #21524 after): whole-repo 144, metadata-core 0, and its allocated-but-absent finding set is identical to the after run's (0 removed, 0 added). Its resolves reads 35,483, 15 more than above, from the merged main commits outside this package.

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 (57) and classifies each citation with the gate's classifyCitation against one board enumerated by the gate's enumerateBoard (194 pages, frontier #21521, 19,342 records, read 02:18:40Z to 02:21:51Z), the same board for both readings. Every one of the 12 numbers was then read on its own over the issues endpoint (02:29:32Z): all 12 answer 404; the lit controls #5286 and #12624 answer 200, and so do the two numbers that stay on changed lines (#10101, #7894).

reading citations dead src comment test comment tsup.config.ts comment other files test string changelog
before, c205b6c35 693 40 19 10 1 0 1 9
after, fcee5ffe3 668 10 0 0 0 0 1 9

The citation count drops by 25: the 30 rewritten sites less the 5 objectui#6111 respellings, which stay citations as cross-repository ones (src comment cross-repo 16 to 19, test comment 6 to 8). The live counts did not move (src comment: 325 resolve, 6 as pull requests; test comment: 49 and 4). A third, raw reading (every # followed by 2 to 6 digits, whatever surrounds it, CHANGELOG.md aside) counts 477 before and 452 after: also a drop of 25.

Comment ids. Every ten-digit run under packages/metadata-core (its CHANGELOG.md aside) was read: two lines. artifact-forward-conversion.test.ts:486 cites ruling 5865890672, which answers 200 (the #20390 ruling comment; the control 5964472656, the claim, answers 200 too). contract-suite.ts:331 is a zero-filled sha256: fixture, not a citation.

The objectui number. objectui#6111 was read in this session: it answers 200 (a closed issue, 「Authored FormSection.visibleWhen is dropped by all four plugin-form layouts」), beside objectui#6110 and objectui#6010, both 200. Stage 6 could not read objectui from its container and reused the spec lane's reading; this one is direct.

Per-number table

census counts census sites, outside the one site 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 c205b6c35 (git merge-base --is-ancestor, exit 0 for all 10; the clone is not shallow). The + lines carry exactly these 10 nine-hex spans as new ones. Each commit names the number it replaces, in its message, its diff or both (b5a239815 in its subject's squash suffix only; f887e5249 in its message only). git blame at the base puts 10 of the 23 commit-anchored lines on their anchor; the other 13 were written by a commit that cites the number as an earlier decision (200d255e7 citing #12914 and #12930, 1272f0a6b citing #8707 and #8778, 15eb2c97f citing #10340 and #8919, 46644e25a citing #11021, 15d55fb24 citing #11235), 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
#6111 3 0 2 objectui#6111 repository qualifier reused (stage 6; the spec lane's 2123fcca3) every site reads 「objectui#6110 + #6111」: the second number is objectui's too, so it now carries its qualifier like the first
#8707 3 0 0 1408fe385 commit reused (the plugin-audit, plugin-approvals and service-automation lanes) stamp audit rows from the record's own organization, the resolver this package now hosts. [#8707 / #10101] reads [commit 1408fe385 / #10101], the plugin-audit lane's spelling of the same pair
#8778 1 0 0 7901b2dd2 commit reused (stage 4; the spec, plugin-security, plugin-audit, plugin-approvals, service-storage and service-automation lanes) 「Option A per the maintainer ruling on #8778」: the stamp-only organization declaration. The site is inside a quoted ruling (see Wordings)
#8919 1 0 0 b5378550e commit reused (the runtime lane, for the same 「single-resolution shape the REST doors carry」 phrase; the rest, cloud-connection, plugin-security and dogfood lanes) gate /meta publish and rollback on manage_metadata
#10062 2 0 0 fa5d137ab commit reused (stage 3; the service-automation lane) gate undeclared workspace imports; it sank the provenance pair here and created code-artifact-provenance.ts
#10340 3 0 4 26f3588fb commit reused (stage 1; the rest and runtime lanes) decide /meta org scope on the folded type; it corrected the measured-false parity claim in meta-write-org-scope.ts and wrote that file's test header
#10842 1 0 0 f334d662e commit reused (stage 1) watch(_, since) replays from history; it settled that card and deleted the resumableWatch declaration the example quoted
#11021 2 0 0 7d81c889f commit reused (stage 1) close() terminates watch iterators instead of emitting a drain event; it wrote the invariant's MUST NOT
#11235 0 1 0 376c70f98 commit reused (stage 1; the rest lane) derive the discovery version; it added shims: true to packages/metadata-protocol/tsup.config.ts, the line this one mirrors
#12914 1 0 3 f887e5249 commit reused (stage 6) a form SECTION visibleWhen binds current_user too: it re-measured the section contract sentence
#12930 1 0 0 b5a239815 commit measured a form FIELD visibleWhen binds current_user: it re-measured the field prose (2026-08-28, the same day as the vocabulary correction 2852accef)
#16864 1 0 1 ADR-0087 ADR measured passage; the spec lane's a8acee28d anchored #16864 to ADR-0087's 2026-09-13 addendum for the three-seam sentence the 「Superseded for metadata at rest」 note under 「The load-window's second half is now mechanical」 records the determination these sites quote: the paragraph states the rule 「for the authoring load path and for nothing else」, and 「Retirement is an authoring-surface event」. It was written by 24a86923d with the 2026-09-13 addendum (「the code half is #16864's」). 29dd1a6dd, the commit that settled that card and wrote the flag's own docblock, says the same; the ADR comes first

No ADR or ruling record names any of the 12 numbers: git grep over docs/adr and scripts/adr-anchors finds none of them. ADR-0087 records #16864's determination without naming the number.

Wordings to check

Most rewrites swap a tag in place ([#N] to [commit SHA], (#N) to (commit SHA), #N re-measured to commit SHA re-measured, a #N — header to Commit SHA —, stage 1's form). These say more than the tag:

Sites left

Mechanical guard: no code token moves

The guard (stages 2 to 8's) compares base c205b6c35 against the tree over all 14 touched files, with TypeScript 6.0.3:

  • 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, at fcee5ffe3:

  • Real run: 17,663 base tokens, 0 files with a token change (exit 0).
  • Comment control (「Faithful again」 to 「FAITHFUL again」, form-predicate-root-policy.ts): 0 files changed (exit 0).
  • Positive control, an identifier (BOUND_FORM_FIELD_PREDICATE_ROOTS to XBOUND_…, form-predicate-root-policy.ts): DIFFER on both readings (exit 1).
  • Positive control, a template-literal string (「must name the 」 to 「must name thE 」, contract-suite.ts): DIFFER on both readings (exit 1).
  • Positive control, a numeric literal (setTimeout(resolve, 100) to 101, contract-suite.ts): DIFFER on both readings (exit 1).
  • Positive control, a config value (sourcemap: true to false, tsup.config.ts): 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 (ce90e5aab5fa, cc43d4b043b5, 23fa6b1bd3aa), with git diff HEAD empty and a clean tree afterwards. The identifier control's first attempt was refused by ablation-replace before the guard ran (its replacement contained the anchor, so the anchor count moved 1 to 1); the anchor was changed and the whole control set re-run, and the numbers above are that run's.

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 89s), at fcee5ffe3: the dependency closure was built first (pnpm --filter '@objectstack/metadata-core^...' build), then the package's own build (tsup and check-dts-emitted) ran three times:

  • Leg 1, the head text: 12 dist files hashed. Of the 20 rewritten non-test lines, 13 appear verbatim in dist, all in declaration files (index.d.ts / index.d.cts, the shared chunk repository-DHMpxysr.d.ts, and testing.d.ts for contract-suite.ts). The 7 that do not are module docblocks, // lines and the docblock of a non-exported constant (ORG_OVERRIDABLE_TYPES): artifact-forward-conversion.ts:101, index.ts:57 and :120, record-organization.ts:4 and :19, meta-write-org-scope.ts:77, tsup.config.ts:43.
  • Leg 2, the base text put back in the 10 non-test touched files (10 of 10 proven equal to their base blob): 4 of the 12 files differ from leg 1 (index.d.ts, index.d.cts, repository-DHMpxysr.d.ts, testing.d.ts); the JavaScript files and their sourcemaps do not. scripts/ablation-dist-preflight.mjs finds the base marker 「the /meta org scope is decided from the RAW url spelling: translations / email_templates read and write env-wide where their singular twin is org-scoped #10340 measurement in」 in 2 built files (index.d.ts, index.d.cts; exit 0).
  • Leg 3, after the proven restore (10 of 10 equal to their HEAD blob, git diff HEAD empty, porcelain empty): all 12 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-metadata-core-provenance-anchors.md declares a patch for @objectstack/metadata-core, comment text only, with the claim's Clause-②: no line. It names every anchor that is not a commit: ADR-0087 for the two retiredFromLoadPath sites, the five objectui#6111 respellings, and the bracketed substitution inside the quoted ruling. The changeset commit touches no file under packages/metadata-core.

Gates (head 99f2cfdf0)

  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at 99f2cfdf0 (15 paths against merge base 88fb5e85a, 78 changed lines) derived 62 commands. All 62 ran, each exit code captured before any pipe: 62 exit 0. --ran reports 「62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero) and exits 0. The PM's lead derivation (54 commands, tree c205b6c35) is a subset: the extra 8 are the families the .changeset/ path adds (the ADR-0087 registration and empty-changeset pairs, check:objectui-changeset, check:pm-changeset-deadline-census and two release self-tests).
  • Roster families under touched directories, run as well: node scripts/check-changeset-fixed.mjs, pnpm check:authz-resolver, pnpm check:error-code-casing and pnpm check:filter-alias-parity: 4 exit 0.
  • Named readings: node scripts/check-issue-citations.mjs exits 0 (「every citation this change adds resolves (or is a declared cross-repo reference)」: 8 judged across 9 files: 6 cross-repo and 2 live, the objectui#… pairs and Promote resolveRecordOrganizationField to the shared platform-row resolver (approvals + automation runs), per the ruled cloud#1395 Option A #10101 kept on changed lines); 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:nul-bytes exits 0 (9,870 files, no raw control bytes), and a control-byte grep over the 15 changed files finds none (exit 1). The four changeset gates (check-changeset-no-major, check-adr-0087-registration, check-empty-changeset with --base origin/main, and check:changeset-gate-self-tests) exit 0.
  • Build, tests and typecheck, under the verify lock: the workspace build after the merge (turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2, 71 of 71 tasks, 8 cached; VERDICT command-exit 0, held 246s); then at 99f2cfdf0 pnpm --filter @objectstack/metadata-core test: 16 test files pass (16), 298 tests pass (298); pnpm --filter @objectstack/metadata-core typecheck (tsc --noEmit && tsc --noEmit -p tsconfig.test.json) exits 0 (VERDICT command-exit 0, held 18s). tsc --listFilesOnly puts all 16 tracked test files in tsconfig.test.json's program and the 9 changed non-test src files in tsconfig.json's; tsup.config.ts is in neither, and the token guard covers it. No importing package owes a run: the declaration files change only in comment text.
  • Lint, as a proven narrowing, at 99f2cfdf0: eslint with inline config disabled, over the 14 touched .ts files plus dist/index.js as the control: 15 results, 0 errors and 1 warning, the control's ignore notice; none of the 14 is reported ignored. 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 3 commits October 3, 2026 02:32
…its and ADR that decided them

Stage 9 of the domain:engine dead-citation lane: 30 comment and docblock
sites on 29 lines in 14 files of packages/metadata-core that cited tracker
numbers now answering 404 cite an object this repository controls instead
(ruling C+D, form C): 10 numbers by commit, #16864 by ADR-0087, and the
objectui pair respelled objectui#6110 + objectui#6111. Comments only; every
file keeps its line count.

Claude-Session: https://claude.ai/code/session_01DDZNkDVwPQnevTFcYE47H3
Co-authored-by: Claude <noreply@anthropic.com>
…d declaration files

Clause-②: no

Claude-Session: https://claude.ai/code/session_01DDZNkDVwPQnevTFcYE47H3
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tests tooling labels Oct 3, 2026
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ⚠️ 8 changed file(s) yielded no anchor (packages/metadata-core/src/artifact-forward-conversion.ts, packages/metadata-core/src/code-artifact-provenance.ts, packages/metadata-core/src/form-predicate-root-policy.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/metadata-core/src/artifact-forward-conversion.ts, packages/metadata-core/src/code-artifact-provenance.ts, packages/metadata-core/src/form-predicate-root-policy.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 — 4 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 88fb5e85a02009344e9e2cf1abc929ae694c051f → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 88fb5e85a02009344e9e2cf1abc929ae694c051f

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

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 3, 2026 03:28
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 3, 2026 03:28
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 3, 2026
Merged via the queue into main with commit c98a72d Oct 3, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20595-metadata-core-citations branch October 3, 2026 03:58
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/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants