Skip to content

docs(service-datasource): re-anchor the dead tracker citations to the commits that decided them - #20693

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20596-service-datasource-citations
Sep 29, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20596-service-datasource-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20596
Clause-②: no

What changed

This is the fifth stage of the domain:services lane of the dead-citation sweep. It covers packages/services/service-datasource/src/** and nothing else. By the seat's fresh census at the claim (5894843429), it is the largest package in the lane that no in-flight work holds. Later stages cover the other packages, so this PR says Part of and the card stays open.

Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 4 (PR #20609 as 422db788a, PR #20626 as b80ab579d, PR #20634 as 4d04b6be3, PR #20658 as 9a4b2bb38). That is 75 sites on 74 lines in 23 files, covering 16 numbers:

  • 44 census sites (every census site this package has);
  • 31 sites in test comments, which the census defers.

Each rewritten line now cites the commit in origin/main history that decided what the line describes, and says in its own words what was decided: 17 distinct shas. #8696 was one card fixed in two halves, so its lines cite the half they describe: the mysql DSN branch (72050cc47) or the mongodb DSN branch (90a12fb18). PR #8588 was itself a pull request, and it now cites its squash commit 3dede582b. No number in this package has an ADR or ruling record of its own in the repository (a grep of docs/adr/ for all 16 finds none), so every anchor is a commit, per ruling C's order. No number was dropped.

Only comments changed. Every touched source file keeps its line count (78 lines out, 78 in, over 23 files), so no line citation into these files moves. 4 of those 78 lines hold no dead citation; they are reflow, listed under Wordings below. No code token moves (see the guard below).

No citation number is added. Every tracker number on an added line was already on the line it replaces: the only one is #12482, which resolves and stood on datasource-connection-service.ts:101 before. Over the whole diff, added minus removed is 0 or negative for every number, and no number is new to the diff. No PR number stands on an added line.

Thirteen dead sites are left on purpose, all of them test titles (see the list below).

One more file: a patch changeset for @objectstack/service-datasource, because the rewritten docblocks ship (see Changeset below).

Census: service-datasource, before and after

Instrument (A1). The gate's own node scripts/check-issue-citations.mjs --census --json, read-only and unchanged. The count below is its allocated-but-absent findings under packages/services/service-datasource/. Each run counts as a reading only because its board frontier equals the newest issue number, read by a separate request just before and just after the run.

reading tree board whole-repo allocated-but-absent service-datasource sites lines files numbers
before base 6981abfd2, run 2026-09-29T17:02:34Z to 17:06:27Z enumerated, 186 pages, frontier #20684 (newest #20684 before and after), 18,511 numbers 1,318 44 43 9 14
after head f5ec6bacd, run 17:18:37Z to 17:22:33Z enumerated, 186 pages, frontier #20686 (newest #20686 before and after), 18,513 numbers 1,274 0 0 0 0

The before count matches the seat's census at the claim (44 sites in 9 files, at 6bff748b). The whole-repo drop is 44, exactly this diff's census sites. The resolves tally is 32,909 in both runs, and resolves-as-pull-request (1,984) and cross-repo-unjudged (994) did not move either. The after run was taken on f5ec6bacd; the head 265dc6861 adds only the changeset. No run was truncated or discarded: all four enumerations in this stage (two census runs and the two supplementary boards below) read 186 pages at the newest frontier.

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 service-datasource/src (61 files). It uses one board for both trees, enumerated by the gate's own enumerateBoard at 17:22:42Z (186 pages, frontier #20686, equal to the newest).

reading citations dead src comment test comment src string test string
before, 6981abfd2 791 88 44 31 0 13
after, f5ec6bacd 716 13 0 0 0 13

Its src-comment column equals the census's 44, which is the control on the second instrument. The 646 resolving and 57 pull-request citations are the same in both readings, and the drop of 75 citations is exactly the rewritten sites. An earlier board (17:07:08Z, frontier #20685) gave the same base reading. A third, raw reading (every # followed by digits, judged against the same board, whatever surrounds it) finds 88 dead occurrences before and 13 after, and its residue equals the gate's residue site for site.

Per-number table

Sites and files count every dead occurrence in scope at the base (comments and strings, tests included). rewritten / left counts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject.

number sites / files rewritten / left anchor: what it decided
#6268 6/4 6/0 68f5eccb1: the libSQL/Turso host loader gets one owner (@objectstack/runtime), and MissingDriverPackageError becomes one class across both hosts, because serve.ts decides fatality with instanceof. The cli and runtime stages' anchor
#6345 9/5 9/0 e2798fab7: one driver vocabulary; mongo renamed to mongodb, turso made a full builtin with a contract, and this factory's dispatch made exhaustive. The spec stages' anchor
#8588 1/1 1/0 3dede582b: external.credentialsRef (and only it) allowed on schemaMode: 'managed'; #8588 was that pull request, and this is its squash commit
#8696 13/4 10/3 two halves: 72050cc47, a bound credentialsRef reaches the mysql client on the DSN branch as { uri, password } (5 sites); 90a12fb18, the mongodb DSN branch carries it in options.auth beside an unmodified url (5 sites). The spec stage's anchor for the mongo half
#8873 8/3 7/1 096106522: a bound credentialsRef reaches the postgres SERVER on the DSN branch; connectionString is dropped and pg gets its own parse of the url with the credential attached. The spec stage's anchor
#8874 9/2 7/2 d70428ae7: a declared ssl reaches the mysql client on both branches, in the spelling mysql2 accepts ({}, never true). The spec stage's anchor
#8876 1/1 1/0 d634e665b: urlUserinfoUsername exported, the username half of the shared URL userinfo grammar. The spec stage's anchor
#9040 4/3 2/2 24206416a: a credential in the mongo options passthrough (config.options.auth.password) is refused at publish. The spec stage's anchor
#9041 2/2 2/0 d491625c1: a bound credentialsRef with a user-less mongo config.url is refused at the one door that sees both halves. The spec stage's anchor
#10537 3/2 3/0 e634ecf6a: POST /external/validate scoped to the URL's datasource; it adds validateDatasource. The rest and runtime stages' anchor
#10962 5/2 4/1 29d067646: one live introspection per datasource per validation sweep, memoised per call and never per instance (its message names #10962)
#11166 5/1 4/1 735f5c709: an unreachable remote is the new unreachable diff kind, not missing_table. The runtime stage's anchor
#12010 9/5 8/1 77b91bdb4: ConnectionEngineLike derived from the engine contract, and registerDriver stops promising it accepts any value. The runtime stage's anchor
#12248 1/1 1/0 8425c17cc: the ruled engine members adopted onto IDataEngine, the datasource-lifecycle trio among them. The spec stage's anchor
#12943 3/2 3/0 090f2302e: the guarded optional-driver loads declared as optional peers of this package. The cli and runtime stages' anchor
#13279 9/4 7/2 6a180e42d: a failed permission-store read raises AuthzStoreUnavailableError (503) instead of reading as zero grants; its message carries the 2026-08-30 ruling, and it moved driver-error-classification.ts into @objectstack/types. The anchor of stage 2 and of the rest, runtime and types stages

Every cited sha matches exactly one commit (git rev-parse --disambiguate, count 1 for each of the 17), and every one is an ancestor of the base (merge-base --is-ancestor, exit 0 for all 17; the history is complete, --is-shallow-repository false, 15,110 commits). Where an earlier stage already anchored a number, this stage reuses that anchor after checking it against this package's lines. New to the sweep here: 72050cc47 (the mysql half of #8696), 3dede582b and 29d067646.

Wordings to check

The 13 sites left

  • Test titles, 13 sites. describe / it titles, which are string tokens, left as stages 1 to 4 left theirs: admin-routes-authz-outage-envelope.test.ts:158 (#13279); admin-routes-tenancy-posture-admission.test.ts:557 (#13279); bound-secret-dsn-branches.test.ts:136, :244 (#8696); connection-engine-like-contract.test.ts:21 (#12010); datasource-config-redaction.test.ts:406 (#9040); datasource-credential-migration.test.ts:226 (#9040); external-datasource-service.test.ts:453 (#11166), :690 (#10962); mysql-dsn-ssl.test.ts:165, :324 (#8874), :260 (#8696); postgres-dsn-bound-secret.test.ts:160 (#8873).
  • There is no operator string, assertion message, generated header or quoted ruling carrying a dead number in this package. The verbatim maintainer quotations in scope (「同意」 and 「同意所有」, on 8 lines) carry no dead number and are untouched.

Mechanical guard: no code token moves

The guard compares the TypeScript parser's leaf nodes, with comments as trivia and JSDoc nodes never visited, base 6981abfd2 against head. Template literals are therefore read in context. It ran over all 23 touched .ts files.

  • Real run: 24,055 base leaf tokens, 0 files with a token change (exit 0).
  • Comment control in default-datasource-driver-factory.ts (Lazy + caught exactly like to Lazy and caught exactly like): 0 files changed, as expected (exit 0).
  • Positive control, a code token added in default-datasource-driver-factory.ts (const url = resolveTursoUrl(spec); given a trailing ?? undefined): DIFFER (exit 1).
  • Positive control, one digit changed inside a kept test title (mysql-dsn-ssl.test.ts:165): DIFFER (exit 1).

Every mutation went through scripts/ablation-replace.mjs, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (8c164aa6178f, 2feeaeb0411d), with git diff HEAD empty and a clean tree afterwards. A first draft of the guard used the bare scanner, which loses template context and reported token changes inside comments; it was replaced by the parser walk before any reading was taken from it.

Changeset

This change ships bytes, so a patch changeset for @objectstack/service-datasource (.changeset/20596-service-datasource-provenance-anchors.md) is included. It says only that the provenance comments were re-anchored, in stages 3 and 4's words.

Measured on the built package (A3): files[] is dist, README.md and CHANGELOG.md. After the build, the rewritten comments reach dist: 6a180e42d, e2798fab7 and e634ecf6a once, and 29d067646 three times, in each of dist/index.d.ts, index.d.cts, index.js and index.cjs; 68f5eccb1 4 times, 090f2302e twice, and 77b91bdb4 and 8425c17cc once each, in both declaration files. Positive control: the unchanged line 「registerDatasourceDef, markDatasourceUnavailable,」 beside the shipped rewrite at datasource-connection-service.ts:95 is found once in index.d.ts. A never-written negative phrase appears nowhere in dist. No dead number of the 16 is left anywhere in dist.

Gates (head 265dc6861)

  • Citation judging, as CI runs it: pnpm check:issue-citations (self-test) exits 0. node scripts/check-issue-citations.mjs exits 0: the diff-scoped run judged 1 citation (#12482), and it resolves.
  • Doc authoring: pnpm check:doc-authoring exits 0, with the sibling-package prose ids at their baseline and no growth.
  • Derived gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 265dc6861 derived 63 commands: all 54 derived at dispatch, plus check:duration-unit-keys, check:dispatcher-error-vocabulary, check:engine-double-contract, check:logger-receiver-detach, check:objectql-double-limit, check:query-options-erasure, check:type-check-coverage, check:type-check-debt and check:where-matcher. Each ran with its exit code captured before any pipe, and all 63 exit 0. --ran, fed each command with its exit code, reports 63 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0. A full turbo run build of ./packages/* and ./packages/*/* ran first under the shared verify lock (71 of 71 tasks, exit 0), so no gate hit an unbuilt workspace.
  • Roster families the derivation lists outside its commands (their rosters sit in directories this diff touches): node scripts/check-changeset-fixed.mjs, pnpm check:authz-resolver, pnpm check:error-code-casing and pnpm check:filter-alias-parity, each exit 0.
  • Tests and typecheck, under the verify lock:
    • pnpm --filter @objectstack/service-datasource test: 34 files pass and 693 tests pass. That is every test file in the package, the 14 touched ones included.
    • pnpm --filter @objectstack/service-datasource typecheck exits 0. Its tsconfig.json includes all of src, and --listFiles shows all 61 files under src/, the 34 test files included, and all 23 touched files in the program.
  • Lint, as a proven narrowing: eslint --no-inline-config --format json over the 23 touched .ts files gives 23 files, 0 errors and 0 warnings. All 23 are in eslint's own population (isPathIgnored is false for each). eslint.config.mjs never enables type-aware linting (no parserOptions.project, as its own lines 327-328 state), so a comment edit here cannot move the verdict on any untouched file. The repo-wide pnpm lint is CI's run.
  • Control bytes: pnpm check:nul-bytes exits 0, and a raw scan of the 24 changed files for control bytes finds none.

Acceptance notes

  • The gate-invisible spellings, grepped as the claim asked. CITATION_RE refuses a hyphen after the digits and a / before the # (check-issue-citations closeout (extractor spellings): CITATION_RE refuses a hyphen after the digits, so a dead #N-word citation (#13398-class) is invisible to the diff gate and to the census #20636). In this package there is no #N-word spelling at all. There are 7 #A/#B lines (admin-routes.ts:28, datasource-route-ledger.ts:159, turso-driver-config.ts:132, external-introspection-seam.test.ts:14, :102, :163, turso-bound-secret-authoring.test.ts:8), and every second number on them is live: #10998, #4251 and #4249 are issues, and #8078, #4176 and #4202 are pull requests. So nothing there needed rewriting. The raw scan above, which sees both spellings, agrees.
  • The census instrument did not truncate in this stage. Four enumerations read 186 pages each at the newest frontier.
  • Anchors the next stages can reuse, each checked here: #13279 → 6a180e42d; #12010 → 77b91bdb4; #6345 → e2798fab7; #6268 → 68f5eccb1; #12943 → 090f2302e; #8696 → 72050cc47 (mysql) or 90a12fb18 (mongodb); #8873 → 096106522; #8874 → d70428ae7; #10962 → 29d067646.
  • Base. The branch is 5 commits behind origin/main (14f80e239, read at 17:27Z). None touches service-datasource, scripts/ or .changeset/config.json, so there was no merge.

Generated by Claude Code

… commits that decided them

Every comment and docblock site under packages/services/service-datasource/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 (ruling C+D, form C): 75 sites on 74 lines
in 23 files, 16 numbers, 17 commits, plus 4 reflow lines. Comments only; every
file keeps its line count, and no citation number is added.

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
Co-authored-by: Claude <noreply@anthropic.com>
The rewritten docblocks ship in dist (index.d.ts / index.d.cts, and the
runtime bundles for the ones tsup keeps), so the released package changes
bytes and owes a patch changeset.

Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H
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

8 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ⚠️ 3 changed file(s) yielded no anchor (packages/services/service-datasource/src/datasource-pool-support.ts, packages/services/service-datasource/src/missing-driver-package-error.ts, packages/services/service-datasource/src/turso-driver-config.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
  • 3 changed file(s) yielded no anchor (packages/services/service-datasource/src/datasource-pool-support.ts, packages/services/service-datasource/src/missing-driver-package-error.ts, packages/services/service-datasource/src/turso-driver-config.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 — 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 14f80e23957165f6fb23c2b3d59bdc7668652dfb → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 14f80e23957165f6fb23c2b3d59bdc7668652dfb

⚠️ 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 September 29, 2026 18:16
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 0e9ad74 Sep 29, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20596-service-datasource-citations branch September 29, 2026 18:35
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