Skip to content

docs(metadata-fs): re-anchor the dead tracker citations to the commit that decided them (stage 13 of #20595) - #21640

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

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20595
Clause-②: no

What changed

Stage 13 of the domain:engine lane of the dead-citation sweep: packages/metadata-fs/**, comment and docblock prose only, per the claim (5973452558). Stages 1 to 11 landed as a7d9768ec, d150c3039, 4bf4e7e70, 13a24ece2, db0cf2231, 85986144c, 48fa7a381, c205b6c35, c98a72d69, fd5a1cd59 and f97660cdd; stage 12 (packages/formula) is PR #21635, in review, with a disjoint file surface. #20595 stays open: this PR does not touch formula, nor the test-string sites the card carries for a widened stage, and the seat decides the card's close-out.

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 3 sites on 3 lines in 3 files, all citing one number (#11021), all re-anchored to one commit, 7d81c889f:

  • 2 census sites (2 lines: src/repository.ts:230 and src/sync.ts:41): the whole allocated-but-absent population of the gate's own census in this package at the base;
  • 1 test-comment site (test/close-terminates-watch.test.ts:103), outside the census glob (test/ is not under src/, and the census defers test files anyway). Same number;
  • outside the census glob, inside the claimed surface: none. README.md, tsconfig.test.json and vitest.config.ts carry 10 citations between them, and all 10 resolve on the enumerated board (below); package.json, tsconfig.json and tsup.config.ts carry none;
  • dead comment ids: none. The package carries no ten-digit comment id and no issuecomment or discussion_r link (git grep exit 1).

Anchors: 1 number, by commit; 0 by ADR, 0 by repository qualifier; 1 sha. 7d81c889f is the anchor stage 1 (a7d9768ec) and stage 9 (c98a72d69) already chose for the same number; it is reused here and re-proven below for this package's sentences.

Only comments changed. All three files keep their line counts (3 lines out, 3 in, plus the changeset), so no line citation into any of them moves. No code token moves (the guard below). All 6 changed lines under packages/ open with a comment marker. No citation number is added: the only tracker number on a + line is #11127 on sync.ts:41, carried over unchanged from the - line, and it resolves (a closed issue). The only new nine-hex span is 7d81c889f, 3 times.

A patch changeset: 1 of the 2 rewritten non-test lines is in the published dist (the FileSystemRepository.close() docblock, in the declarations and in the JavaScript esbuild emits), 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 0fc80878f (the before run below), allocated-but-absent per remaining domain:engine package (stage 12's H0 list):

package before after this stage
metadata-fs 2 0
formula 4 4 (removed by stage 12, PR #21635, not yet on main)
drivers/driver-mongodb, drivers/driver-turso, metadata-core, 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

metadata-fs reads 2, both #11021, at repository.ts:230 and sync.ts:41, exactly as stage 12's head census (b89eb86cb) read it. So the stage went ahead. On this branch's tree the lane total goes 6 to 4; with stage 12's PR it is 0.

Census: metadata-fs, before and after

Instrument. 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-fs/.

reading tree board whole-repo allocated-but-absent sites lines files numbers
before base 0fc80878f, run 21:04:24Z to 21:07:44Z enumerated, 195 pages, frontier #21636, 19,457 records 119 2 2 2 1
after 67f182575, run 21:14:26Z to 21:17:43Z enumerated, 195 pages, frontier #21637, 19,458 records 117 0 0 0 0
head 32de59091, run 21:37:42Z to 21:40:56Z enumerated, 195 pages, frontier #21639, 19,460 records 117 0 0 0 0

The whole-repo drop is 2, and the before and after finding sets differ by exactly the 2 rows of this package, removed; none was added. resolves (35,763), resolves-as-pull-request (2,383) and cross-repo-unjudged (1,254) did not move: #11127 stays on sync.ts:41 and still resolves. The head's only later commit is the changeset; the head run's finding set is identical to the after run's, line numbers included.

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 (24) and classifies each citation with the gate's classifyCitation against one board enumerated by the gate's enumerateBoard (195 pages, frontier #21636, 19,457 records, read from 21:09:16Z to 21:12:31Z), the same board for both readings.

reading citations dead src comment test comment test string other files changelog
before, 0fc80878f 137 5 2 1 0 0 2
after, 67f182575 134 2 0 0 0 0 2

The citation count drops by 3, the 3 rewritten sites; no respelling stays a citation. The live counts did not move (src comment: 39 resolve as issues, 2 as pull requests; test comment: 44 and 9; test string: 10 and 0; files outside src and test: 8 and 2; changelog: 16 and 2). A third, raw reading (every # followed by 2 to 6 digits, whatever surrounds it, CHANGELOG.md aside) counts 117 before and 114 after: also a drop of 3.

Single reads over the issues endpoint: #11021 answers 404; #11127 answers 200 (a closed issue: FileSystemRepository.close() never reaching its broker); #11136 answers 200 (the pull request whose squash is 7d81c889f).

Per-number table

src counts census sites, test the test-comment sites.

number src test anchor kind source what it decided
#11021 2 1 7d81c889f commit reused (stage 1 a7d9768ec, stage 9 c98a72d69), re-proven here close() terminates watch iterators instead of emitting a drain event: it measured why a synthetic drain event is the wrong shape (the filter and the numeric since drop it, and delivering an event never ends an iterator), fixed that defect in SysMetadataRepository, and wrote invariant 8 in metadata-core's repository.ts (the squash of PR #11136)

Each sentence, judged against the decision it describes rather than the number:

The proof, per the earlier stages' standard:

Wordings to check

All 3 rewrites swap a tag in place, in forms the earlier stages already use:

No reflow. No line was reflowed, so repository.ts:230 and close-terminates-watch.test.ts:103 are now longer than their block's wrap. eslint.config.mjs declares no line-length rule, and a reflow would move neighbouring lines. No file cites a line of any of the three touched files (git grep exit 1), and neither changed phrase is quoted elsewhere.

Sites left

Mechanical guard: no code token moves

The guard compares base 0fc80878f against the tree over all three touched files, with TypeScript 6.0.3, to the earlier stages' two-reading specification. The earlier guard scripts were scratch files, so it was rewritten here to that specification and proven with the controls below.

  • 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, with JSDoc nodes skipped. String, template and numeric literals are compared in full on both readings.

Results, at 67f182575 (the later commit touches none of the three files):

  • Real run: 6,075 base tokens (reading 2), 0 files with a token change (exit 0).
  • Comment controls: 「awaiting the watcher,」 to 「… the WATCHER,」 (repository.ts), 「Best-effort cleanup:」 to 「Best-effort CLEANUP:」 (sync.ts) and 「bites on its own.」 to 「bites ON its own.」 (the test file). 0 files changed (exit 0 each).
  • Positive control, an identifier (export function createBroker( to createBrokerX(, sync.ts): DIFFER on both readings (exit 1).
  • Positive control, a string literal (the word 「no」 in the 「empty filter, no since」 row label, to 「NO」, the test file): DIFFER on both readings (exit 1).
  • Positive control, a template literal (the @ separator in the sweep-failure key template, to #, repository.ts): DIFFER on both readings (exit 1).
  • Positive control, a numeric literal (SETTLE_MS = 2_000 to 2_001, the test file): DIFFER on both readings (exit 1).

Each mutation went through scripts/ablation-replace.mjs (wrap mode; the anchor hit 1 before and 0 after, and the blob changed). It ran under a shell trap that restores by absolute path from HEAD. Each restore was proven equal to its HEAD blob (888f39203432, 122a45dcb516, 0d266189d60c), and afterwards git diff HEAD was empty and the tree clean.

Changeset: patch (dist measured)

files[] is dist, README.md and CHANGELOG.md, and the package is not private. One script ran under the shared verify lock (VERDICT command-exit 0, held 79s, shared-box seconds), at 67f182575. It built the dependency closure first (pnpm --workspace-concurrency=2 --filter '@objectstack/metadata-fs^...' build, exit 0), then ran the package's own build (tsup and check-dts-emitted) three times, exit 0 each:

  • Leg 1, the head text: 6 dist files hashed (index.js, index.cjs, their sourcemaps, index.d.ts, index.d.cts). 1 of the 2 rewritten non-test lines appears verbatim in dist: the close() docblock line (repository.ts:230), in index.d.ts, index.d.cts, index.js and index.cjs (esbuild keeps that docblock). The other (sync.ts:41) sits on an interface that is erased from the JavaScript and never reaches the declarations (grep exit 1). scripts/ablation-dist-preflight.mjs finds the head marker 「was measured to be so (commit 7d81c88)」 in those 4 files with a clean tree (exit 0).
  • Leg 2, the base text put back in repository.ts and sync.ts (proven equal to their base blobs d551426a7545 and 48798bcf7661, written to the tree only, 0 paths staged): 4 of the 6 files differ from leg 1 (index.js, index.cjs, index.d.ts, index.d.cts); the two sourcemaps do not. The preflight finds the base marker 「was measured to be so ([finding] SysMetadataRepository.close() cannot drain a filtered or numeric-since watcher — the pending next() never settles and the consumer's for-await hangs #11021)」 in the same 4 files (exit 0).
  • Leg 3, after the proven restore (equal to the HEAD blobs 888f39203432 and 122a45dcb516, git diff HEAD empty, porcelain empty): all 6 files are byte-identical to leg 1. The preflight's --absent reading of the base marker exits 0 with a clean tree. So the build is deterministic, and the difference is the rewrite.

So the rewrite ships. .changeset/20595-metadata-fs-provenance-anchors.md declares a patch for @objectstack/metadata-fs, comment text only, with the claim's Clause-②: no line. The anchor is a commit, so the changeset names no ADR, repository qualifier or bracketed substitution. It says which published files carry the reworded text, as measured above. The changeset commit touches no file under packages/metadata-fs.

Gates (head 32de59091)

  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at 32de59091 (4 paths against merge base 0fc80878f) derived 61 commands. All 61 ran (21:25:07Z to 21:36:22Z, after the workspace build), each exit code captured before any pipe: 61 exit 0. --ran reports 「61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero) and exits 0.
    • The dispatch's lead derivation (47 commands, one path) is a subset. The extra 14 are:
      • the eight 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;
      • check:type-check-coverage and check:type-check-debt;
      • four gates whose sources name the touched files: check:engine-double-contract, check:objectql-double-limit, check:query-options-erasure and check:where-matcher.
  • Named readings:
    • node scripts/check-issue-citations.mjs exits 0 (1 citation judged across 2 files: the carried-over #11127, which resolves).
    • pnpm check:issue-citations exits 0 (its 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 (10,001 files, no raw control bytes), and a control-byte grep over the 4 changed files finds none (exit 1).
    • The changeset gates exit 0: check-adr-0087-registration (「1 non-breaking changeset(s) seen」), check-empty-changeset (「1 declaring changeset(s) added」), check-changeset-no-major (「no major bump」), and check:changeset-gate-self-tests. The Clause-② level axis of check-changeset-no-major reads the pull request body, so it does not apply to a local run; that reading is CI's.
  • Build, tests and typecheck, under the verify lock, at 32de59091:
    • The workspace build (turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2): VERDICT command-exit 0, held 198s, shared-box seconds; 71 of 71 tasks, 20 cached.
    • The tests and typecheck: held 33s. pnpm --filter @objectstack/metadata-fs test: 10 test files pass, 70 tests pass (exit 0). pnpm --filter @objectstack/metadata-fs typecheck (tsc --noEmit and tsc --noEmit -p tsconfig.test.json) exits 0.
    • tsc --listFilesOnly puts every touched file in a program: repository.ts and sync.ts in both configs, and close-terminates-watch.test.ts in tsconfig.test.json, whose program holds all 10 test files.
    • No importing package owes a run, because the declaration files change only in comment text.
  • Lint, as a proven narrowing, at 32de59091:
    • eslint ran with inline config disabled (--format json) over the 3 touched files plus dist/index.js as the control.
    • 4 results: 0 errors, and 1 warning, which is the control's ignore notice. No touched file is reported ignored, and --print-config resolves a config for each.
    • eslint.config.mjs never enables type-aware linting (its lines 327 and 328 say so; --print-config shows no parserOptions.project and no projectService), 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 3, 2026 21:13
… that decided them

Three comment and docblock sites in packages/metadata-fs cited a tracker
number that now answers 404 (two census sites, in src/repository.ts and
src/sync.ts, and one test comment in test/close-terminates-watch.test.ts).
Each now cites commit 7d81c88, the change that made close() terminate
watch iterators instead of emitting a drain event, measured why the drain
event was the wrong shape, and wrote invariant 8 in metadata-core. The
live #11127 beside one of them stays. Comment text only; no line count
changes.

Claude-Session: https://claude.ai/code/session_017ErfyP2Rx7XWHJA27QjyUi
Co-authored-by: Claude <noreply@anthropic.com>
One of the two rewritten src lines (the FileSystemRepository.close()
docblock) reaches the published dist, in the declarations and in the
JavaScript esbuild emits, measured with a three-leg dist reading.

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

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/concepts/metadata-lifecycle.mdx (via FileSystemRepository (symbol, a top-level class))
What this run could not see
  • 1 changed file(s) yielded no anchor (packages/metadata-fs/src/sync.ts) — pages documenting those are invisible to this run
  • 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 — 1 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 5b5e83f446bde0bf6e13db304b9f07f115635704 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 5b5e83f446bde0bf6e13db304b9f07f115635704

⚠️ 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 5b5e83f446bde0bf6e13db304b9f07f115635704 → 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

ACCEPT — PR #21640 at head 32de59091a (#20595 stage 13, metadata-fs)

domain:engine#1 · session_017ErfyP2Rx7XWHJA27QjyUi · read at 2026-10-03T21:58Z. The os-dev report is on #20595 (5973858328). Judged against GitHub and the branch, not against the report.

  • Shape: draft, base main, assignee os-project-manager.
    • The first lines are Part of #20595 and Clause-②: no.
    • The closing-keyword scan finds nothing; the card's close-out is the seat's.
  • Scope: 4 files, +18/-3.
    • One comment line in each of repository.ts, sync.ts and test/close-terminates-watch.test.ts, all read in the diff, plus the changeset.
    • No tracker number is added. The live #11127 beside the sync.ts site is carried over unchanged; it answers 200 as a closed issue.
  • Anchor checked: #11021 → 7d81c889f, the anchor stages 1 and 9 chose for it.
    • 7d81c889f is fix(metadata-protocol): close() terminates watch iterators instead of emitting a drain event (#11021) (#11136).
    • That is the decision each of the three sentences describes: the drain-event measurement, invariant 8, and "the sibling defect".
  • Changeset, checked sentence by sentence:
    • '@objectstack/metadata-fs': patch and Clause-②: no.
    • "One of these docblocks sits on a public method (FileSystemRepository.close())" is true of repository.ts:230.
    • The rest matches the dev's three-leg dist reading: the reworded text reaches the published .d.ts / .d.cts and .js / .cjs, and the sourcemaps do not change. sync.ts:41 sits on an interface, which is erased.
    • "Comment only" matches the diff.
  • Clause-②: no — accepted. There is no path leg and no surface moves.
  • Census: metadata-fs 2 → 0, and the whole repo 119 → 117 on this branch's tree. The finding sets differ by exactly the two removed rows. Stage 12 has landed since (0a0debbe96), so with this PR this lane's census population reaches 0.
  • Evidence:
    • The token guard reports 0 token changes, with comment controls passing and identifier, string, template and numeric controls failing.
    • The metadata-fs suite passes 70 of 70, and typecheck exits 0.
    • dispatch-gates --ran reconciles 61 of 61.
  • Deviation 6 (a second relay dispatch for the report): accepted. The first run concluded failure with zero writes, and the card carries exactly one report comment, read back byte-identical.
  • CI on 32de5909, at this read: in progress. The seat lands only once every check is green or an expected skip.

After landing: the seat closes #20595 for this lane, as the dispatch's done-signal reads ("domain:engine packages 0").

  • What stays, by surface:
    • the 2 formula test-string sites;
    • the CHANGELOG.md lines, which are release-owned;
    • packages/lint's 9 test-comment lines, which belong to the spec lane.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 3, 2026 22:13
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 3, 2026 22:13
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 3, 2026
Merged via the queue into main with commit 1e4ae08 Oct 3, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20595-metadata-fs-citations branch October 3, 2026 22:50
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