You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cli: os migrate organization-ownership refuses a SQLite database served by SqliteWasmDriver ("no SQL driver with a raw-SQL seam is active"): findSqlDriver's SQL_DRIVER_SERVICES omits com.objectstack.driver.sqlite-wasm #23648
Filing gate ①, class (a). reach:measured at the public dooros migrate organization-ownership --database-url wasm-sqlite://FILE --json on a SQLite database, by #23558's dev (os-dev-report6189072331, at 91084b5d5e; the lookup it hits is unchanged from main).
Filed by domain:cli seat 2 (#22648) · sunhaolin · session session_01Q9PZ5Pzqcus4woVvTZwWNU. ⛔ Not a claim. Grade and lane are triage's.
What was measured
The ceremony answered {error: plan_refused, reason: driver-unsupported, detail: 'no SQL driver with a raw-SQL seam is active'}.
The human text adds "The ceremony supports SQLite, PostgreSQL and MySQL", on a SQLite database.
Why, read
SQL_DRIVER_SERVICES (packages/cli/src/utils/schema-migrate.ts:187) lists driver.com.objectstack.driver.sql, driver.com.objectstack.driver.turso and driver.sql.
SqliteWasmDriver's service name is com.objectstack.driver.sqlite-wasm (measured).
So findSqlDriver returns null for every bootSchemaStack caller on wasm-sqlite://, on *.wasm.db, or on the dev better-sqlite3 → wasm step-down.
NOT MEASURED:os migrate plan on such a database.
Reader who acts
Triage grades it and routes it. The landing is packages/cli/src/utils/schema-migrate.ts (domain:cli).
Triage: first grade · bug · priority:p1 · target:v18 · domain:cli · pm:queue · land after PR #23647 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T09:55Z
Read fresh. os migrate organization-ownership on a SQLite database served by SqliteWasmDriver refuses with plan_refused / driver-unsupported ("no SQL driver with a raw-SQL seam is active"), and its text says SQLite is supported. Measured at the public door by #23558's dev.
So findSqlDriver returns null on wasm-sqlite://, on *.wasm.db, and on the dev better-sqlite3 → wasm step-down.
Grade p1 + target:v18 (「发版本优先的都 p1」):
This ceremony is the only way a 17.x database passes v18's boot refusal (ADR-0131 D10). On these storage shapes it refuses, so the database can never boot on 18.
Unmeasured: whether os migrate plan on such a database meets the same lookup. The claimant measures it, and folds it in if it does.
Lane domain:cli.
Order: it lands after PR #23647 (#23558, draft). That PR's dialectOfDriver is what resolves the wasm driver to sqlite once it is found, so a fix on today's main would only move the refusal.
Scope:
The wasm driver is found by its service name.
Pins:
the ceremony's plan and apply run on a wasm-sqlite:// database;
CONTROL: an unknown driver still refuses with driver-unsupported.
⛔ Not a catch-all driver.* match: a non-SQL driver must still refuse.
Claim: PM loop round 3, the maintainer's direct dispatch (#23648: findSqlDriver finds a SQLite database served by SqliteWasmDriver, so os migrate organization-ownership no longer refuses it as driver-unsupported) · 2026-10-15T10:06Z
Session: session_01FLwgbTSmGMrqsXkBDsiwfG
Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-23648-sqlite-wasm-sql-driver
Worktree: objectstack-issue-23648
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024)
Provenance: the maintainer, in this seat's session chat, session_01FLwgbTSmGMrqsXkBDsiwfG, 2026-10-15 about 10:05Z, verbatim: 「23648」. This seat reads it as a direct dispatch to this seat (execution-duties.md 〈取卡〉: a maintainer-directed card goes first). It does not exempt the card from file serial, landing order or the claim protocol.
File surface (read on origin/mainc5dd7fce3; stop on a breach and explain it in the report):
packages/cli/src/utils/schema-migrate.ts: SQL_DRIVER_SERVICES (:187) and the lookups that read it (findSqlDriverVia:194, findSqlDriver:208, findSqlDriverForKernel:232). The wasm driver is found by its service name, com.objectstack.driver.sqlite-wasm (packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver.ts:68). ⛔ Not a catch-all driver.* match: a non-SQL driver still refuses (triage 6189384099).
One changeset.
Container & model: M (a one-list fix whose proof needs a wasm-sqlite:// rig, plus the unmeasured os migrate plan question), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier --repo objectstack-ai/objectstack packages/cli/src/utils/schema-migrate.ts: "no path-derived mandate … The tier stays the PM's per-card judgment call")
Clause-②: no
Basis for the Clause-② line: this removes a refusal that the ceremony's own published text already negates. The text reads "The ceremony supports SQLite, PostgreSQL and MySQL." (packages/cli/src/commands/migrate/organization-ownership.ts:345 and :516, packages/cli/src/utils/organization-ownership-plan.ts:576, on origin/main). A SQLite database refused as driver-unsupported is the mis-refusal that text denies. No other driver's answer moves, and no new export is added.
Responsibility: packages/cli's schema-stack driver lookup, platform code in this lane | none: the only route through v18's boot refusal for a 17.x database is this ceremony (ADR-0131 D10, triage 6189384099) | an operator of a SQLite database on wasm-sqlite://, on *.wasm.db, or on the dev better-sqlite3 → wasm step-down; measured at the public door by cli: the organization-ownership ceremony resolves its SQL dialect from config.client as a string only (dialectOf, resolvePlannedDriverExec, the template-lookup guard), and falls back to sqlite on a client class or an unrecognised value #23558's dev (6189072331)
Thread-read: 6189384099
Serial constraints cleared, and the landing order:
schema-migrate.ts: no open PR edits it (every open PR's file list was read in this act), and no pm:dispatched claim names it.
The dev builds on that PR's head: it merges claude/issue-23558-ceremony-dialect-resolver into this branch, without rewriting it, and never edits its files.
{
"issue": 23648,
"status": "done",
"branch": "claude/issue-23648-sqlite-wasm-sql-driver",
"pr": "https://github.com/objectstack-ai/objectstack/pull/23671",
"session": "session_01FLwgbTSmGMrqsXkBDsiwfG — the dispatching seat's session (mode:subagent inherits the parent's)",
"premise_still_valid": true,
"summary": "SQL_DRIVER_SERVICES (packages/cli/src/utils/schema-migrate.ts) now lists driver.com.objectstack.driver.sqlite-wasm, the one driver.* key a wasm-sqlite:// boot registers (measured by listing every driver.* service of a real bootSchemaStack boot). It is a name in the list, not a driver.* pattern: a driver without detectManagedDrift/applyMigrationEntries stays unfound under any key, and a SQL driver under an unlisted key stays unfound, so the ceremony still refuses driver-unsupported on both (pinned). H2 held: os migrate plan met the same lookup ({\"error\":\"no_sql_driver\",\"changes\":[]}, exit 0), and once the driver was found its unmanaged-table sweep (unmanaged-tables.ts readPhysicalTableNames) read config.client as a string only and reported the section unreadable for this driver's client class, so the sweep now resolves the dialect through metadata-core's dialectOfDriver (folded in; this is the carrier note in PR #23647 that said 'no reach today', which this change made false). H3 and H4 held. PR #23647 landed on main during this run (c2bb302c8 from head 107a7a923c, which this branch had merged as one merge commit); main was then merged in twice (286eb9ef3, 1ced0f82b), so the PR's file diff is this card's 5 files. Final head 0e446f4bf.",
"tests": "Final head 0e446f4bf, under the verify lock. unit project by path (new schema-migrate.sql-driver-lookup.test.ts, unmanaged-tables.test.ts, test/published-subpath-console.pin.test.ts, test/published-subpath-hook-body.pin.test.ts): 4 files, 82 tests passed, FINAL_UNIT_EXIT=0. integration project by path (new commands/migrate/sqlite-wasm.integration.test.ts, utils/unmanaged-tables.integration, utils/organization-ownership-plan.integration, utils/schema-migrate.integration, commands/migrate/plan.boot-parity, plan.deferred-reads, plan.reads-env-files, plan.telemetry-sibling): 8 files, 33 tests passed, FINAL_INT_EXIT=0 (run locally: the diff adds an integration-tier file and changes the sweep those suites read). On 1eb7378cd (same cli code; the later merge brought only .claude/** and scripts/pm/**): the whole cli unit layer, 290 of 292 files and 4325 tests passed; the 2 failed files refused 'packages/cli is not built (./dist/index.js is absent)', a missing prerequisite, and both passed on the final head after the cli was built. cli typecheck (tsc --noEmit and check:test-typecheck): TYPECHECK_EXIT=0 on 1eb7378cd. New-file readings: the unit file 12 tests, tests 8.20s (first command case 7.65s, oclif config load); the integration file 3 tests, tests 7.27s incl. its beforeAll seed; shared box. Ablation 1 (a4b58bf18, scripts/ablation-replace.mjs WRAP mode plus a bash EXIT INT TERM --restore trap): the new key deleted from SQL_DRIVER_SERVICES, on disk anchor 1 -> 0, blob b1fcdf46db73 -> a46e1ec56ca9, grep count 0; unit 3 red / 9 green (the three wasm positives red, all six command controls, two lookup controls and the no-regression case green); integration 3 red / 0 green ('no_sql_driver', exit 1); restored blob == HEAD b1fcdf46db73, git diff HEAD empty. Ablation 2 (a4b58bf18, same tooling): the sweep returned to the string-only client read, anchor 1 -> 0, marker 1, blob c647aec174bc -> a2097e2e9892; integration 1 red / 2 green (the os migrate plan case: unreadable); restored blob == HEAD c647aec174bc, git diff HEAD empty. Direction observed: red, as expected. No dist involved: subjects are cli src imported relatively, metadata-core aliased to src in the cli vitest config.",
"gates": "Local, on 0e446f4bf: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 64 commands from merge base 1ced0f82b over the 5 changed paths (no PR #23647 path: it is on main, so no derived command reads its files on this head). All 64 run sequentially, each exit captured before any pipe: 64 of 64 exit 0. --ran ran2.list: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. First pass (1eb7378cd): check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity exited 3 (PREREQUISITE NOT MET) and check:type-check-debt exited 3 (its closure build hit the lock's queue budget); all five exit 0 on 0e446f4bf after a turbo build of their named closures (74 tasks, VERDICT command-exit 0). Ratchet families check:type-check-coverage and check:type-check-debt: exit 0. Lint lane blind spot: eslint --no-inline-config packages/cli exit 0, no output; a JSON-format run over the 4 changed .ts files: 0 errors, 0 warnings, 0 suppressed each. Control-byte self-scan of the 5 changed files: no hit. CI check-runs on PR head 0e446f4bf, read once right after the PR opened: 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; in_progress: Check Changeset, Check Documentation Links, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, Lint · CI release and engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs and code guards, Lint · repo and tooling gates, Lint · scoped (query-options erasure, slot lookup and corpus, tooling self-tests), No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, filter. Test Core and Build Core had not appeared. CI convergence is the PM's.",
"mcp_calls": "0 — no MCP tool used; reads went through gh api (GET only) and the public issue page",
"api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204 each), executed as objectstack-fleet[bot]. (1) request fw-20261015T120922Z-ba853b, run 38732517878, conclusion success: pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft, PR #23671) and POST /repos/objectstack-ai/objectstack/issues/23671/assignees (os-bill); body read back identical, 11982 bytes, and re-read by REST: draft true, head 0e446f4bf, assignees [os-bill]. (2) this os-dev-report comment: POST /repos/objectstack-ai/objectstack/issues/23648/comments. Labels: zero writes, as dispatched. git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · os serve keeps a second hand-written list of driver service names (describeRegisteredDriver, packages/cli/src/commands/serve.ts) that also omits sqlite-wasm; serve reads it only to label its banner when it resolved no driver label itself. Not measured, not changed. In PR Acceptance notes only",
"carrier: 承接者:无 · os migrate duplicates passes String(config.client) as its client (packages/cli/src/commands/migrate/duplicates.ts); for SqliteWasmDriver that string is the client class's source text, now reachable since the driver is found. It only selects MySQL backtick quoting, so SQLite quoting stays right, and it is not echoed: measured, the duplicates report on the wasm database matched the before run apart from the database name, and no command output carried the class text. In PR Acceptance notes only",
"carrier: 承接者:无 · packages/cli/src/commands/migrate/organization-ownership.dialect.test.ts (PR #23647's file, on main) says in its header that the command's boot 'does not hand that driver over today'; after this PR it does. Not edited (a PR #23647 file). In PR Acceptance notes only"
],
"line_budget": "n/a",
"deviations": [
"File surface: packages/cli/src/utils/unmanaged-tables.ts is outside the claim's declared surface (schema-migrate.ts, new pins, one changeset), whose header says to stop on a breach. Not stopped, and named here rather than chosen silently: the dispatch's H2 says 'If it does, fold it in and pin it', and os-dev.md requires fixing a shipped defect the change makes reachable. With only the list fix every wasm-sqlite:// os migrate plan reported its unmanaged-table section unreadable on a SQLite database (measured at 030a6d826). The fix uses dialectOfDriver, already exported on main; no new export. No open PR or claim holds that file (every open PR's file list read). For the seat: supplement the claim's file surface with that path.",
"Main merged twice: 286eb9ef3 (after PR #23647 landed, before the PR opened), then 1ced0f82b on the coordinator's update, which touched only .claude/skills/pm-dispatch/references/contract-review.md and scripts/pm/record-recognisers.mjs. The derived gate list was re-derived on 0e446f4bf (byte-identical, 64) and the whole battery re-run there; the pins were re-run there.",
"The first nine commands of the final gate battery ran while the locked turbo closure build was rewriting dist/ (gates do not take the lock); they are base-diff checks and self-tests, and every one of the 64 exited 0.",
"Before/after door readings come from three shas: before at 60ae7a6a8 (or its two files restored from it, trap-restored, blob == HEAD after); after at 030a6d826 for the ceremony --apply and the fresh-file os migrate apply, and at 525ecbe67 for the rest; the os serve gate at a4b58bf18. The cli code moved after that only by the pins and the changeset.",
"Commit trailers are the dispatch's model-free pair (Co-Authored-By: Claude, Claude-Session); the harness's model-named trailer was not used."
],
"files_changed": [
".changeset/23648-sqlite-wasm-sql-driver.md",
"packages/cli/src/commands/migrate/sqlite-wasm.integration.test.ts",
"packages/cli/src/utils/schema-migrate.sql-driver-lookup.test.ts",
"packages/cli/src/utils/schema-migrate.ts",
"packages/cli/src/utils/unmanaged-tables.ts"
],
"before_after": [
"os migrate organization-ownership (plan), wasm-sqlite://: before exit 1 {error: plan_refused, reason: driver-unsupported, detail: 'no SQL driver with a raw-SQL seam is active'}; after exit 0, plan written, client null, database = the file",
"os migrate organization-ownership --apply --backup-taken --plan-file: before exit 1 {error: apply_refused, reason: driver-unsupported} (plan file from a native run of the same database); after exit 0, report kind organization-ownership-apply, all nine steps done, sys_migration row adr-0131-organization-ownership persisted in the file (read past the driver)",
"os migrate plan: before exit 0 {error: no_sql_driver, changes: []}; list fix alone exit 0 with unmanagedTables unreadable ('the connected dialect (unnamed client) is not one this sweep enumerates tables on'); after exit 0, pending [], unmanagedTables read, 71 physical tables, matching the native file: run",
"os migrate apply: before exit 0 {error: no_sql_driver}, nothing created; after exit 0, 71 tables created and persisted (fresh file)",
"os migrate multi-value-columns: before exit 0 {error: no_sql_driver, targets: []}; after exit 0, targets [], database = the file",
"os migrate unmapped-columns --object sys_user: before exit 0 {error: no_sql_driver}; after exit 0, columns [], database = the file",
"duplicates, account-issuer, meta --stored, audit-metadata-bodies, comment-reactions, security-catalog-overlays, os storage orphans: before exit 0 with database 'unknown'; after exit 0, same counts, database = the file",
"recorded-by, resume, os secret rewrap, os secret orphans: exit 0, same answer before and after (no driver read)",
"value-shapes, files-to-references, summary-nulls: exit 1 'No app objects are loaded' before and after (the fixture artifact declares no object); files-to-references' driver read (planMediaColumnMove) not reached: NOT MEASURED",
"os serve with OS_ARTIFACT_URL=file://… declaring storage.notNull on a nullable column, database wasm-sqlite://: before booted ('Server is ready', the destructive drift only warned; stopped by timeout 120, exit 124, my own process); after exit 1, 'Refusing to boot — 1 destructive schema change(s) required', naming the column"
],
"callers": [
"SQL_DRIVER_SERVICES reader 1: findSqlDriverVia (its default names) -> findSqlDriver -> bootSchemaStack's stack.driver. Measured through 19 commands at the door (table above; files-to-references' driver read not reached) and pinned by the integration file (apply, plan, ceremony plan and apply)",
"reader 1 via findSqlDriverForKernel -> os serve's artifact-boot migration gate (OS_ARTIFACT_URL): measured at the door (before booted past a destructive change, after refused); not pinned by a new test (the gate's policy is pinned by artifact-boot-migration*.test.ts on fake drivers)",
"reader 2: DeferSchemaDdlPlugin.init iterates SQL_DRIVER_SERVICES and then every driver.* service, so it already armed the wasm driver before the fix (the H1 probe saw setDeferredDdl on it); the list change does not move it. Not separately measured",
"not a reader: findTelemetryDriver uses its own list ([driver.telemetry]); a sqlite-wasm primary gets no telemetry sibling on either path (telemetry-datasource.ts), so unchanged",
"not a reader, same family: serve.ts describeRegisteredDriver keeps its own list (carrier note above); not measured"
],
"pr_body_changes": []
}
Why: the dispatch's H2 told the dev to fold the unmanaged-table sweep in if the list fix made it reachable. It did: measured on the list fix alone, every wasm-sqlite://os migrate plan reported that section unreadable.
The change resolves the dialect through @objectstack/metadata-core's dialectOfDriver and adds no export. No open PR edits the file, and no other claim names it.
Landed: PR #23671 → a4b87ef556 (#23648). The card is closed completed, and pm:dispatched is stripped
domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-15T12:48Z · holder of claim 6189580848 (surface supplemented in 6191898538), released by this landing.
reading
value
queue
added_to_merge_queue 12:26Z, merged 12:47Z
origin/main
a4b87ef556: one parent (a queue squash), an ancestor of origin/main, 5 files +514 / −4 as reviewed at 0e446f4bf; no queue branch left
card
closed completed by the PR's Fixes #23648; pm:dispatched removed by targeted delete
Review chain: ACCEPT 6191888397 on a true-green head. No contract review was owed: no Clause-②: yes, no packages/spec/src/**, no governed path. The seat judged Clause-②: no itself, including the os serve artifact boot gate's behaviour change on wasm-sqlite://.
What landed:
SQL_DRIVER_SERVICES lists driver.com.objectstack.driver.sqlite-wasm. On a SQLite database served by SqliteWasmDriver, the organization-ownership ceremony and every os migrate command now find the driver, and no longer refuse it as driver-unsupported or no_sql_driver.
os migrate plan's unmanaged-table sweep resolves the dialect through dialectOfDriver.
The os serve artifact boot gate now applies its migration policy on such a database.
Activity
objectstack-fleet commentedon Oct 15, 2026
Triage: first grade ·
bug·priority:p1·target:v18·domain:cli·pm:queue· land after PR #23647 · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T09:55ZRead fresh.
os migrate organization-ownershipon a SQLite database served bySqliteWasmDriverrefuses withplan_refused / driver-unsupported("no SQL driver with a raw-SQL seam is active"), and its text says SQLite is supported. Measured at the public door by #23558's dev.SQL_DRIVER_SERVICES(packages/cli/src/utils/schema-migrate.ts:187) omitscom.objectstack.driver.sqlite-wasm.findSqlDriverreturns null onwasm-sqlite://, on*.wasm.db, and on the dev better-sqlite3 → wasm step-down.Grade p1 +
target:v18(「发版本优先的都 p1」):os migrate planon such a database meets the same lookup. The claimant measures it, and folds it in if it does.Lane
domain:cli.Order: it lands after PR #23647 (#23558, draft). That PR's
dialectOfDriveris what resolves the wasm driver tosqliteonce it is found, so a fix on today'smainwould only move the refusal.Scope:
wasm-sqlite://database;driver-unsupported.driver.*match: a non-SQL driver must still refuse.findingleaves on grading.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 3, the maintainer's direct dispatch (#23648:
findSqlDriverfinds a SQLite database served bySqliteWasmDriver, soos migrate organization-ownershipno longer refuses it asdriver-unsupported) · 2026-10-15T10:06ZSession:
session_01FLwgbTSmGMrqsXkBDsiwfGAccount:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23648-sqlite-wasm-sql-driverWorktree:
objectstack-issue-23648Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)Provenance: the maintainer, in this seat's session chat,
session_01FLwgbTSmGMrqsXkBDsiwfG, 2026-10-15 about 10:05Z, verbatim: 「23648」. This seat reads it as a direct dispatch to this seat (execution-duties.md〈取卡〉: a maintainer-directed card goes first). It does not exempt the card from file serial, landing order or the claim protocol.File surface (read on
origin/mainc5dd7fce3; stop on a breach and explain it in the report):packages/cli/src/utils/schema-migrate.ts:SQL_DRIVER_SERVICES(:187) and the lookups that read it (findSqlDriverVia:194,findSqlDriver:208,findSqlDriverForKernel:232). The wasm driver is found by its service name,com.objectstack.driver.sqlite-wasm(packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver.ts:68). ⛔ Not a catch-alldriver.*match: a non-SQL driver still refuses (triage6189384099).packages/cli/src/**. ⛔ Not inside the files PR fix(cli): the organization-ownership ceremony reads its dialect once, through metadata-core's shared resolver, and refuses an unresolved one before any statement #23647 edits (organization-ownership*.tsand their tests,packages/metadata-core/src/legacy-organization-row*.ts).Container & model:
M(a one-list fix whose proof needs awasm-sqlite://rig, plus the unmeasuredos migrate planquestion),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier --repo objectstack-ai/objectstack packages/cli/src/utils/schema-migrate.ts: "no path-derived mandate … The tier stays the PM's per-card judgment call")Clause-②: no
Basis for the Clause-② line: this removes a refusal that the ceremony's own published text already negates. The text reads "The ceremony supports SQLite, PostgreSQL and MySQL." (
packages/cli/src/commands/migrate/organization-ownership.ts:345and:516,packages/cli/src/utils/organization-ownership-plan.ts:576, onorigin/main). A SQLite database refused asdriver-unsupportedis the mis-refusal that text denies. No other driver's answer moves, and no new export is added.Responsibility:
packages/cli's schema-stack driver lookup, platform code in this lane | none: the only route through v18's boot refusal for a 17.x database is this ceremony (ADR-0131 D10, triage6189384099) | an operator of a SQLite database onwasm-sqlite://, on*.wasm.db, or on the dev better-sqlite3 → wasm step-down; measured at the public door by cli: the organization-ownership ceremony resolves its SQL dialect from config.client as a string only (dialectOf, resolvePlannedDriverExec, the template-lookup guard), and falls back to sqlite on a client class or an unrecognised value #23558's dev (6189072331)Thread-read: 6189384099
Serial constraints cleared, and the landing order:
schema-migrate.ts: no open PR edits it (every open PR's file list was read in this act), and nopm:dispatchedclaim names it.6189384099): this lands AFTER PR fix(cli): the organization-ownership ceremony reads its dialect once, through metadata-core's shared resolver, and refuses an unresolved one before any statement #23647 (cli: the organization-ownership ceremony resolves its SQL dialect from config.client as a string only (dialectOf, resolvePlannedDriverExec, the template-lookup guard), and falls back to sqlite on a client class or an unrecognised value #23558,domain:cliseat 2, draft). That PR'sdialectOfDriveris what resolves the found driver tosqlite.claude/issue-23558-ceremony-dialect-resolverinto this branch, without rewriting it, and never edits its files.mainis merged in, so its diff is this card's alone, and the seat queues it.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{ "issue": 23648, "status": "done", "branch": "claude/issue-23648-sqlite-wasm-sql-driver", "pr": "https://github.com/objectstack-ai/objectstack/pull/23671", "session": "session_01FLwgbTSmGMrqsXkBDsiwfG — the dispatching seat's session (mode:subagent inherits the parent's)", "premise_still_valid": true, "summary": "SQL_DRIVER_SERVICES (packages/cli/src/utils/schema-migrate.ts) now lists driver.com.objectstack.driver.sqlite-wasm, the one driver.* key a wasm-sqlite:// boot registers (measured by listing every driver.* service of a real bootSchemaStack boot). It is a name in the list, not a driver.* pattern: a driver without detectManagedDrift/applyMigrationEntries stays unfound under any key, and a SQL driver under an unlisted key stays unfound, so the ceremony still refuses driver-unsupported on both (pinned). H2 held: os migrate plan met the same lookup ({\"error\":\"no_sql_driver\",\"changes\":[]}, exit 0), and once the driver was found its unmanaged-table sweep (unmanaged-tables.ts readPhysicalTableNames) read config.client as a string only and reported the section unreadable for this driver's client class, so the sweep now resolves the dialect through metadata-core's dialectOfDriver (folded in; this is the carrier note in PR #23647 that said 'no reach today', which this change made false). H3 and H4 held. PR #23647 landed on main during this run (c2bb302c8 from head 107a7a923c, which this branch had merged as one merge commit); main was then merged in twice (286eb9ef3, 1ced0f82b), so the PR's file diff is this card's 5 files. Final head 0e446f4bf.", "tests": "Final head 0e446f4bf, under the verify lock. unit project by path (new schema-migrate.sql-driver-lookup.test.ts, unmanaged-tables.test.ts, test/published-subpath-console.pin.test.ts, test/published-subpath-hook-body.pin.test.ts): 4 files, 82 tests passed, FINAL_UNIT_EXIT=0. integration project by path (new commands/migrate/sqlite-wasm.integration.test.ts, utils/unmanaged-tables.integration, utils/organization-ownership-plan.integration, utils/schema-migrate.integration, commands/migrate/plan.boot-parity, plan.deferred-reads, plan.reads-env-files, plan.telemetry-sibling): 8 files, 33 tests passed, FINAL_INT_EXIT=0 (run locally: the diff adds an integration-tier file and changes the sweep those suites read). On 1eb7378cd (same cli code; the later merge brought only .claude/** and scripts/pm/**): the whole cli unit layer, 290 of 292 files and 4325 tests passed; the 2 failed files refused 'packages/cli is not built (./dist/index.js is absent)', a missing prerequisite, and both passed on the final head after the cli was built. cli typecheck (tsc --noEmit and check:test-typecheck): TYPECHECK_EXIT=0 on 1eb7378cd. New-file readings: the unit file 12 tests, tests 8.20s (first command case 7.65s, oclif config load); the integration file 3 tests, tests 7.27s incl. its beforeAll seed; shared box. Ablation 1 (a4b58bf18, scripts/ablation-replace.mjs WRAP mode plus a bash EXIT INT TERM --restore trap): the new key deleted from SQL_DRIVER_SERVICES, on disk anchor 1 -> 0, blob b1fcdf46db73 -> a46e1ec56ca9, grep count 0; unit 3 red / 9 green (the three wasm positives red, all six command controls, two lookup controls and the no-regression case green); integration 3 red / 0 green ('no_sql_driver', exit 1); restored blob == HEAD b1fcdf46db73, git diff HEAD empty. Ablation 2 (a4b58bf18, same tooling): the sweep returned to the string-only client read, anchor 1 -> 0, marker 1, blob c647aec174bc -> a2097e2e9892; integration 1 red / 2 green (the os migrate plan case: unreadable); restored blob == HEAD c647aec174bc, git diff HEAD empty. Direction observed: red, as expected. No dist involved: subjects are cli src imported relatively, metadata-core aliased to src in the cli vitest config.", "gates": "Local, on 0e446f4bf: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 64 commands from merge base 1ced0f82b over the 5 changed paths (no PR #23647 path: it is on main, so no derived command reads its files on this head). All 64 run sequentially, each exit captured before any pipe: 64 of 64 exit 0. --ran ran2.list: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. First pass (1eb7378cd): check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity exited 3 (PREREQUISITE NOT MET) and check:type-check-debt exited 3 (its closure build hit the lock's queue budget); all five exit 0 on 0e446f4bf after a turbo build of their named closures (74 tasks, VERDICT command-exit 0). Ratchet families check:type-check-coverage and check:type-check-debt: exit 0. Lint lane blind spot: eslint --no-inline-config packages/cli exit 0, no output; a JSON-format run over the 4 changed .ts files: 0 errors, 0 warnings, 0 suppressed each. Control-byte self-scan of the 5 changed files: no hit. CI check-runs on PR head 0e446f4bf, read once right after the PR opened: 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; in_progress: Check Changeset, Check Documentation Links, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, Lint · CI release and engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs and code guards, Lint · repo and tooling gates, Lint · scoped (query-options erasure, slot lookup and corpus, tooling self-tests), No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, filter. Test Core and Build Core had not appeared. CI convergence is the PM's.", "mcp_calls": "0 — no MCP tool used; reads went through gh api (GET only) and the public issue page", "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204 each), executed as objectstack-fleet[bot]. (1) request fw-20261015T120922Z-ba853b, run 38732517878, conclusion success: pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft, PR #23671) and POST /repos/objectstack-ai/objectstack/issues/23671/assignees (os-bill); body read back identical, 11982 bytes, and re-read by REST: draft true, head 0e446f4bf, assignees [os-bill]. (2) this os-dev-report comment: POST /repos/objectstack-ai/objectstack/issues/23648/comments. Labels: zero writes, as dispatched. git push is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · os serve keeps a second hand-written list of driver service names (describeRegisteredDriver, packages/cli/src/commands/serve.ts) that also omits sqlite-wasm; serve reads it only to label its banner when it resolved no driver label itself. Not measured, not changed. In PR Acceptance notes only", "carrier: 承接者:无 · os migrate duplicates passes String(config.client) as its client (packages/cli/src/commands/migrate/duplicates.ts); for SqliteWasmDriver that string is the client class's source text, now reachable since the driver is found. It only selects MySQL backtick quoting, so SQLite quoting stays right, and it is not echoed: measured, the duplicates report on the wasm database matched the before run apart from the database name, and no command output carried the class text. In PR Acceptance notes only", "carrier: 承接者:无 · packages/cli/src/commands/migrate/organization-ownership.dialect.test.ts (PR #23647's file, on main) says in its header that the command's boot 'does not hand that driver over today'; after this PR it does. Not edited (a PR #23647 file). In PR Acceptance notes only" ], "line_budget": "n/a", "deviations": [ "File surface: packages/cli/src/utils/unmanaged-tables.ts is outside the claim's declared surface (schema-migrate.ts, new pins, one changeset), whose header says to stop on a breach. Not stopped, and named here rather than chosen silently: the dispatch's H2 says 'If it does, fold it in and pin it', and os-dev.md requires fixing a shipped defect the change makes reachable. With only the list fix every wasm-sqlite:// os migrate plan reported its unmanaged-table section unreadable on a SQLite database (measured at 030a6d826). The fix uses dialectOfDriver, already exported on main; no new export. No open PR or claim holds that file (every open PR's file list read). For the seat: supplement the claim's file surface with that path.", "Main merged twice: 286eb9ef3 (after PR #23647 landed, before the PR opened), then 1ced0f82b on the coordinator's update, which touched only .claude/skills/pm-dispatch/references/contract-review.md and scripts/pm/record-recognisers.mjs. The derived gate list was re-derived on 0e446f4bf (byte-identical, 64) and the whole battery re-run there; the pins were re-run there.", "The first nine commands of the final gate battery ran while the locked turbo closure build was rewriting dist/ (gates do not take the lock); they are base-diff checks and self-tests, and every one of the 64 exited 0.", "Before/after door readings come from three shas: before at 60ae7a6a8 (or its two files restored from it, trap-restored, blob == HEAD after); after at 030a6d826 for the ceremony --apply and the fresh-file os migrate apply, and at 525ecbe67 for the rest; the os serve gate at a4b58bf18. The cli code moved after that only by the pins and the changeset.", "Commit trailers are the dispatch's model-free pair (Co-Authored-By: Claude, Claude-Session); the harness's model-named trailer was not used." ], "files_changed": [ ".changeset/23648-sqlite-wasm-sql-driver.md", "packages/cli/src/commands/migrate/sqlite-wasm.integration.test.ts", "packages/cli/src/utils/schema-migrate.sql-driver-lookup.test.ts", "packages/cli/src/utils/schema-migrate.ts", "packages/cli/src/utils/unmanaged-tables.ts" ], "before_after": [ "os migrate organization-ownership (plan), wasm-sqlite://: before exit 1 {error: plan_refused, reason: driver-unsupported, detail: 'no SQL driver with a raw-SQL seam is active'}; after exit 0, plan written, client null, database = the file", "os migrate organization-ownership --apply --backup-taken --plan-file: before exit 1 {error: apply_refused, reason: driver-unsupported} (plan file from a native run of the same database); after exit 0, report kind organization-ownership-apply, all nine steps done, sys_migration row adr-0131-organization-ownership persisted in the file (read past the driver)", "os migrate plan: before exit 0 {error: no_sql_driver, changes: []}; list fix alone exit 0 with unmanagedTables unreadable ('the connected dialect (unnamed client) is not one this sweep enumerates tables on'); after exit 0, pending [], unmanagedTables read, 71 physical tables, matching the native file: run", "os migrate apply: before exit 0 {error: no_sql_driver}, nothing created; after exit 0, 71 tables created and persisted (fresh file)", "os migrate multi-value-columns: before exit 0 {error: no_sql_driver, targets: []}; after exit 0, targets [], database = the file", "os migrate unmapped-columns --object sys_user: before exit 0 {error: no_sql_driver}; after exit 0, columns [], database = the file", "duplicates, account-issuer, meta --stored, audit-metadata-bodies, comment-reactions, security-catalog-overlays, os storage orphans: before exit 0 with database 'unknown'; after exit 0, same counts, database = the file", "recorded-by, resume, os secret rewrap, os secret orphans: exit 0, same answer before and after (no driver read)", "value-shapes, files-to-references, summary-nulls: exit 1 'No app objects are loaded' before and after (the fixture artifact declares no object); files-to-references' driver read (planMediaColumnMove) not reached: NOT MEASURED", "os serve with OS_ARTIFACT_URL=file://… declaring storage.notNull on a nullable column, database wasm-sqlite://: before booted ('Server is ready', the destructive drift only warned; stopped by timeout 120, exit 124, my own process); after exit 1, 'Refusing to boot — 1 destructive schema change(s) required', naming the column" ], "callers": [ "SQL_DRIVER_SERVICES reader 1: findSqlDriverVia (its default names) -> findSqlDriver -> bootSchemaStack's stack.driver. Measured through 19 commands at the door (table above; files-to-references' driver read not reached) and pinned by the integration file (apply, plan, ceremony plan and apply)", "reader 1 via findSqlDriverForKernel -> os serve's artifact-boot migration gate (OS_ARTIFACT_URL): measured at the door (before booted past a destructive change, after refused); not pinned by a new test (the gate's policy is pinned by artifact-boot-migration*.test.ts on fake drivers)", "reader 2: DeferSchemaDdlPlugin.init iterates SQL_DRIVER_SERVICES and then every driver.* service, so it already armed the wasm driver before the fix (the H1 probe saw setDeferredDdl on it); the list change does not move it. Not separately measured", "not a reader: findTelemetryDriver uses its own list ([driver.telemetry]); a sqlite-wasm primary gets no telemetry sibling on either path (telemetry-datasource.ts), so unchanged", "not a reader, same family: serve.ts describeRegisteredDriver keeps its own list (carrier note above); not measured" ], "pr_body_changes": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Claim surface, supplemented ·
domain:cliseat 1 (#6024) ·os-bill· 2026-10-15T12:19ZThe claim's file surface gains one path:
packages/cli/src/utils/unmanaged-tables.ts(readPhysicalTableNames).Why: the dispatch's H2 told the dev to fold the unmanaged-table sweep in if the list fix made it reachable. It did: measured on the list fix alone, every
wasm-sqlite://os migrate planreported that section unreadable.The change resolves the dialect through
@objectstack/metadata-core'sdialectOfDriverand adds no export. No open PR edits the file, and no other claim names it.The seat's ACCEPT on PR #23671 records the check.
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Landed: PR #23671 →
a4b87ef556(#23648). The card is closedcompleted, andpm:dispatchedis strippeddomain:cliseat 1 (#6024) ·os-bill· sessionsession_01FLwgbTSmGMrqsXkBDsiwfG· 2026-10-15T12:48Z · holder of claim6189580848(surface supplemented in6191898538), released by this landing.added_to_merge_queue12:26Z, merged 12:47Zorigin/maina4b87ef556: one parent (a queue squash), an ancestor oforigin/main, 5 files +514 / −4 as reviewed at0e446f4bf; no queue branch leftcompletedby the PR'sFixes #23648;pm:dispatchedremoved by targeted delete6191888397on a true-green head. No contract review was owed: noClause-②: yes, nopackages/spec/src/**, no governed path. The seat judgedClause-②: noitself, including theos serveartifact boot gate's behaviour change onwasm-sqlite://.SQL_DRIVER_SERVICESlistsdriver.com.objectstack.driver.sqlite-wasm. On a SQLite database served bySqliteWasmDriver, the organization-ownership ceremony and everyos migratecommand now find the driver, and no longer refuse it asdriver-unsupportedorno_sql_driver.os migrate plan's unmanaged-table sweep resolves the dialect throughdialectOfDriver.os serveartifact boot gate now applies its migration policy on such a database.packages/cli/src/utils/schema-migrate.tsandunmanaged-tables.ts. cli: organization-ownership --apply column-drops refuses a host-declared platform-global object (ADR-0131 D7) whose fate is column-drop — "not proposed for dropping by the schema-drift ceremony" #23666's claim (this seat) is no longer serial behind this one.serve.ts'sdescribeRegisteredDriverlist omits sqlite-wasm; it labels the banner only.duplicates.tspassesString(config.client). Measured: it does not change quoting and is not echoed.organization-ownership.dialect.test.tsis stale.Generated by Claude Code