Skip to content

refactor(driver-sql): the by-path readers read the sql-driver facade, so the codemod moves the five path-reader members (#30147 phase 2c) - #30363

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-6gf6xi
Nov 5, 2026
Merged

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Yibo Wang · project thread

Part of #30147 (phase 2c of 2a-2d: the readers that sliced sql-driver.ts by path read the facade form, so the codemod moves the five path-reader members. 2d and the phase 3 measurement stay open on the card.)

维护者速读

  • 改了什么:新增 scripts/sql-driver-split-source.mjs,把 SqlDriver 重新读成一份文本(每个 codemod stub 的方法体换成它所调用的 facet 方法体,leaf 放回类前);cli 的 5 个 generate-* pin 和 check-keyed-text-bounds.mjs 改用它。codemod 因此清空 2 个 pin 和 10 个 needle,createColumn 写出返回类型 void,重新生成后 5 个成员变成委托,登记表 73 → 68。
  • 为什么改:这些读者只认 sql-driver.ts 本文件的文字,codemod 只好把这 5 个方法留在类上(Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147,裁决 6597555122 第 3 条:读者与模块同一个 PR 里跟上)。
  • 风险与回滚:方法体逐字节不变(180/180),公开 .d.ts 与 base 相同;5 个 pin 断言一条未改,只换了读取来源。回滚即 revert。
  • 先看:sql-driver-split-source.mjs(约 160 行,只认 codemod 写的 stub 形态,认不出就抛错而不是读 stub);cross-package-test-inputs.mjs 与 turbo.json 里为 cli 新增的声明。
  • 两分钟验证:node scripts/codemod-split-sql-driver.mjs --self-test(新电池 "split readers (Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147)" 8 例)和 node scripts/check-keyed-text-bounds.mjs --self-test(新增 3 例),都退出 0。
  • 需要你做的:无,席位审阅并落地。

Clause-②: no
Metadata-protocol: none

What changes

Five members stayed on SqlDriver because readers sliced sql-driver.ts by path: createColumn, createAuditTimestampColumn, varcharColumnChars, ensureShardTable and initObjects. Each reader now reads SqlDriver as one text, and the codemod tables that held the five go.

scripts/sql-driver-split-source.mjs (new, with its .d.mts). readSqlDriverSource(srcDir) returns sql-driver.ts with the body of every codemod stub replaced by the body of the facet method it calls, and the leaf (sql-driver-top-level.ts) put back ahead of the class. A method's own signature on the class is then followed by its own body, as before the split. It follows exactly the stub the codemod writes: one statement, carrying the [#29520 codemod] marker, returning <X>Facet.<m>(…) or <X>Facet.<m>.call(<x>Host.of(this), …) (or the generic spelling), with the module named in the marker. A marked body of any other shape, a missing module, or a facet without that static member throws. The reader never hands back the stub text. Unmarked bodies (the hand-series delegations) stay as they are. It is a reading, not an undo: imports, a private docblock and the stub-side spellings stay as the split has them. --verify remains the byte-for-byte proof.

Readers.

  • The five packages/cli generate-* pins (builtin-id-column, field-type-vocabulary, file-reference-width, multiple-json-column, string-family-width) build SQL_DRIVER_SOURCE from readSqlDriverSource(DRIVER_SQL_SRC).text instead of readFileSync(…/sql-driver.ts). No assertion, anchor or message changes.
  • scripts/check-keyed-text-bounds.mjs reads its emitter the same way. A reader refusal becomes the gate's existing { error } refusal.

Codemod (scripts/codemod-split-sql-driver.mjs).

  • PATH_READER_PINS (2 rows) and PATH_READER_NEEDLES (10 rows) are emptied. Both tables stay, with a note on why they are empty.
  • EXPLICIT_RETURN_TYPES gains createColumn: 'void', copied from the base dist/index.d.ts (protected createColumn(…): void;).
  • Regenerated from 21510bba: createColumn, createAuditTimestampColumn and varcharColumnChars move to sql-driver-column-creation.ts; ensureShardTable and initObjects move to sql-driver-rotation.ts; two top-level declarations move to the leaf. sql-driver.ts goes from 10,624 to 9,741 lines.

Declarations. The pins now read every sql-driver-*.ts module a stub names, through paths the cross-package scan cannot name. scripts/cross-package-test-inputs.mjs gives @objectstack/cli the glob packages/drivers/driver-sql/src/sql-driver-*.ts plus the reader and its .d.mts, with heldBy witnesses naming the five pins (and one for sql-driver.ts, which no literal names any more). turbo.json @objectstack/cli#test carries the same three inputs. The glob also matches the package's tests; that adds no re-run, because cli#test already depends on build → ^build, and driver-sql's build hashes $TURBO_DEFAULT$.

Registry. The five rows are deleted, so 73 rows become 68 (the base has 73: #30264 added four engine.ts rows after 2b's count of 69).

card before after
#30020 19 19
#30054 16 16
#30055 6 6
#30147 32 27 (sql-driver.ts 8 → 3)
total 73 68

The three sql-driver.ts rows left on #30147 are applyFilterCondition (2d), get supports and static DIALECT_CONNECT_TIMEOUT (phase 3 names both).

Tests

  • Codemod --self-test gains a seventh battery, "split readers (Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147)", with 8 cases, driven over a split the script generates and lays out on disk:

    • every stub is followed;
    • each followed stub reads its base body byte for byte after the signature the class keeps;
    • no stub text survives;
    • the leaf stands ahead of the class;
    • an unsplit file is read as it stands;
    • a missing module, a facet without the static, and a marked stub of another shape each refuse.

    106 cases in 7 batteries (98 in 6 before); the battery floor goes 6 → 7.

  • check-keyed-text-bounds --self-test gains 3 cases in "the emitter-derived family" (floor 3 → 6): the family is read through a stub from the facet module, and a stub naming an undeclared facet or of another shape refuses.

  • No assertion in any of the five pins changes. Before the reader change, the regenerated tree reds 28 of their cases and check-keyed-text-bounds exits 2 ("could not find the keyed-text arm"). Measured.

  • The suites below ran at base bfca0efb and at head; the counts are equal.

suite base head
driver-sql (vitest run) 238 files passed, 12 skipped; 3,859 passed, 216 skipped the same
driver-turso (subclasses SqlDriver) 97 files; 2,514 passed, 34 skipped the same
driver-sqlite-wasm (subclasses SqlDriver) 40 files; 750 passed the same
cli by-path pins (9 files, the five generate-* pins among them) 9 files; 116 passed the same
types / metadata / metadata-protocol by-path tests, spec check-liveness.test 53 / 11 / 33 / 74 passed the same

Acceptance notes

Verification

Head d67df0b5, base origin/main bfca0efb.

Proof readings
  • Byte-identity: node scripts/codemod-split-sql-driver.mjs --verify --base 21510bba exit 0, "180/180 moved bodies identical to base (body, parameters, return type, async); 129/129 moved top-level declarations identical to base (leading comments included); sql-driver.ts 18334 -> 9741 lines; undoing the split does rebuild the base byte-for-byte".
  • Determinism: two --write runs from the unsplit input give output tree sha256 0d2ba8a299610def947cd879cee7e7c36aae58aecfca0f8acacc395339f7bf16 both times (input sha256 2d2ebebd…), and the tree on disk is unchanged by either.
  • Public .d.ts: dts-public.mjs over the base and head dist exit 0, pass: true, both files raw-equal (index.d.ts sha256 92e2cfb2… on both sides, as at 2a and 2b).
  • Typecheck: pnpm --filter @objectstack/driver-sql typecheck and pnpm --filter @objectstack/cli typecheck (which includes check:test-typecheck, so the pins' import of the .d.mts) exit 0.
  • check-tenant-chokepoint: 24/21/3/4/0 across 39 files at base and head; --self-test exit 0.
  • Durability gate --list at base and head: 52 durability seams with the same verdicts (103 read seams); the only change is the line of the two runWideningAlters() seams inside sql-driver-rotation.ts (:321/:367 → :661/:707), because ensureShardTable and initObjects moved in above them.
  • check-keyed-text-bounds: exit 0 over the tree, the family read through the stub is the same 8 types; --self-test exit 0.
  • check-cross-package-test-inputs and check-ci-filter-parity exit 0.
  • Facade gate exit 0, "5 facade class(es) in 3 file(s) hold delegations only, 68 named exception(s)"; --self-test exit 0 (gate script and its cases untouched).
  • node scripts/pm/dispatch-gates.mjs --commands: 79 derived commands, each run, all exit 0; --ran reconciles 79 derived, 79 run, 0 NOT-MEASURED. Also run: the codemod, check-keyed-text-bounds, durability, check-tenant-chokepoint and facade gate --self-tests, check:lean-entry-closure, eslint over the changed files (0 errors), all exit 0.
  • Changed lines 2,417 (+1,407 / -1,010), under the 3,000 threshold.

Generated by Claude Code

… so the codemod moves the five path-reader members (#30147 phase 2c)

A new reader, scripts/sql-driver-split-source.mjs, returns SqlDriver as one
text: each codemod stub's body replaced by the facet body it calls, the leaf
ahead of the class. The five packages/cli generate-* pins and
check-keyed-text-bounds read through it, so the codemod empties
PATH_READER_PINS and PATH_READER_NEEDLES and writes createColumn's return
type. Regenerated from 21510bb: createColumn, createAuditTimestampColumn,
varcharColumnChars, ensureShardTable and initObjects move; the registry loses
their five rows (73 -> 68). cli declares the modules the reader follows.

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

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-sql, touching 82 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/drivers/driver-sql/src/sql-driver-database-helpers.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 0e4dfbe27a2a312864cd8d14e4954b6af14e2a22.

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

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/drivers/driver-sql/src/sql-driver-database-helpers.ts) — pages documenting those are invisible to this run
  • 2 anchor(s) matched too much of the corpus to be a work list: created_at (literal, 43 pages), sys_user (literal, 49 pages)
  • the SDK route bridge reached 61 of 219 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 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; 103 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 0e4dfbe27a2a312864cd8d14e4954b6af14e2a22 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 0e4dfbe27a2a312864cd8d14e4954b6af14e2a22

⚠️ 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 0e4dfbe27a2a312864cd8d14e4954b6af14e2a22 → 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

domain:devx#1 · os-support-ai · session_01WGufzgBDcBNVmSmo7VFHpj

Stamp: 2026-11-05T08:06Z
Head-sha: d67df0b

维护者速读

  • 改了什么: 新增 scripts/sql-driver-split-source.mjs。它把 SqlDriver 拼回成一份完整文本:每个委托的方法体从它所在的 facet 读回来,遇到跟不上的委托就直接报错。cli 的 5 个 generate-* pin 和 check-keyed-text-bounds 改为通过它读源码,断言一条没改。codemod 清空了 PATH_READER_PINS 和 NEEDLES,又有 5 个成员移进 facet,例外从 73 条降到 68 条。
  • 为什么改: Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147 第二阶段 2c。这 5 个成员原来留在类上,只因为这些 pin 按 sql-driver.ts 的路径读源码。
  • 风险与回滚: 这些 pin 读到的文本与以前等价,断言不变。对照:去掉这个读取器,新的文件布局下有 28 个 pin 用例变红,keyed-text-bounds 退出 2。turbo 和 cross-package-test-inputs 声明了新的输入文件,facet 改了也会触发 cli 的 pin。回滚就是 revert。
  • 先看: scripts/sql-driver-split-source.mjs,以及 5 个 pin 测试里各自只改了的那一行读取。
  • 两分钟验证: 在 cli 包跑 generate-*.pin.test.ts,然后 node scripts/check-keyed-text-bounds.mjs,都应退出 0。
  • 需要你做的: 无,由席位落地。
  • 席位意见: ACCEPT。

席位核对

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 08:07
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 5, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant