Skip to content

refactor(driver-sql): the durability gate and the compile-refusal enumeration read the sql-driver facade, so the codemod moves four more members (#30147 phase 2b) - #30306

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

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-6gf6xi

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Yibo Wang · project thread

Part of #30147 (phase 2b of 2a-2d: two by-path readers learn the facade form, so the codemod moves four more members. 2c, 2d and the phase 3 measurement stay open on the card.)

维护者速读

  • 改了什么:check-durability-degradation-log-level.mjs 学会跨文件跟随 sql-driver 的 facade(facet 模块里的 this.x() 调到 SqlDriver#x,再穿过 stub 到 facet 方法体);sql-driver-compile-refusal-seam.test.ts 改为读取全部 sql-driver-*.ts 模块。codemod 因此去掉 1 个 pin 和 4 个 needle,重新生成后又有 4 个成员变成委托,登记表 73 → 69。
  • 为什么改:这两个读者只认 sql-driver.ts 本文件,codemod 只好把这些方法留在类上;读者学会新形态后,codemod 才能把它们移走(Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147,裁决 6597555122 第 3 条)。
  • 风险与回滚:方法体逐字节不变(175/175),公开 .d.ts 与 base 相同;durability 门禁在 base 和 head 上读到同样的 52 个 seam、同样的判定,只有两个 seam 的位置从 sql-driver.ts 换到 sql-driver-rotation.ts。回滚即 revert。
  • 先看:门禁里新增的 FACADE_LOG_HOP / createFacadeLogHop 和 collectLoggedLevels 里的 6 行接入;测试里 sources 的改法。
  • 两分钟验证:node scripts/check-durability-degradation-log-level.mjs --self-test(新增 10 行通过)和 node scripts/codemod-split-sql-driver.mjs --verify --base 21510bba(175/175,退出 0)。
  • 需要你做的:无,席位审阅并落地。

Clause-②: no
Metadata-protocol: none

What changes

Two readers took sql-driver.ts text by path, so the codemod pinned four members on the class. Each reader now reads the facade form, and the pins go.

scripts/check-durability-degradation-log-level.mjs. Its catch side follows a log helper to its body by name, in the same file. A catch the codemod moves into a facet module calls this.logDurabilityFailure(…), which that module does not declare. Once logDurabilityFailure itself moves, the method the call reaches is a one-call stub. Either way the catch read "swallowed, no log": with the pins removed and no reader change, the gate reds the two runWideningAlters() catches in sql-driver-rotation.ts. FACADE_LOG_HOP follows exactly the two shapes the codemod writes:

  • HOST CALL: this.x(…) in a sql-driver-*.ts module, inside a function whose this is the module's own host interface (bare or through a Pick naming x), whose member x is typed T['x'] with T the SqlDriver class imported from ./sql-driver.js (directly or as SqlDriverClass), resolves to SqlDriver#x in sql-driver.ts. That is one hop, the same hop the call made before the move.
  • STUB: a SqlDriver method whose last statement returns <X>Facet.x.call(<y>Host.of(this), …) is read as the facet's static x. This costs no depth.

Every other shape stays unresolved, as before. A log found across the hop is reported at the line of the call in the file being judged. The hop is handed in by run() to the log-level rule only. The read-seam rule's scan roots do not include driver-sql, so the two rules still agree on every file they both read.

packages/drivers/driver-sql/src/sql-driver-compile-refusal-seam.test.ts. The enumeration read five named files. It now reads every sql-driver-*.ts module in the directory. A facet's static x is named SqlDriver.x, because it is that method's body. The positive control also asserts that the five files it used to read, plus one facet module, are still among those it reads. The pinned sets are unchanged.

Codemod (scripts/codemod-split-sql-driver.mjs). These entries are gone:

  • the logDurabilityFailure pin;
  • the this.runWideningAlters( needle;
  • the three CLASS_PATH_READER_NEEDLES rows (the table stays, empty, with its comment rewritten).

The tree is regenerated from 21510bba, so logDurabilityFailure, migrateMysqlDatetimeColumns, migrateMysqlTimeColumns and resolveWithheldFilterRefusal move. sql-driver.ts goes from 10,717 to 10,624 lines.

Registry. The four rows are deleted, so 73 rows become 69.

card before after
#30020 17 17
#30054 16 16
#30055 6 6
#30147 34 30 (sql-driver.ts 12 → 8)
total 73 69

Tests

  • The durability gate's self-test gains 10 rows, each driven through analyzeSourceFile the way run() drives it, over multi-file fixtures:
    • the hop reaches a loud body;
    • the same hop to a warn body is judged at that level;
    • with no hop the moved catch reads swallowed;
    • the same files in another directory, a member typed otherwise, a member the Pick omits and a class type imported from elsewhere each resolve nowhere;
    • a routed module's SqlDriverClass alias resolves;
    • a sql-driver.ts catch follows the stub;
    • a stub handing anything but <y>Host.of(this) is not followed.
      The selfTest partition floor goes 70 → 80 and the roster total 137 → 147.
  • The compile-refusal test keeps its 115 cases. Reading the old five files over the new tree reds "only three functions build the envelope WITHOUT the seam". Measured before the widening.
  • No other test file changes. The suites below ran at base 9b8a5867 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) 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 d3ca391c, base origin/main 9b8a5867.

Proof readings
  • Byte-identity: node scripts/codemod-split-sql-driver.mjs --verify --base 21510bba exit 0, "175/175 moved bodies identical to base (body, parameters, return type, async); 127/127 moved top-level declarations identical to base; sql-driver.ts 18334 -> 10624 lines; undoing the split does rebuild the base byte-for-byte".
  • Determinism: two --write runs from the unsplit input give tree sha256 5044055d6e0d47825283c7fe8d3c539a823909573a382434b0cda80e1b76326c both times.
  • Durability gate, --list at base and head: 52 seams, the same verdicts. The only change is the location of the two runWideningAlters() seams, from sql-driver.ts:5187 / :5281 to sql-driver-rotation.ts:327 / :373, both "recovers on one branch, loud (error … via logDurabilityFailure())". Without the hop, head reds those two.
  • 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).
  • Typecheck: pnpm --filter @objectstack/driver-sql typecheck exit 0.
  • check-tenant-chokepoint: 24/21/3/4/0 across 39 files at base and head; --self-test exit 0.
  • Facade gate exit 0, "3 facade file(s) hold delegations only, 69 named exception(s)"; --self-test 36 exit 0.
  • node scripts/pm/dispatch-gates.mjs --commands: 74 derived commands, each run, all exit 0; --ran reconciles 74 derived, 74 run, 0 NOT-MEASURED. Also run: the codemod, durability, check-tenant-chokepoint and facade gate --self-tests, check:lean-entry-closure, eslint over the changed files, all exit 0.
  • Changed lines 740 (+542 / -198), under the 3,000 threshold.

Generated by Claude Code

…meration read the sql-driver facade, so the codemod moves four more members (#30147 phase 2b)

check-durability-degradation-log-level.mjs follows a catch's log helper
across the facade (FACADE_LOG_HOP): `this.x()` in a sql-driver-*.ts facet
module resolves to SqlDriver#x through the module's host interface, and a
`<X>Facet.x.call(<y>Host.of(this), ...)` stub is read as the facet body.
sql-driver-compile-refusal-seam.test.ts reads every sql-driver-*.ts module
and names a facet static as the SqlDriver method it is.

The codemod drops the logDurabilityFailure pin, the runWideningAlters
needle and the CLASS_PATH_READER_NEEDLES rows; regenerated from 21510bb,
logDurabilityFailure, migrateMysqlDatetimeColumns, migrateMysqlTimeColumns
and resolveWithheldFilterRefusal move (175/175 bodies identical, public
.d.ts byte-identical). Registry 73 -> 69 rows.

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

20 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • 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 8b117c0e54a685b9fe580ae595f71ac3685f80b3 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 8b117c0e54a685b9fe580ae595f71ac3685f80b3

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

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

Stamp: 2026-11-05T05:40Z
Head-sha: d3ca391

维护者速读

  • 改了什么:

    • durability 门禁(check-durability-degradation-log-level.mjs)新增 FACADE_LOG_HOP:它会沿 facet 模块的 host 调用,以及 sql-driver.ts 里的一行委托,一直跟到真正的方法体。
    • compile-refusal 的枚举测试改为读所有 sql-driver-*.ts 模块。
    • codemod 去掉 logDurabilityFailure 的 pin 和 4 根 needle。

    又有 4 个成员移进 facet,登记表例外从 73 条降到 69 条。

  • 为什么改: Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147 第二阶段 2b。这 4 个成员原来留在类上,只因为门禁和测试按文件路径读它们;现在门禁和测试能读到 facet 模块了。

  • 风险与回滚: 门禁只多跟一跳,没有删检查,也没有加豁免。52 个 seam 在 base 和 head 上的判定相同,去掉这一跳会有 2 个变红。回滚就是 revert。

  • 先看: 门禁里 facadeHop.follow 那一段,以及新增的 10 个 self-test 用例。

  • 两分钟验证: node scripts/check-durability-degradation-log-level.mjs --self-test,147 个用例全过。

  • 需要你做的: 无,由席位落地。

  • 席位意见: ACCEPT。

席位核对

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 05:41
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 5, 2026 05:41
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit bfca0ef Nov 5, 2026
54 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-6gf6xi branch November 5, 2026 06:26
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 tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant