Skip to content

docs(driver-sql): re-anchor the dead tracker citations to the commits and ADR that decided them (stage 4 of #20595) - #21357

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

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20595
Clause-②: no

What changed

Stage 4 of the domain:engine lane of the dead-citation sweep: packages/drivers/driver-sql/**, comment and docblock prose only, per the claim (5946343111). Stages 1 to 3 landed as a7d9768ec, d150c3039 and 4bf4e7e70; #20595 stays open for the next 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 291 sites on 287 lines in 54 files, covering 39 numbers, plus one dead comment-id citation on two lines:

  • 126 census sites (122 lines, 6 files under src/): the whole allocated-but-absent population of the gate's own census in this package at the base, the slash-joined #7737/#10629 and #14079/#15683/#17343 from the post-landing census (5923084795, now at sql-driver.ts:12236 and :16167) included. That census's third driver-sql site, the URL-spelled #17590 at :3933, left the file in 58a77dbde2 before this base;
  • 165 test-comment sites (165 lines, 48 test files), which the census defers. They carry 37 numbers: 24 the census itself reads as dead in this package's src, 5 more it reads as dead elsewhere in the repository, and 8 it never judges (they stand only in test files), which the board and a single read each settle;
  • the dead comment id 5448627494 (on [finding] AGGREGATION_ROWS has no boolean column, so the cross-driver aggregation conformance family cannot see a boolean aggregand on any face #11152, which is live), on two test-comment lines.

Anchors: 38 numbers by commit, 1 by ADR (ADR-0104's 2026-09-05 addendum), 0 by words alone; the comment id by commit. 16 numbers reuse the anchor another lane or stage already measured for them, 23 were measured here (one of them split across two commits), and the comment id was measured here. 39 distinct shas.

Only comments changed. Every file keeps its line count (291 lines out, 291 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, and the diff-scoped gate judged the 10 citations left on changed lines: all 10 resolve.

A patch changeset: 57 of the 122 rewritten non-test lines are in the published dist (the .d.ts keeps JSDoc on exported members, and esbuild keeps some comments in the JS), and dist is not byte-identical with the base text (see Changeset).

Census: driver-sql, 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/drivers/driver-sql/.

reading tree board whole-repo allocated-but-absent sites lines files numbers
before base 222ecc27f, run 05:52:18Z to 05:55:43Z enumerated, 192 pages, frontier #21345, 19,166 records (newest number read before and after the run: #21345) 456 126 122 6 26
after 286316ebd, run 06:17:50Z to 06:21:10Z enumerated, 192 pages, frontier #21352, 19,173 records (newest before: #21351, after: #21352) 330 0 0 0 0

The whole-repo drop is 126, and the two finding sets differ by exactly the 126 rows of this package, removed; none was added. resolves (34,789), resolves-as-pull-request (2,378) and cross-repo-unjudged (1,155) did not move. The card's 128 was taken at f11b5f20a2 with the older extractor; the base here reads 126. The head's later commits are a merge of main that touches no file under packages/drivers/driver-sql and 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 (238 .ts, package.json, tsconfig.json, README.md, CHANGELOG.md, LICENSE), and classifies each citation with the gate's classifyCitation against one board enumerated by the gate's enumerateBoard (192 pages, frontier #21346, 19,167 records, 05:56:41Z to 05:59:55Z). Every one of the 39 numbers in the population was then read on its own over the issues endpoint: all 39 answer 404, and the lit controls #5286 and #12624 answer 200.

reading citations dead src comment test comment test string changelog
before, 222ecc27f 4,920 411 126 165 51 69
after, working tree at 286316ebd 4,629 120 0 0 51 69

The drop of 291 citations is exactly the rewritten sites, and the live counts did not move (src comment: 1,352 resolve, 24 as pull requests; test comment: 1,545 and 69). A third, raw reading (every # followed by 2 to 6 digits, whatever surrounds it) counts 4,939 before and 4,654 after: a drop of 285, which is the 291 less the 6 URL-spelled sites that carry no #.

Comment ids. Nine distinct comment-id citations stand on 19 sites in this package (CHANGELOG.md aside). Each was read over the issue-comments endpoint: 5448627494 answers 404 (it was a comment on #11152, which itself answers 200), and the other eight answer 200 (5302931807, 5404884704, 5556979386, 5618311630, 5861435168, 5865693155, 5881556735, 5934879010; control 5946343111, 200). So the one dead id is in the population. 5642107998, the ruling record e04a0aff2's message names for #17590, also answers 404; it is not cited in this package.

Per-number table

src counts census sites, test counts test-comment sites. Every sha below matches exactly one commit (git rev-parse --disambiguate, count 1) and is an ancestor of the merge base 04f0cc499 (git merge-base --is-ancestor, exit 0 for all 39 shas; the clone is not shallow). The + lines introduce exactly these 39 nine-hex spans and no other. The message or the diff of each one names the number it replaces: 23 in the message and the diff, 11 in the diff alone (#11065, #11374 for d0e3a885b, #12978, #12999, #13015, #13324, #14438, #14628, #16649, #16711, #17586), 3 only in the subject's squash suffix (#6076, #14434, #17876, where the dead number was that pull request's own and the commit is its squash), and one exception, #10629, explained under Wordings to check. f6fa22ce1's diff names the comment id three times. Where a sentence credits a ruling, a measurement, a review or a note to the number, the anchor's own message or diff carries it (checked per site; the ones that needed a reworded sentence are listed below). source says whether another lane or stage already used this anchor for this number (reused) or it was measured here (measured).

number src test anchor kind source what it decided
#6075 1 3 d367f03d6 commit measured five drivers' query parameters follow DriverQuery
#6076 0 1 6513c1749 commit measured IDataDriver's query parameter becomes DriverQuery (that pull request's squash)
#8778 0 2 7901b2dd2 commit reused stamp-only tenancy.organizationField
#8823 0 3 4dfa369a9 commit reused drop the caller value MySQL inlines in its duplicate-entry diagnostic
#9542 5 6 8bbf45947 commit measured bound the metadata-lock wait on boot schema-sync's MySQL widening ALTER too, keeping boot's swallow
#10165 0 1 801296050 commit reused lifecycle ttl.onlyWhen row filter with the canonical null predicate
#10629 1 0 199ec4712 commit reused bind federated objects whatever the boot order (stage 3's anchor; the live #7737 carries the citation)
#10836 0 2 7ab286e44 commit measured live pg + mysql legs for the ttl.onlyWhen $null suite
#11065 0 1 20950404c commit reused count a boolean aggregand as 1/0 in avg and sum
#11067 10 10 479fba50d commit measured stamp updated_at when the driver never ran DDL
#11374 16 7 d0e3a885b + 107bb4ba4 commit measured emit varchar(maxLength) for a text field a declared index keys on / carry an over-long UNIQUE index on a hash-shadow column, the route the 2026-08-24 ruling chose
#12380 9 13 4045b954d commit reused make the SQLite Field.json codec injective, one encoding across all three dialects
#12978 0 2 e4902d2b9 commit reused declare sourced maxLength on the keyed text columns of the sys_notification_* objects
#12998 19 7 df1c75c4b commit measured hash-shadow UNIQUE indexes carry the NULL-safe organization key part (ADR-0120 D3)
#12999 3 1 ebcc34e89 commit measured name the real remedy when a bounded field sits over a stale TEXT column
#13015 17 6 cd1348802 commit measured a shadow-carried UNIQUE is not index drift, and its remedy dropped the constraint
#13279 1 1 6a180e42d commit reused fail loud when a permission-store read fails; it moved the classifier pins into driver-error-classification.test.ts
#13324 1 4 4cda78c9b commit reused require a missing-table error to name the table that was read
#14434 0 1 93940d492 commit measured declare the not-found arm on IDataDriver.update() (that pull request's squash)
#14438 1 3 2200f8ec8 commit measured update() publishes the contract's record-or-null, not any (the squash of PR #15280)
#14628 1 1 6392b9c2b commit measured budget the 8th live-cell hook, reached through rawDriver()
#14902 7 9 61821e54c commit reused a plain unique index over duplicate rows is loud and non-fatal (the squash of PR #15477)
#15041 2 5 ADR-0104, 2026-09-05 addendum ADR reused the media family's column holds the bare sys_file id; the step's abort requirement, its SQL sketch, and the generator as the side that does not move
#16570 0 5 b72226f48 commit measured declare the indexes key initObjects / registerObjectMetadata already read
#16609 1 5 78bc4ad58 commit measured findWithWindowFunctions presents its rows like every other read door, and the alias-collision ruling
#16619 2 1 45cfa1b88 commit measured canonical ISO-Z read presentation (that pull request's squash; its message records the contract review)
#16649 1 0 613bfbd3d commit reused register the remaining door: 'none' codes, re-registering MONGODB_MULTI_TENANT_UNSUPPORTED
#16657 0 1 5a95b0e93 commit reused read the dialect text out of cause for operator-facing records
#16711 2 5 7862fb711 commit reused object-definition parameters declare the keys they are read for
#16729 1 1 0f38ab084 commit reused an explicit tenancy opt-out survives a partial syncSchema re-registration
#17343 3 8 82cb69fed commit measured a multiple: true boolean column keeps its $contains membership filter
#17586 4 2 d46deba19 commit measured keep multi-valued boolean/toggle columns out of the read-coercion registry
#17590 5 20 e04a0aff2 commit reused compile $contains on a JSON column as a per-dialect MEMBERSHIP test; its message records the director's 2026-09-12 Ruling A
#17639 5 10 7c2c5aedd commit measured envelope the distinct() backend fault
#17690 4 8 be5c60291 commit measured eight more IDataDriver doors publish their declared return type
#17857 4 2 9ccc4179e commit measured attribute an unresolvable distinct() column to the clause the caller named
#17876 0 2 be5c60291 commit measured that pull request's squash, which installed the ContainsAny detector
#17879 0 4 eb9334915 commit measured measure the ContainsAny phantom-leg sweep across eight door pins
#17970 0 2 47e6601c5 commit measured collapse ContainsAny's distributivity so union-shaped doors assert
comment 5448627494 0 2 f6fa22ce1 commit measured the 2026-08-28 maintainer ruling: min/max over booleans answer numbers on every face, superseding #11249's false/true

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, PR #N to its squash commit, a URL @see to @see commit SHA), the form the landed stages use. These say more than the tag:

Sites left

  • In comments (src, test, vitest.config.ts): none.
  • String literals: 51 test-string sites, 24 numbers, 26 files (describe and it titles, assertion arguments): #11374 5, #12380 4, #17590 4, #17639 4, #12998 3, #13015 3, #16609 3, #17343 3, #17586 3, #17857 3, #11067 2, #14902 2, and 12 more once each. Every one of the 24 is in this stage's population, so the table above holds an anchor for each. Non-test strings carry none. Strings are outside this stage's surface.
  • Outside src: the release-owned CHANGELOG.md names dead numbers on 69 sites (31 numbers); left. package.json, tsconfig.json, vitest.config.ts, README.md and LICENSE cite no dead number.

Mechanical guard: no code token moves

The guard (stages 2 and 3's) compares base 222ecc27f against the working tree over all 55 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 (an empty block) 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 at the head: 165,798 base tokens, 0 files with a token change (exit 0).
  • Comment control (「which IS its value」 to 「which IS ITS value」, sql-driver.ts): 0 files changed (exit 0).
  • Positive control, an identifier (hashShadowColumnFor to hashShadowColumnForX, schema-drift.ts): DIFFER on both readings (exit 1).
  • Positive control, a string literal ('storage' to 'storageX' in FieldKeyClass, builtin-column-collision.ts): DIFFER on both readings (exit 1).
  • Positive control, a numeric literal (MEDIA_ID_MOVE_WIDTH = 2048 to 2049, media-column-move.ts): DIFFER on both readings (exit 1).

Each mutation went through scripts/ablation-replace.mjs (wrap mode, anchor hit 1 to 0, replacement 0 to 1) under a shell trap that restores by absolute path from HEAD. Each restore was proven equal to its HEAD blob (cd55a4ca44f3, 72e45a83968f, 86ebb324c1b6, fe0ce2c4d5bd), 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. The whole workspace was built first (turbo run build over ./packages/* and ./packages/*/*, 71 of 71 tasks, VERDICT command-exit 0). Then the package's own build (tsup plus check-dts-emitted) ran three times in one script under the shared verify lock (VERDICT command-exit 0):

  • Leg 1, at 02d2a034a: 6 dist files hashed. Of the 122 rewritten non-test lines, 57 appear verbatim in dist: 52 from sql-driver.ts, 3 from schema-drift.ts, 1 each from media-column-move.ts and dialect-emission-refusal.ts; in index.d.ts / index.d.mts (51) and index.js / index.mjs (52).
  • Leg 2, the base text put back in the 6 non-test files (6 of 6 proven equal to their base blob): 4 of the 6 files differ from leg 1 (index.d.ts, index.d.mts, index.js, index.mjs).
  • Leg 3, after the proven restore (6 of 6 equal to their HEAD blob, git diff HEAD empty): all 6 files are byte-identical to leg 1, so the build is deterministic and the difference is the rewrite.

So the rewrite ships, and .changeset/20595-driver-sql-provenance-anchors.md declares a patch for @objectstack/driver-sql, comment text only, with the claim's Clause-②: no line.

Gates (head fad95aff7)

  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at fad95aff7 (56 paths against merge base 04f0cc499) 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 roster families the derivation flags under a touched directory also ran, each exit 0: node scripts/check-changeset-fixed.mjs, pnpm check:authz-resolver, pnpm check:error-code-casing, pnpm check:filter-alias-parity.
  • Against the newer main: main moved six commits after the merge, none touching a file here. A probe tree at origin/main f9bcd08be with this diff applied derived 64 commands, the one addition being node scripts/check-dts-emitted.mjs --self-test (that script is unchanged across the range). It ran, exit 0, and --ran on the probe reports 「64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN」.
  • Named in the dispatch: node scripts/check-issue-citations.mjs exits 0 (「every citation this change adds resolves」, 10 judged across 6 files); 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,641 files, no raw control bytes).
  • Tests and typecheck, under the verify lock, at fad95aff7: pnpm --filter @objectstack/driver-sql test: 215 test files pass and 11 skip (226); 3,594 tests pass and 202 skip. The 11 skipped files are the live-dialect suites (PostgreSQL and MySQL cells), declared un-run locally; CI's Temporal Conformance (live PG + MySQL) job runs them. pnpm --filter @objectstack/driver-sql typecheck exits 0; tsc --listFiles puts all 226 tracked test files and all 55 changed files in its program.
  • Lint, as a proven narrowing: eslint with inline config disabled, over the 55 touched .ts files plus dist/index.js as the control: 56 results, 0 errors and 1 warning, the control's ignore notice; none of the 55 is reported ignored. eslint.config.mjs never enables type-aware linting (its lines 327-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

  • Base. The branch was cut at 222ecc27f and merged with main once, at 04f0cc499, before the gates (merge 02d2a034a, no conflict, no file under packages/drivers/driver-sql, and neither check-issue-citations.mjs nor dispatch-gates.mjs). Tests, typecheck and gates ran on the head after it. The net diff against main is the 55 rewritten files (+291/−291) and the changeset.
  • Two sentences now state something that is no longer true, and this stage changes only their citation. sql-driver-12998-shadow-null-safe-key.test.ts:266 says initObjects' parameter type does not declare indexes; b72226f48 declared it, and the citation now reads 「(the gap commit b72226f closed)」. sql-driver.ts:18142 says 「driver-sql: the platform-objects schema does not sync onto MySQL — unbounded string fields become TEXT, which MySQL refuses to index #11374's remaining half may still reshape the text side」; it was written on 2026-08-24 (c49afd0886), a day before 107bb4ba4 settled that half, and now reads 「the half commit d0e3a88 left open」. Comment accuracy, outside a citation sweep.
  • The token guard's first reading-1 run was wrong, and was replaced. It reported sql-driver.ts as DIFFER on reading 1 alone: an empty catch { } block has no child nodes, so its leaf text carried the comment inside it (// Pre-#12380 row: …). Reading 2 agreed with no change throughout. Reading 1 now re-scans such a leaf with trivia skipped; the real run and all four controls above are from the corrected guard.
  • Wording only: no line without a number was changed, except sql-driver-17639-distinct-fault-envelope.test.ts:206, listed above.

Generated by Claude Code

claude added 3 commits October 2, 2026 06:15
… and ADR that decided them (stage 4 of #20595)

Comment and docblock prose only, in ruling C+D's form C: every comment
site in packages/drivers/driver-sql that cited a tracker number answering
404 (39 numbers, 291 sites on 287 lines), plus the dead comment id
5448627494 (2 lines), now cites the ADR when one records the decision,
otherwise the commit in this repository that made it. Every file keeps
its line count; no code token, string literal or numeric literal moves;
no tracker number is added.

Claude-Session: https://claude.ai/code/session_017xfMoEjKUuSh2xYB8sCozp
Co-authored-by: Claude <noreply@anthropic.com>
57 of the 122 rewritten non-test lines ship verbatim in dist (index.d.ts,
index.d.mts, index.js, index.mjs); a base-text rebuild differs in those 4
of 6 dist files and a restored-head rebuild is byte-identical.

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

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-sql, touching 26 documentable anchor(s). ⚠️ 3 changed file(s) yielded no anchor (packages/drivers/driver-sql/src/dialect-emission-refusal.ts, packages/drivers/driver-sql/src/live-dialect-matrix.testkit.ts, packages/drivers/driver-sql/src/media-column-move.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

30 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json 96b12b589ff864c2500e231f0b31b10be69d2c54.

⛔ 4 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/drivers/driver-sql/src/dialect-emission-refusal.ts, packages/drivers/driver-sql/src/live-dialect-matrix.testkit.ts, packages/drivers/driver-sql/src/media-column-move.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 — 11 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 96b12b589ff864c2500e231f0b31b10be69d2c54 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 96b12b589ff864c2500e231f0b31b10be69d2c54

⚠️ 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 96b12b589ff864c2500e231f0b31b10be69d2c54 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: fad95aff731848bc407b300da2067aadc0c7a475
Local-runs: none

Inputs read, and nothing else: card #20595 (body and all seventeen comments: the two lane pointers, the post-landing census 5923084795, the stage-1 to stage-3 claims, dev reports, ACCEPTs and landing records, the stage-4 claim 5946343111, the stage-4 os-dev-report 5947116210), the stage-1 contract review 5939794396 on #21233 and stage 3's 5943182373 on #21268, ruling C+D (5749154545 on #19123), PR #21357 (body, the 56-file list, the commit list, the diff against its merge base), the anchors, ADR and files at the head through git show, git log, git grep, git rev-parse, git merge-base, git blame, git diff and one in-memory git merge-tree in a full (not shallow) clone, the issues endpoint for every number the diff removes or keeps, and the head's check-runs last. The dispatch order and the seat's own conclusions were not inputs.

① Derived judgments

Diff of record. The merge base of the head with origin/main (23365eaedf at read) is 04f0cc499, the commit the branch merged once at 02d2a034a. GitHub's diff for #21357 (56 files, +306/-291, 255 hunks) is byte-equal, index lines aside, to git diff 04f0cc499 fad95aff7. The merge commit brings no file under packages/drivers/driver-sql, nor scripts/check-issue-citations.mjs, nor scripts/pm/dispatch-gates.mjs. Three commits: 286316ebd (the rewrite, on 222ecc27f) and fad95aff7 (the changeset) each end in the model-free trailer pair; the third is the merge, which carries no trailer, the shape stage 3 landed with. Head repo equals base repo (not a fork). Judged RIGHT.

Accept set and public surface: nothing moves. Judged RIGHT, on this reading of the diff text: every -/+ line was paired in order within its hunk, 291 pairs across the 55 .ts files, no hunk unpaired, the 15 unpaired + lines being the changeset. In all 291 pairs the first differing character lies after a // on that line (none inside a URL scheme) or on a line whose first non-blank is * or /*, no pair has a */ before its change point, and the new line is a comment at that point too. The 26 pairs whose quote-character counts move are apostrophes or backticks inside comment prose (for example builtin-column-collision.ts:75, where the trailing // comment after the maxLength: 'storage' token is the only thing that changes; sql-driver.ts:20298 commit 4045b954d's message). Every .ts file keeps its line count: numstat additions equal deletions for all 55, and wc -l at 04f0cc499 and at the head agree for each. So no code token, string literal or numeric literal changes on this reading. The dev's parser-based guard (0 of 55 files on two readings, comment control at 0, identifier, string and numeric controls at DIFFER) is consistent with it; I did not re-run the guard. The line the guard's first reading-1 run tripped on, sql-driver.ts:20306 (// Pre-#12380 row: … inside an empty catch), is comment-only on this pass as well.

Sampled hunks: all 291 pairs were read as their -/+ pair; the ones named here are 34 across 17 files. sql-driver.ts:336 (the maintainer ruling on #15041 to the maintainer ruling in ADR-0104's 2026-09-05 addendum), :1185 and :1220 (#9542 to commit 8bbf45947), :5442 ([#17586] to [commit d46deba19]), :8414 ([#11067] to [commit 479fba50d], a method docblock), :11060 (that question is #17590's to that question belonged to the card commit e04a0aff2 closed), :11072 (the gap #17639 left FILED to the gap commit 7c2c5aedd left FILED, the live #11541 kept), :11247 (#17857's to commit 9ccc4179e's, #7929 kept), :12236 (the #7737/#10629 pair, below), :15845 (measured in the #16619 contract review to measured in the contract review commit 45cfa1b88 records), :16167 ([#14079/#15683/#17343] to [#14079/#15683, commit 82cb69fed]), :16692 ([#17590, director ruling 2026-09-12] to [commit e04a0aff2, director ruling 2026-09-12]), :18142 (below), :18166 ((#11374, #12999) to (commits d0e3a885b and ebcc34e89)), :18377 (maintainer ruling on #11374, to maintainer ruling recorded in commit 107bb4ba4, with 2026-08-24 on the next line), :18510 (The pre-#12998 to The older (before commit df1c75c4b)), :20298 (See the ruling recorded on #12380. to See the decision recorded in commit 4045b954d's message.), :20306; schema-drift.ts:420 (#11374/#11627 exist to end to #11627 and commit d0e3a885b exist to end), :451, :2458 and :2474 (the card's control sites, pre-#12998 to before commit df1c75c4b); dialect-emission-refusal.ts:66; live-dialect-matrix.testkit.ts:451; media-column-move.ts:9; sql-driver-11627-hash-shadow-key.test.ts:18; sql-driver-11635-boolean-aggregand-answers.test.ts:9 and sql-driver-11782-boolean-row-read-presentation.test.ts:36-:37 (the comment id); sql-driver-12998-shadow-null-safe-key.test.ts:266; sql-driver-15989-file-family-bare-id.test.ts:7 (the verbatim 「15041 应该改为实际 id 保存。选A,其他同意」 kept); sql-driver-17343-multi-valued-boolean-membership.test.ts:62 and :66 (@see URLs to @see commit 82cb69fed / @see commit e04a0aff2); sql-driver-17639-distinct-fault-envelope.test.ts:44, :49, :205 and :206 (the one numberless line, owns to owned, whose subject is the card named on :205); sql-driver-doors-declared-types.test.ts:6 (#14438 (PR #15280) to Commit 2200f8ec8 (PR #15280)); sql-driver-query-signature.test.ts:12 (after #6076 merged to after commit 6513c1749 landed); sql-driver-update-declared-null.test.ts:11 (#13878 / PR #14434 to #13878 / commit 93940d492). Every one is a comment-only rewrite in ruling C's form: an ADR where one records the decision, else a commit sha, a PR number only beside a sha. Judged RIGHT.

Anchors. The + lines introduce exactly 39 new nine-hex spans, the 39 distinct shas of the per-number table (be5c60291 serves #17690 and #17876; #11374 takes two), and no other. All 39 resolve with git rev-parse --disambiguate to exactly one commit each, and git merge-base --is-ancestor exits 0 against both origin/main and the merge base 04f0cc499 for all 39; the clone is not shallow. For 38 of the 39 numbers the anchor's message or diff names the number it replaces: 23 in the message body and the diff, 11 in the diff alone (#11065, #11374 for d0e3a885b, #12978, #12999, #13015, #13324, #14438, #14628, #16649, #16711, #17586), and 3 only in the subject's squash suffix (#6076, #14434, #17876), where the dead number was that pull request's own and the commit is its squash, exactly the body's split; f6fa22ce1's diff names the comment id three times. The one exception is #10629, judged next. PR numbers appear beside a sha only as a convenience (PR #15280 beside 2200f8ec8, PR #15477 beside 61821e54c, both answering 200 as pull requests), never as the citation. Judged RIGHT.

The #7737/#10629 pair, sql-driver.ts:12236. 199ec4712 (2026-08-12) is #7737's fix, bind federated objects whatever the boot order; its message names #7737 once and its diff eleven times, and never #10629; the message states the ruling the line paraphrases in its own words (OS_SKIP_SCHEMA_SYNC is a DDL flag while the federated binding is DDL-free; ObjectQLPlugin reconciles on kernel:ready). The line now reads the same ruling #7737 already made for FEDERATED objects (commit 199ec4712) — OS_SKIP_SCHEMA_SYNC is about DDL, and a binding that is DDL-free must not ride on it, stage 3's judged form (5943182373): the live #7737 (200) carries the citation, the dead number is dropped, the commit beside it is the ruling's in-repo record. Judged RIGHT.

The #11374 split. d0e3a885b (2026-08-23, emit varchar(maxLength) for a text field a declared index keys on) names #11374 fourteen times in its diff and adds explainUnkeyableTextColumn / boundedObject on eleven added lines; the 20 sites citing it describe the keyed-text rule, the shard path, boundedObject() and the named refusal (sql-driver.ts:11777, :11800, :12375, :13575, :14908, :18041, :18058, :18457, :19421; schema-drift.ts:420, :861, :2032; builtin-column-collision.ts:75; the 11794 and keyed-text-mysql suites). 107bb4ba4 (2026-08-25) carries move #11374's refusal pins to the non-unique case, a branch the ruling deliberately replaced and the prefix constraint the ruling rejected, which is the hash route; it carries no date, so the 3 sites that credit the 2026-08-24 ruling keep their date and read landed as / recorded in (sql-driver-11627-hash-shadow-key.test.ts:18, sql-driver-keyed-text-mysql.test.ts:104, sql-driver.ts:18377-:18378), stage 1's #9741 precedent. The other lanes' anchors for #11374 (e4902d2b9, f64668d3c, 3954fb7df) are bound declarations in service-messaging, plugin-audit/plugin-security and platform-objects, a different subject; the driver's own rule is d0e3a885b. Judged RIGHT.

The #17590 sites reworded in tense. e04a0aff2's message says Fixes #17590 and Route ruled by the director seat on 2026-09-12 (5642107998 …): Ruling A — $contains on a multi-valued / JSON column is a membership test, and nothing about distinct(); 5642107998 answers 404, so the commit is the ruling's only in-repo record. All 25 e04a0aff2 sites were read: the 18 that describe $contains take the tag in place (sql-driver.ts:16692, :17178, :17198; the 17343, 17590, 15683, 20987 and json-column-operator suites), and the 7 written while the card was open say the card commit e04a0aff2 closed, which owned the sibling divergence, if a card after commit e04a0aff2 rules that a json column should ANSWER a distinct read (both retirement clauses), the ruling commit e04a0aff2 records cannot move it, a verdict about the request that commit e04a0aff2 has not made, that question belonged to the card commit e04a0aff2 closed, Nothing here touches the card commit e04a0aff2 closed and the divergence commit e04a0aff2 ruled on the filter side. None credits the commit with a distinct() verdict. The verb on sql-driver-17639-distinct-fault-envelope.test.ts:206 (owns to owned) follows the card on :205 into the past tense; the sentence reads coherently at the head. Judged RIGHT.

The dead comment id 5448627494 to f6fa22ce1. The id answers 404; its card #11152 answers 200 and stays on both lines. f6fa22ce1 (2026-08-28) aligns min/max over booleans to the numeric domain per the 2026-08-28 maintainer ruling (option A, superseding #11249's false/true) on driver-sql result presentation among four faces, and its diff names the comment id three times. The two lines now read landed as commit f6fa22ce1 and keep the verbatim 「12745 A回,其他同意。」. Judged RIGHT.

#15041 to ADR-0104's 2026-09-05 addendum (7 sites, plus the changeset). docs/adr/0104-field-runtime-value-shape-contract.md at origin/main, ## Addendum (2026-09-05) (line 1027), names #15041 as its provenance with the maintainer's verbatim reply, and carries each claim the sites make: step 3a aborting on the first cell that is not a JSON string (media-column-move.ts:9, sql-driver-15989-file-column-move.test.ts:16-:17), the ALTER … USING sketch beside it (:16), The driver is the side that moves; the generator's VARCHAR(2048) and The generator changes nothing (sql-driver.ts:336), option A for the file family (schema-drift.base-type-mismatch.test.ts:367), and ### Sequencing item 2, the driver card #15989 (sql-driver-15989-file-column-move.test.ts:5, the live #15989 kept on :4). Ruling C's first rung applies and every site takes it. Judged RIGHT.

No new tracker number; live numbers stayed. For every pair, the numbers on the + line are a subset of the numbers on its - line: 0 added. 321 #N occurrences on - lines, 36 on +, net 285 gone, the dev's 291 sites less the 6 URL-spelled @see lines that carry no #; 39 distinct numbers removed, the per-number table exactly. Probed over the issues endpoint at my read: all 39 removed numbers answer 404; all 29 kept numbers answer 200, 27 as issues and 2 as pull requests (#15280, #15477, each beside its squash); the comment id 5448627494 answers 404; controls #5286, #12624, #20595 and #21357 answer 200. At the head no non-test file under src names any of the 39 numbers, and no URL-spelled #17343 / #17586 / #17590 remains; the census's third driver-sql site (sql-driver.ts:3933, the URL #17590) left the file in 58a77dbde2 on 2026-10-01, before this base, as the body says. Judged RIGHT.

Rewritten sentences stay true. Each sentence that credits a commit with a ruling, a measurement, a review or a note was matched against that commit: 8bbf45947 carries keeping boot's swallow and the escape from the swallow (sql-driver.ts:13034, :13219); 4045b954d carries the live 17/17 and 13/17 measurement and refuses to guess at the two that the pre-fix encoding made ambiguous, called a posture and not a ruling (:20298, sql-driver-12380-json-roundtrip.test.ts:409); 45cfa1b88 carries Contract review of PR #16619 (PASS WITH FINDINGS), FINDING-1 to FINDING-3 and the hand-made TEXT-affinity audit column (sql-driver.ts:15782, :15845; sql-driver-13973-canonical-iso-read-door.test.ts:472); eb9334915 is Fixes #17879, a measurement card whose message says both candidates were measured and the repair itself is not proposed here (sql-driver-distinct-filter-narrowing.test.ts:55, :70; sql-driver-update-declared-null.test.ts:54, :69); 9ccc4179e carries the attribution arm #17639 deliberately left filed (sql-driver.ts:11072); 613bfbd3d's diff re-registers MONGODB_MULTI_TENANT_UNSUPPORTED under the ruling as a deliberate reversal (dialect-emission-refusal.ts:66; the runtime lane's 44c917a47 is the vocabulary-gate half, a different subject); 6392b9c2b wrote the (#14628) budget line itself and names 13b520069's seven sites (live-dialect-matrix.testkit.ts:451, sql-driver-datetime-mysql-storage.test.ts:57); 7862fb711 carries each with a TS2353 negative control (sql-driver-16711-object-def-param-keys.test.ts:143); 7901b2dd2 is stamp-only tenancy.organizationField … Option A per the maintainer ruling on #8778 (sql-driver-tenant-scope.test.ts:519, :588); 78bc4ad58 carries The collision case is ruled and pinned … its value now stays raw (sql-driver-window-function-output.test.ts:191, :199); 61821e54c names both shapes that reach the plain path, tenancy: { enabled: false } and an explicit unique: 'global' (sql-driver-15479-shadow-plain-unique-duplicates.test.ts:56, :186); b72226f48 adds indexes?: any[] to initObjects (:331, :4); be5c60291's diff adds the ContainsAny type (:56, :55); 47e6601c5 is collapse ContainsAny's distributivity; d367f03d6 and 6513c1749 are the #6075 and #6076 squashes. Nothing overclaimed. Three actor shifts named, none an overclaim: sql-driver-diagnostic-value-probe.test.ts:11 says Commit 4dfa369a9 found one family, where the card found it and the commit redacted it; sql-driver-doors-declared-types.test.ts:6 says Commit 2200f8ec8 (PR #15280) … filed the census, the pull request's act with its live number kept beside the sha; sql-driver-16711-object-def-param-keys.test.ts:143 and sql-driver.ts:12268 say the card commit 7862fb711 closed / the card behind commit 7862fb711, which the commit's message does not state but its diff does, naming #16711 on 32 lines across three test files named for the card and its changeset.

Reach into dist, which decides the changeset. Not rebuilt here. From the tree at the head: the package's files is dist, README.md, CHANGELOG.md, no private field, build is tsup --config ../../../tsup.config.ts plus check-dts-emitted; the root tsup.config.ts sets entry src/index.ts, dts unless OS_SKIP_DTS, formats esm and cjs, no minify, so the .d.ts emission keeps the JSDoc on exported declarations; src/index.ts exports SqlDriver and three functions from sql-driver.ts plus dialect-emission-refusal.ts's surface, and the sampled sql-driver.ts sites are method docblocks on that class. The 122 rewritten non-test lines are 101 in sql-driver.ts, 17 in schema-drift.ts and 1 each in the other four src files, the dev's six. The dev's three-leg measurement (57 of 122 verbatim in index.d.ts / index.d.mts / index.js / index.mjs; base text rebuilt differs in 4 of 6 files; restore byte-identical, 6 of 6) is consistent with that and is read, not reproduced. A changeset is owed. Judged RIGHT.

② Semver level

.changeset/20595-driver-sql-provenance-anchors.md at the head: frontmatter '@objectstack/driver-sql': patch; a summary line; Clause-②: no bare at the start of its own line (line 7), the shape scripts/pm/clause2-line.mjs, the fleet's one reader of that line, accepts; prose naming ADR-0104's 2026-09-05 addendum, the reach into index.d.ts / index.d.mts and the esbuild-kept JavaScript comments, and Comment only: no export, type, error code, status, message text or runtime behaviour changes. patch is the right level: nothing authorable, exported or on a payload moves, so no breaking marker and no ADR-0087 disposition is owed, and Clause-②: no is the right arm. No skip-changeset label (labels: documentation, size/l, tests, tooling). The PR body's first line is Part of #20595 with no closing keyword, and its second is Clause-②: no. Check Changeset and Part-of PR must not also close its card read success at the check-run read below. Judged RIGHT.

③ Boundary flags

  • Deviation (1), the one no-number line (sql-driver-17639-distinct-fault-envelope.test.ts:206). Judged in ①. Accepted.
  • Deviation (2), main moving six commits after the single merge, and the probe. Understated in one respect, which does not change the verdict: of the six commits to f9bcd08be, none touches a file in this diff or check-issue-citations.mjs, as the dev says, but 57c9fe39bc (06:11Z) edits scripts/pm/dispatch-gates.mjs itself (its self-test specimen moves off check-dts-emitted.mjs because ci.yml's Build Core began running that checker's --self-test). That is why the probe tree derived 64 commands and not 63: the derivation moved, not the tree; check-dts-emitted.mjs is unchanged across the range, as the body says. The probe carried 57c9fe39bc, the extra command ran, exit 0, and --ran on the probe reads 64/64/0/0, so the derived set the queue's rebuild will meet is covered. Since then origin/main has moved two more (96b12b589f, 23365eaedf); no file under packages/drivers/driver-sql moved on main after 04f0cc499, and an in-memory git merge-tree --write-tree origin/main fad95aff7 reports no conflict (mergeable: true at the PR read). The queue rebuilds onto main. Accepted.
  • Deviation (3), the token guard's corrected reading 1. Disclosed, replaced, and the replacement's 0 of 55 agrees with my text reading, including the empty-catch line that tripped the first run. Accepted.
  • Deviation (4), the detached runs with recorded PIDs and a foreground wait, each verdict read from its own log. Process, not substance. Accepted.
  • Deviation (5), the model-free trailer pair. Both authored commits end in Claude-Session: and Co-authored-by: Claude; the merge commit carries none, as stage 3's did; the PR footer is the session-URL form, right for a body. Accepted.
  • Deviation (6), tsc --listFiles outside the verify lock. A read of the program's file list. Accepted.
  • open_questions: none declared, none found.
  • The two now-untrue sentences recorded in Acceptance notes. Both confirmed stale at the head: sql-driver-12998-shadow-null-safe-key.test.ts:264-:266 still says initObjects' parameter type does not declare indexes, and b72226f48's message says it added indexes?: any[] to initObjects; sql-driver.ts:18142-:18143 still says the half d0e3a885b left open may still reshape the text side, and git blame puts the sentence at c49afd0886 (2026-08-24), a day before 107bb4ba4 settled it. This stage changed only their citations, which is right for a citation sweep: rewriting the claims would be comment accuracy, outside the claim's surface and ruling C's form. Not a FAIL. Escalated to the seat as a comment-accuracy item, carrier: the next driver-sql comment-prose touch, as the stage-3 census-figure sentence was carried.
  • The 51 test-string sites (24 numbers, 26 files). At the head the 39 numbers stand 51 times in *.test.ts files, in describe / it titles and assertion arguments (sampled), in 26 files, the body's count exactly; non-test src files carry none. Outside this stage by the claim's own words (no string literal), and every one of the 24 numbers has its anchor in this PR's table. Correctly left. Carrier, as stages 1 to 3 recorded: this card, a later stage whose claim widens to test strings. Escalated to the seat as the standing carrier question, not a FAIL.
  • The CHANGELOG.md sites. The 39 numbers stand 65 times in packages/drivers/driver-sql/CHANGELOG.md at the head (the body's 69 sites over 31 numbers include numbers outside this population). Release-owned under the Documentation Guardrails; never edited in a code PR, and no CHANGELOG.md is in the file list. Correctly left. Dropped.
  • The dead ruling record 5642107998 (named in e04a0aff2's message for driver-sql: the $contains MEMBERSHIP spelling on any multi-valued / JSON column is a DATABASE_ERROR 500 on live PostgreSQL (SQLSTATE 42883, operator does not exist: json ~~ text) — it has only ever been executed on SQLite #17590) answers 404 and is cited nowhere in this package; the sites that credit the 2026-09-12 ruling cite the commit, whose message carries the ruling's content. Noted, nothing to do here.
  • Governance and size. The file list touches no governed surface (docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md, docs/NORTH-STAR.md); Governed Surface Queue Guard reads success; 597 changed lines, under the 5,000-line class; head repo equals base repo; draft, auto-merge not armed. This record is the dispatch's adversarial review, not a Prime Directive 14 tier record.
  • Check-runs on the head, read last, at 2026-10-02T07:17:21Z. 33 runs: 26 completed/success, 3 completed/skipped (Build Docs, Console Pin Gate, Packed-tarball smoke (opt-in), all three roster names in scripts/pm/check-expected-skips.mjs), 4 in_progress with no conclusion: Lint & Repo Gates, Test Core (3/6), Test Core (5/6), Test Core (6/6). Of the seven required contexts by exact name: TypeScript Type Check (07:11:50Z), Dogfood Regression Gate (07:10:29Z), Build Core (07:06:51Z), Temporal Conformance (live PG + MySQL) (07:11:25Z) and Governed Surface Queue Guard (07:03:32Z) read success; Lint & Repo Gates is in progress and not yet a verdict; no run named exactly Test Core was present at read, its shards 1, 2 and 4 reading success and 3, 5 and 6 in progress, so that context is not yet a verdict either. Also success: Check Changeset, Check PR Size, Part-of PR must not also close its card, The card this PR closes must claim this branch, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Dogfood Verify CLI, the four Type Check · jobs, the three Dogfood Regression Gate shards, Auto Label, Check Documentation Links, Flag docs affected by code changes, filter. An in-progress required job is not a verdict and does not by itself make this record FAIL; the seat confirms the green bar from the merge bar before enqueue.
  • Local-runs: none, spelled out. Reads only: GitHub GETs (the card, its comments, the two prior review records, the ruling, the PR, its files and diff, the issues and comments endpoints, the check-runs); git fetch, git show, git log, git grep, git rev-parse, git merge-base, git blame, git diff and one in-memory git merge-tree in the main clone (no worktree, no checkout); a text pairing pass over the downloaded diff and the number probes, both from the scratch directory. No build, test, gate or ablation was run or re-run; every guard, census, dist and gate figure above is the dev's, read and judged for consistency, not reproduced.

Implemented-by: claude/issue-20595-driver-sql-citations
Reviewed-by: session_017xfMoEjKUuSh2xYB8sCozp

VERDICT: PASS


Generated by Claude Code

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/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants