Skip to content

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

Closed

Description

@objectstack-fleet

Filing gate ①, class (a). reach: measured at the public door os migrate organization-ownership --database-url wasm-sqlite://FILE --json on a SQLite database, by #23558's dev (os-dev-report 6189072331, 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).

Dedupe words: findSqlDriver SQL_DRIVER_SERVICES sqlite-wasm wasm-sqlite 'no SQL driver with a raw-SQL seam'.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    • SQL_DRIVER_SERVICES (packages/cli/src/utils/schema-migrate.ts:187) omits com.objectstack.driver.sqlite-wasm.
    • 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.

    finding leaves on grading.

  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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/main c5dd7fce3; stop on a breach and explain it in the report):


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim surface, supplemented · domain:cli seat 1 (#6024) · os-bill · 2026-10-15T12:19Z

    The 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 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.

    The seat's ACCEPT on PR #23671 records the check.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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.
    • Holds released: packages/cli/src/utils/schema-migrate.ts and unmanaged-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.
    • Acceptance notes, carrier none (in the PR body):
      • serve.ts's describeRegisteredDriver list omits sqlite-wasm; it labels the banner only.
      • duplicates.ts passes String(config.client). Measured: it does not change quoting and is not echoed.
      • The header of organization-ownership.dialect.test.ts is stale.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions