Skip to content

refactor(driver-sql): move the autonumber sequence path out of sql-driver.ts into sql-driver-autonumber.ts (#25521 cut 11) - #26322

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-r8r6to
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-r8r6to

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Part of #25521
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Ruling-ref: 6348891160

Cut 11 of the sql-driver.ts split (#24586 ruling A, recorded in 6270097840). The claim is 6424911800. The cut opens with a fresh seam table (below), taken on origin/main after cut 10 merged, and takes the area that pays best without breaking a series limit. The bodies of six SqlDriver methods move unedited into a new seam module, packages/drivers/driver-sql/src/sql-driver-autonumber.ts, through a new host, AutonumberHost. Together they are the autonumber sequence path:

The change is move-only, and the card stays open for later cuts. There is no docs/adr/** edit, no packages/spec/** edit, no anchor entry change and no new gate. Branch claude/project-thread-r8r6to (the platform assigned it to this card thread, as the claim records). One commit, 69181bf14, on origin/main 817cb8983 (cut 10's merge).

Net line count (the seat's rule). sql-driver.ts goes from 21,018 lines to 20,827: -191.

  • Out: the six bodies, 248 lines (79 + 61 + 51 + 21 + 11 + 25), and the two import lines of isUniqueViolationError and uniqueViolationColumn, whose last reader moved. Three more such names (renderAutonumber, readAutonumberCounter, missingFieldValues) leave a line that stays.
  • In: the six stub bodies, 54 lines (13 + 9 + 11 + 2 + 7 + 12, each 4 + 2 per field read + 1 per method read; maxAutonumberCounter reads no member, so its stub is a comment and a direct call), and 5 lines for the new import and its comment.
  • Priced before the move at -194 for the bodies alone.
  • The new module is 367 lines.

Serial with the file's in-flight PRs. I read the full file list of every open PR at start (36 PRs, on cut 10's head) and again after cut 10 merged, before the first edit (28 PRs). No open PR touches sql-driver.ts, turso-driver.ts, the CRUD section, check-tenant-chokepoint.mjs or the driver-sql anchor entries.

Seam table, fresh, on 817cb8983

origin/main is at 817cb8983, after cut 10 (#26287) and #26261.

  • Size and churn. sql-driver.ts is 21,018 lines. 30-day lines are git blame lines from commits on or after 2026-09-26T19:27:54Z, 30 days before the base commit. History reaches 2026-09-15, and scripts/pm/git-history.mjs count proves 71 commits on the file in that window (29 in the last 7 days). In all, 3,523 lines (16.8%) are from the last 30 days.
  • Class shape. SqlDriver spans lines 5591-20943 with 350 members: 243 instance methods (49 public), 13 accessors and 32 statics, all 32 of them private or protected. 30 of the instance methods are already stubs from cuts 1-10.
  • Inferred return types. One public member has one: the supports getter, in the class head.
  • How it was measured. A TypeScript compiler AST script, which strips casts, parentheses, ! and satisfies before it reads this. Sections are the class's own banner comments (// === blocks and // ── sub-banners), as cuts 9 and 10 cut them, with the docblock heading "The sequence semantics a second face shares" folded into CRUD.
Lines Section First … last member Lines 30-day Methods (public) Inferred public getBuilder sites Statics (private/protected)
1-5590 Module preamble - 5,590 843 - - - -
5591-7182 Class head: fields, statics, constructor, capability getters name … assertDialectEmits 1,592 290 8 (1) 1 0 18 (18)
7183-7614 Lifecycle connect … disconnect 432 155 8 (3) 0 0 6 (6)
7615-10319 CRUD — IDataDriver core find … delete 2,705 739 43 (7) 0 12 0 (0)
10320-10931 Bulk & Batch Operations bulkCreate … count 612 119 9 (6) 0 7 0 (0)
10932-11028 Raw Execution rawStatementFault … noteRuntimeIndexDdl 97 28 3 (1) 0 0 0 (0)
11029-11121 Transactions beginTransaction … rollbackTransaction 93 46 7 (5) 0 0 0 (0)
11122-11653 Aggregation aggregate … unresolvableAggregateColumnRefusal 532 60 5 (1) 0 1 0 (0)
11654-11941 Distinct distinct … unresolvableDistinctColumnRefusal 288 17 3 (1) 0 1 0 (0)
11942-12057 Window Functions findWithWindowFunctions … findWithWindowFunctions 116 4 1 (1) 0 1 0 (0)
12058-12156 Query Plan Analysis explain … analyzeQuery 99 1 2 (2) 0 1 0 (0)
12157-12215 Schema Sync (syncSchema / init) syncSchema … reclaimSpace 59 34 3 (3) 0 0 0 (0)
12216-13957 Schema Sync (syncSchema / init) › Data-lifecycle rotation (ADR-0057 P2) rotationStateByTable … migrateMysqlTimeColumns 1,742 72 26 (4) 0 0 0 (0)
13958-14214 Schema Sync (syncSchema / init) › Deferred schema DDL (#3917) setDeferredDdl … flushDeferredSchemaDdl 257 25 6 (4) 0 0 0 (0)
14215-15029 Schema Sync (syncSchema / init) › Managed-schema drift & reconcile (#2186) dialectName … createNullSafeUniqueIndex 815 237 23 (3) 0 0 0 (0)
15030-15081 Schema Introspection listPhysicalColumns … introspectSchema 52 46 2 (2) 0 0 0 (0)
15082-15352 Internal helpers getKnex … auditMissingTenant 271 73 8 (1) 0 1 0 (0)
15353-17793 Internal helpers › Filter helpers tableNameForBuilder … applyFalseConstant 2,441 438 44 (2) 0 0 0 (0)
17794-17969 Internal helpers › Field mapping mapSortField … mapAggregateFunc 176 2 6 (0) 0 0 0 (0)
17970-18017 Internal helpers › Window function builder buildWindowFunction … buildWindowFunction 48 26 1 (0) 0 0 0 (0)
18018-19964 Internal helpers › Column creation helper nowColumnDefault … applyDeclaredColumnDefault 1,947 92 19 (0) 0 0 8 (8)
19965-20262 Internal helpers › Database helpers sqliteFilename … isJsonField 298 76 9 (2) 0 0 0 (0)
20263-20739 Internal helpers › SQLite serialisation formatInput … formatOutput 477 27 2 (0) 0 0 0 (0)
20740-20943 Internal helpers › Introspection internals introspectColumnOrder … introspectUniqueConstraints 204 73 5 (0) 0 0 0 (0)
20944-21018 After the class - 75 0 - - - -

Pricing the eligible methods

A method is eligible to move when its return type is annotated or it is not public; it has no getBuilder site, no this.FIELD.delete/insert/update( site, no private or protected static read, no super read, no bare this pass and no write to this; and it is not insertOnlyUpsertColumns. 164 members are eligible on this base. Each is priced as its stub minus its body (a stub costs 4 lines, plus 2 per field or getter read and 1 per method read).

Priced by area (every eligible body with a negative price and no sql-driver.ts#… pointer, summed per section): Filter helpers -550 (22 bodies), Rotation -388 (15), CRUD -351 (18), and every other section -93 or less.

The highest-priced candidates, and why each one stays or moves:

Method (section) Net Disposition
createColumn (Column creation helper) -463 Stays. ADR-0113 cites sql-driver.ts#createColumn, and five cli generate-*.pin.test.ts files read this file's text.
applyFilterCondition (Filter helpers) -368 Stays. ADR-0139 cites sql-driver.ts#applyFilterCondition.
formatOutput, formatInput (SQLite serialisation) -236, -183 Stay. ADR-0104 and ADR-0053 cite them, and the sql-driver.ts anchor entry's ADR-0053 paragraph describes formatOutput.
initObjects (Rotation) -195 Stays. packages/spec/liveness/object.json cites it.
applyCrossFieldComparison (Filter helpers) -179 Not taken: it reads four module-local helpers that other members also call (uncompilableFieldReferenceError alone has 16 readers).
applyNowAnchorComparison (Filter helpers) -101 Not taken: it reads five module-local declarations, two of them (crossFieldComparisonClass, fieldReferenceOffsetOf) shared with the cross-field code. #26261 added it at 19:11Z today.
assertConflictTargetHonoured (CRUD) -89 Not taken: it reads five module-local declarations of the upsert conflict-target refusal.
backendStatementFault (Bulk & Batch), compileFilters (Filter helpers) -75 each Not taken: each reads module-local declarations that other code also reads (PRE_DDL_QUESTION_SCOPE; refusalSubtree, assertCompilableComparand and three more).
getNextSequenceValue (CRUD) -66 Moves (this cut). Reads one module-local declaration, SEQUENCES_TABLE (see below).
fillAutoNumberFields (CRUD) -52 Moves (this cut).
issueAutonumbers (CRUD, public) -40 Moves (this cut).
maxAutonumberCounter (CRUD) -19 Moves (this cut).
resyncSequenceToDataMax (CRUD) -13 Moves (this cut). Reads SEQUENCES_TABLE.
collidingAutoNumberReservations (CRUD) -4 Moves (this cut).

Why this area

  • It pays the most of any area that moves cleanly. Filter helpers' paying bodies each drag module-local refusal helpers that other members also read; under the series' helper rule (a body that drags a shared helper stays) what is left there pays about -100. Rotation's paying bodies read eight shared module-local declarations, as cut 10 measured. In CRUD, the sequence path is the part that moves with one shared declaration.
  • One shared declaration, exported in place (cut 2's shape). SEQUENCES_TABLE is read by the two moved bodies and by three members that stay: ensureSequencesTable, ensureSequencesKeyHashShape and the sequencesTableName getter. It stays in sql-driver.ts, gains export, and the module imports it back, as cut 2 did with seven declarations. The value import is read only inside function bodies, so the module cycle is evaluation-safe. index.ts does not re-export it, and the published .d.ts does not move (proof below).
  • What stays, and why.
    • ensureSequencesTable and ensureSequencesKeyHashShape write this.
    • autoNumberValueExists and scanMaxNumericTail each hold one of the four tenant-column predicates that check:tenant-chokepoint's ADR-0131 D8 rule recognises. That gate scans the three driver files, not seam modules, and does not print the count on success, so moving them would narrow it silently (its floor is 3). I measured the count with the gate's own nullArmsOf: 4 at base and 4 at head, all four in sql-driver.ts.
    • The sequence-semantics members TursoDriver's remote face calls (resolveSequenceTenantId, sequenceKeyHash, defineSequencesTable, createSequencesTable and two getters) and the generic attemptWithoutPoisoning price at -3 or better, so they stay.
  • No series limit is touched: none of the six builds through getBuilder, reads a static, has a this.FIELD.delete/insert/update( site, uses super or a bare this, or writes to this. issueAutonumbers, the one public method, has an annotated return type (a promise of string[][]).
  • Subclasses. TursoDriver overrides getNextSequenceValue, autoNumberValueExists and resyncSequenceToDataMax, and each override calls super on its local path. The stubs stay on the class with the same signatures, so super still reaches them. The moved bodies reach every method through a late-bound closure on the instance, so fillAutoNumberFields still reaches Turso's counter, and the collision path still reaches its autoNumberValueExists and resyncSequenceToDataMax.
  • Path readers, screened. No script, test, doc or ADR names any of the six by a sql-driver.ts#… path or a sql-driver.ts::… key. No test slices their text out of sql-driver.ts. See Acceptance notes for prose that names them.

The shape (#23050 shape B, as cuts 1-10 apply it)

  • Each class method keeps its docblock and signature, byte-identical less async. Its body is now one host literal plus NAME.call(host, ...), marked [#25521 cut 11]. The five async methods return the moved function's own promise. maxAutonumberCounter reads no member, so its stub calls the function directly, as cut 3/16 of [maintainer] refactor(metadata-protocol): split src/protocol.ts (33,065 lines, +10,169 in 30 days) along its ObjectStackProtocolImplementation seams, one move-only slice per PR #25467 did.
  • Fields go as GETTERS that read the driver at call time: autoNumberFields, issuedAutoNumbers, knex, physicalTableByObject and sequencesHasKeyHash. Methods go as closures that call the method on the driver at call time. So a subclass override, an instance spy, or a field replaced after construction is still the one the body reaches (see the probe below).
  • Each moved function types its this as the Pick of AutonumberHost over exactly the members it reads. Each stub annotates its literal as the ThisParameterType of the moved function. There is no cast, and no member becomes public.
  • AutonumberHost lists 17 members, each typed as the class member's indexed access.
  • Module-level declarations. The module imports DriverOptions (type), missingFieldValues, readAutonumberCounter and renderAutonumber from @objectstack/spec/data, StorageNameMapping from @objectstack/spec/system, isUniqueViolationError and uniqueViolationColumn from @objectstack/types, the type Knex, GLOBAL_TENANT from schema-drift.ts, the types AutoNumberReservation and SqlDriver, and SEQUENCES_TABLE from sql-driver.ts. sql-driver.ts drops the five of those names it no longer reads.
  • Comments. The module header says what moved, what stayed and why, and how the bodies reach the class. The module has no anchor entry, so the header's own mention of the ADR-0131 D8 rule counts nowhere. The sql-driver.ts import comment names cut 11 in 4 lines.
  • How the move was made. A script produced it from the source text; nothing was retyped. Each body line is re-indented two columns. No line in the moved bodies starts inside template-literal text.

ADR anchors

check:adr-anchors counts decision-letter citations on the anchored surface: each anchor's invariant, plus the full text of each anchored file.

  • The count. It is 1880 at base 817cb8983 and 1879 at head 69181bf14, over 90 anchored files at both ends. Both runs exit 0.
  • Why it drops by one. getNextSequenceValue's body carries one comment that cites ADR-0131 D9 (the organization-less counter refusal happens first). That comment moves from the anchored sql-driver.ts to the new module, which has no anchor entry. The refusal itself (resolveSequenceTenantId) stays in sql-driver.ts.
  • No entry needs a new home. The only sql-driver.ts entry is ADR-0053's, whose paragraph describes formatOutput and presentReadValue; neither moved. No new entry was added, and no scripts/adr-anchors/** file changed.

The published .d.ts does not change

This is measured under the series bar (ruling 6348891160, item 1).

  • How each end was built. pnpm turbo run build --filter=@objectstack/driver-sql --force at each end, against the same dependency tree. The base leg writes base sql-driver.ts into this worktree and removes the new module after the commit, under an EXIT/INT/TERM trap that restores HEAD. The restore is proved by the HEAD blob hashes (13a5215f, 026dfdda), an empty git diff HEAD and 0 status entries.
  • The hashes. The raw sha256 of dist/index.d.ts and dist/index.d.mts is the same at base and at head: 0f33bf3febaac3c7aa96f68a4226d752766b8203ab7acade523b69f9aaa44d74. cmp finds them identical.
  • Positive control. I dropped protected from getNextSequenceValue in the head index.d.ts. The result hashes to bbd6f18ba89c1fdbfa84c1bb16628d3e6956f8c4b2c8296d7629f75e63de20cb, with a 1-line diff and cmp exit 1.
  • Export lists. CJS require and ESM import of the built dist give 59 / 59 names at both ends, identical (SEQUENCES_TABLE is not among them).
  • The head dist carries the move. .call(host sites in index.mjs go from 30 at base to 35 at head (five; maxAutonumberCounter is a direct call).

Move-only proof

The proof compares TypeScript compiler AST leaf tokens (JSDoc nodes skipped), base 817cb8983 against head 69181bf14. It is a scratch script and is not committed.

Moved body Body tokens Comments Parameter tokens less this Return type tokens Body lines
getNextSequenceValue 394 27 34 4 79
fillAutoNumberFields 393 11 15 6 61
issueAutonumbers 481 5 21 8 51
maxAutonumberCounter 110 6 12 1 21
collidingAutoNumberReservations 118 0 12 6 11
resyncSequenceToDataMax 207 0 3 4 25
  • Each moved body. In every row, 0 tokens differ and every comment is identical. async matches on both ends, and there are no type parameters. Each body line is the base line less two leading spaces.
  • The six stubs. Leading trivia (the docblock), modifiers and the signature are identical to base, less async.
  • The class. It has 350 members at both ends, in the same order, and the 344 unmoved members are byte-identical, trivia included.
  • sql-driver.ts top level. 210 statements at base, 206 of them byte-identical in head. The four that differ: the @objectstack/spec/data and @objectstack/types imports (names dropped), SEQUENCES_TABLE (a leading export, nothing else) and the class. The one new statement is the import of the new module.
  • Result. PROOF OK, exit 0.
  • Negative control. I changed legacy shape. to legacy shap3. in a module copy. The proof then reports getNextSequenceValue with its body tokens and lines differing, prints PROOF FAILED, and exits 1.

Tests

Each end ran under one os-verify-lock hold, after building that end's driver-sql dist. I compared the vitest JSON per test name and status, base 817cb8983 against head 69181bf14. Every part's exit code was captured on its own (build, probe, three suites: all 0 at both ends).

Suite Base Head Lost / changed / added
@objectstack/driver-sql 4060 (3846 passed, 214 skipped; 248 files) same 0 / 0 / 0
@objectstack/driver-turso, against that end's built driver-sql dist 2526 (2492 passed, 34 skipped; 95 files) same 0 / 0 / 0
@objectstack/driver-sqlite-wasm 746 (746 passed; 39 files) same 0 / 0 / 0
  • Type check and lint. tsc --noEmit -p . in driver-sql exits 0. pnpm exec eslint --no-inline-config packages/drivers/driver-sql exits 0, with 0 problems.
  • Late-binding probe. A scratch script, not committed. It runs node against each end's built dist on in-memory SQLite. Its 33 readings print identical output at base and head (diff is empty). They cover:
    1. create reaching a SUBCLASS override of getNextSequenceValue through fillAutoNumberFields, with the arguments it passes;
    2. getNextSequenceValue reaching instance spies on ensureSequencesTable, resolveSequenceTenantId, sequenceKeyHash, scanMaxNumericTail and attemptWithoutPoisoning, cold and warm;
    3. sequencesHasKeyHash flipped on the instance: a scoped format answers the legacy-shape refusal;
    4. fillAutoNumberFields reading physicalTableByObject and autoNumberFields replaced after construction (the scan then names the replaced table; an emptied registry fills nothing), through an instance spy on getNextSequenceValue;
    5. issueAutonumbers ahead of a write and after a collision (a column-named one and a column-blind one), through instance spies on injectTenantOnInsert, fillAutoNumberFields, collidingAutoNumberReservations, autoNumberValueExists, autoNumberCounterKey and resyncSequenceToDataMax; the transaction early-out; and issuedAutoNumbers replaced after construction;
    6. the Autonumber counter neither syncs to MAX(existing) per tenant nor re-checks on collision — warm-DB creates 409 in bursts, each failure burning a number (25 retries observed) #5495 re-seed through create, reaching instance overrides of autoNumberValueExists and resyncSequenceToDataMax;
    7. maxAutonumberCounter on three value sets;
    8. bad arguments: each async method answers a rejection, and maxAutonumberCounter throws synchronously, at both ends (it was never async).
  • Not run. No ablation, because no tested behaviour changed. test:repo was not run locally: the diff touches no repo-project test, and CI's Test Core runs it.

Gates

  • Derived list. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 53 commands for the 2 changed paths (merge base 817cb8983). On head 69181bf14, 50 exit 0 on the first run. Two exit 3 on a missing prerequisite and pass after it is supplied: check-plugin-teardown-shape.mjs --self-test (shallow clone; exit 0 after git fetch origin 621a487607) and check:lean-entry-closure (exit 0 after building objectql under the lock). check:dual-build-cjs-loads exits 3, PREREQUISITE NOT MET (no full build here): NOT MEASURED locally, CI runs it.
  • Reconciliation. dispatch-gates --ran: 53 derived families accounted for, 52 run, 1 NOT-MEASURED (derived from the recorded exit 3), exit 0.
  • Card-named gates, read at base (a clean detached worktree at 817cb8983) and at head, all exit 0:
Gate Base Head
check:adr-anchors 90 files, 1880 decision-letter citations 90 files, 1879 (see ADR anchors)
check:adr-symbol-anchors 2664 resolve 2664 resolve
check:tenant-chokepoint 24 bindings / 3 files, D8 clean; 4 tenant predicates same; 4 tenant predicates
check:driver-conformance 55 covered / 0 DEBT same
check:keyed-text-bounds 112 files / 238 index entries same
check:object-def-param-keys 541 classes / 7 positions same
check:system-context-census 153 sites / 132 symbols same
check-tenant-audit-census 243 sites same
check:logger-receiver-detach 0 detaches 0 detaches
  • Pre-push check:commit-card-trailers and check:nul-bytes pass.

Acceptance notes

  • Prose that names a moved body by file. ADR-0034 says getNextSequenceValue "uses runner = parentTrx ?? this.knex … (sql-driver.ts)". The method still lives on SqlDriver in that file; its body now runs from sql-driver-autonumber.ts. Left as is: no docs/adr/** edit in this series.
  • One comment now points at an import that left. The comment on isUnbackedConflictTargetError in sql-driver.ts (line 2196) warns "Deliberately NOT isUniqueViolationError, which is imported one line away". sql-driver.ts no longer imports that predicate (its last reader moved). The warning stays true; "imported one line away" no longer does. Left unedited because the cut is move-only.
  • TursoDriver's docblocks name SqlDriver.getNextSequenceValue, SqlDriver.maxAutonumberCounter and the others as the members its remote face shares; each is still a member of SqlDriver.
  • Next slice, priced on this base. The remaining CRUD upsert code needs the five conflict-target declarations (cut 2's export shape would cover them). Filter helpers stays the largest area, but its paying bodies share refusal helpers with the members that stay.

Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_012UMsT3A7YJv6eQtR5HED2B

…iver.ts into sql-driver-autonumber.ts

The bodies of SqlDriver#getNextSequenceValue, #fillAutoNumberFields,
#issueAutonumbers, #maxAutonumberCounter, #collidingAutoNumberReservations
and #resyncSequenceToDataMax move unedited into a new seam module through
AutonumberHost. Each method keeps its docblock and signature and hands its
body the members it reads (getters for fields, late-bound closures for
methods), so TursoDriver's overrides and instance spies are still the ones
reached. SEQUENCES_TABLE gains `export` in place and is imported back; five
import names whose last reader moved are dropped. Move-only.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012UMsT3A7YJv6eQtR5HED2B
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-sql, touching 37 documentable anchor(s).

⛔ 1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17/17-1.mdx (via injectTenantOnInsert (symbol, a field of interface AutonumberHost), injectTenantOnInsert (literal, a string literal in injectTenantOnInsert; a string literal in issueAutonumbers))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 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 — 13 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 77dc7062e5a791e02aa2ba9173e067295ebdebca → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 77dc7062e5a791e02aa2ba9173e067295ebdebca

⚠️ 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 77dc7062e5a791e02aa2ba9173e067295ebdebca → 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 · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-10-26T22:00Z · head f19c814197 · #25521 cut 11

The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.

  1. Shape: a draft against main. The body opens with Part of #25521 (⛔ not Fixes; the card stays open for later cuts). Clause-②: no and Metadata-protocol: none are line-initial. skip-changeset applies: the change is move-only. check-governed-merges --pr 26322: NOT governed, 690 changed lines.

  2. Premise measured: the claim 6424911800 asked for a fresh seam table after cut 10, and it is in the PR body. The pick is cut 10's proposal, the CRUD autonumber sequence path. getNextSequenceValue, fillAutoNumberFields, issueAutonumbers (public, annotated), maxAutonumberCounter, collidingAutoNumberReservations and resyncSequenceToDataMax move into the new sql-driver-autonumber.ts through AutonumberHost. Each method stays on the class as a delegate that hands its body the members it reads. Fields go through live getters, so a subclass override, an instance spy or a field replaced after construction is still what the moved body reaches; the dev's late-binding probe reads 33 of 33 identical at both ends.

    The seat compared every line removed from sql-driver.ts with the module after stripping indentation. All 248 are present there except nine:

    • the import lines, whose names the module now imports itself;
    • SEQUENCES_TABLE, which gains export in place (cut 2's shape), because three members that stay still read it;
    • the five method signatures, which lose async now that each returns its module function's promise. The dev's AST proof shows them otherwise identical.

    autoNumberValueExists and scanMaxNumericTail stay because each holds one of the four tenant predicates that check:tenant-chokepoint's D8 rule counts (4 = 4). sql-driver.ts goes from 21,018 to 20,827. The dev also reports:

    • .d.ts identical, with a positive control;
    • the AST proof OK, with a negative control;
    • the sql, turso and sqlite-wasm suites at 0 lost, 0 changed and 0 added per test.
  3. Gates: at this stamp the head's 47 check-runs read 35 success and 12 skipped (path-filtered UI, docs-build, dogfood matrix placeholders, opt-in harnesses and the skipped changeset check), with none failing or in progress, Test Core 1–8 included; mergeable, clean.

    Patch round: the first head read red on Test Core (6/8) (plugin-security). The dev merged main at 46255b1984, ran plugin-security locally at 228 of 228 green, and could not reproduce the red. The re-run on f19c814197 is green across all eight shards.

  4. Accepted deviations: check:adr-anchors reads 1,880 at base and 1,879 at head. The ADR-0131 D9 comment inside getNextSequenceValue's body moves with the body into a file that has no anchor. The card asks for the count to be reported, and it is. The sql-driver.ts anchor entry cites ADR-0053 and ADR-0120 and does not describe a moved body, so no new entry is owed.

  5. Out of scope: none filed. ADR-0034's prose places getNextSequenceValue in sql-driver.ts, which stays true of the method. Its body now runs from the new module, and this series makes no docs/adr/** edit.

  6. Landing: this seat runs pr_ready and then automerge_enable through the relay, confirms MERGED on both readings, and records the landing on [maintainer] refactor(driver-sql): split src/sql-driver.ts (22,096 lines, +2,533 in 30 days) along its SqlDriver seams, one move-only slice per PR #25521.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 26, 2026 22:01
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 26, 2026 22:02
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit 83e9d71 Oct 26, 2026
48 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-r8r6to branch October 26, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants