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

Queued
objectstack-fleet[bot] wants to merge 2 commits into
mainfrom
claude/project-thread-6gf6xi
Queued

objectstack-fleet[bot] wants to merge 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
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
Any commits made after this event will not be merged.

This branch has not been deployed

No deployments
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