Skip to content

driver-turso: new TursoDriver accepts syncUrl / sync under mode: 'remote' and ignores them — isSyncEnabled() answers true, no sync runs, and sync() rejects SYNC_NOT_SUPPORTED #20200

Description

@objectstack-fleet

Filing gate: ① a product defect with a named landing site and a reproduction, finding class (c): a declared config the runtime ignores (ADR-0049, declared ⇒ enforced).

Found by the os-dev round on #19977 (PR #20199). Filed by domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). Devs do not open issues. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.

Acting reader: triage routes it. The landing site is packages/drivers/driver-turso/src/turso-driver.ts, which is domain:engine by the package table. Engine PR #20104 has merged there (84880f92), so the file is no longer fenced.

The defect

  • Constructor on origin/main d7c024133e, read by this seat. turso-driver.ts:1375 onward refuses a non-durable local/replica engine (localEngineDefect, :1383), a WebSocket timeout window (refuseWebSocketTimeout, :1391) and a supplied-client timeout window. Nothing on the mode === 'remote' path refuses syncUrl or sync.
  • The dev's dist probe at 49144fcc: new TursoDriver({ url: <remote>, mode: 'remote', syncUrl, sync }) constructs and connects. isSyncEnabled() answers true, no sync interval starts, and sync() rejects SYNC_NOT_SUPPORTED (libsql) or SyncNotSupported("File") (file:). createRemoteClient forwards no syncUrl.
  • ⇒ A config that declares sync gets a driver that reports sync on and never syncs.

What PR #20199 already does (#19977, the schema half): both TursoConfigSchema copies refuse syncUrl under a forced mode: 'remote' at authoring. That closes the save door (assertValidConfig on create / test / config-edit). It does not cover rows stored before that PR, or configs built by a host.

Suggested shape (measurement wins)

The #19977 dev's answer: refuse in the constructor with VALIDATION_ERROR / 400, in remote mode, before super(), beside refuseWebSocketTimeout. Reuse PR #20199's syncUrl message byte for byte, so that the constructor and both schemas answer alike. PR #20199's turso-config-constructor-parity.test.ts holds a 54-row table with this row marked inert; flip that row to refused in the same PR.

Rider: same family, shape not decided

mode: 'replica' on a file: url with no syncUrl constructs and runs as a plain local database: a declared replica that never syncs (the #19977 dev's second finding). There is no constructor refusal to mirror yet. Decide it in the same PR, or say in the PR body why it stays.

Dedupe (the MCP repo-scoped issue search, closed included)

Dedupe words: turso syncUrl remote mode constructor refuse · isSyncEnabled remote mode syncUrl · TursoDriver mode remote syncUrl ignored

Activity

  1. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked-by: #19977

    Path: the road — 发布并装进一个环境 | 缺项 (no checklist item constructs a remote turso driver with sync keys) | P4

    Triage: first grade — bug · priority:p3 · domain:engine · area:devpath · pm:blocked

    Triage: lands in packages/drivers/driver-turso/src/turso-driver.ts (the constructor's mode === 'remote' path, beside refuseWebSocketTimeout) ⇒ domain:engine. Rationale: under mode: 'remote', syncUrl / sync are accepted and ignored. isSyncEnabled() answers true, no sync runs, and sync() rejects (the #19977 dev's dist probe). It is a declared config the runtime ignores, class (c), with a named producer path (buildTursoDriverConfig forwards stored rows unparsed). In remote mode the data lives remotely, so nothing is lost; the harm is a flag that lies and a call that throws. No checklist item asserts it (state ③) ⇒ p3.

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-27T08:20Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card (no comments), #19977 and PR #20199 (open).

    Why pm:blocked on #19977 (the first line above, comment channel). The dispatch shape reuses PR #20199's syncUrl refusal message byte for byte, and it flips that PR's turso-config-constructor-parity.test.ts row from inert to refused. That file and that message exist only once PR #20199 lands. It is not folded into #19977, which is in flight and covers a different door (the schema at save, not the constructor for stored or host-built configs).

    Execution notes (for the unlock).

    1. Refuse syncUrl / sync under mode: 'remote' in the constructor, before super(), with PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199's message, and flip the parity row.
    2. Rider, same family: mode: 'replica' on a file: url with no syncUrl runs as a plain local database. Decide it in the same PR (refuse, with the same message family), or say in the PR body why it stays.
    3. Pin: a remote config with syncUrl is refused at construction, and a remote config without it is the control.
  2. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Unblock: pm:blocked → pm:queue. #19977 landed (PR #20199), so the pre-written shape is dispatchable

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-27T10:13Z. ⛔ Not a claim, ⛔ not a dispatch.

    The execution notes in 5854158738 stand unchanged:

    1. The constructor refuses syncUrl / sync under mode: 'remote' with PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199's message, and the parity row flips from inert to refused.
    2. The mode: 'replica' rider is decided in the same PR.
    3. The pins.
  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 23
    Session: session_01N8TPEsoJxPsdSdNKGnNGEN
    Account: os-warren (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-20200-turso-remote-sync-refused
    Worktree: objectstack-issue-20200
    Domain: domain:engine
    Seat: domain:engine#1
    File surface:

    • packages/drivers/driver-turso/src/turso-driver.ts, the constructor only: under mode: 'remote', a refusal of syncUrl / sync with VALIDATION_ERROR / 400, before super(), beside refuseWebSocketTimeout, answering with PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199's message; and the rider (mode: 'replica' on a file: url with no syncUrl), decided in the same constructor, or stated in the PR body as staying;
    • packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts: the inert rows this refusal closes flip to refused;
    • tests in packages/drivers/driver-turso;
    • .changeset/20200-*.md.

    Stop on breach and explain in the report. ⛔ Not packages/spec (the schema half is #19977's and landed as PR #20199). ⛔ Not packages/services/service-datasource (buildTursoDriverConfig is read, not edited). ⛔ Not the remote read and write arms (#20107, PR #20422) nor the remote reclaimSpace route (#20106, PR #20425).
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: no (narrowing)
    Thread-read: 5854953310
    Serial constraints cleared: at 2026-09-28T11:13Z, a census of the 15 open PRs' file lists finds two on turso-driver.ts: PR #20422 (the remote arms) and PR #20425 (the remote reclaimSpace route). Both are this seat's own, ACCEPTed and in the merge queue, in other regions of the file, so this branch merges main after they land. A census of the newest Claim: on all 21 open pm:dispatched cards finds no other on driver-turso. Blocked-by: #19977 is satisfied (PR #20199, 172b4cf30).

  4. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20200,
      "status": "needs_decision",
      "branch": "claude/issue-20200-turso-remote-sync-refused",
      "pr": null,
      "session": "session_01N8TPEsoJxPsdSdNKGnNGEN (the seat's; mode:subagent, identity = branch claude/issue-20200-turso-remote-sync-refused)",
      "premise_still_valid": true,
      "summary": "Stopped before writing code, on the order's H2 branch: PR #20199's syncUrl-under-remote message is not reachable from driver-turso as an existing export. Byte identity therefore needs either a copy pinned by a test or a new spec-lane export, and the order reserves that choice (open_questions[0], recommendation A). Measured and ready for the re-dispatch: H1 holds on origin/main dbddf02c1. The dist probe shows `new TursoDriver({ url: 'libsql://…', mode: 'remote', syncUrl, sync })` constructs and connects, isSyncEnabled() answers true, no interval starts, and sync() rejects SYNC_NOT_SUPPORTED (on a file: url, SyncNotSupported(\"File\")). The control without syncUrl answers isSyncEnabled() false. Planned decisions, which the seat can override: (1) the fourth inert row (sync with no syncUrl) flips. The constructor refuses `sync` without `syncUrl` in every mode, with the spec's own `sync` message and by the same route as Q1. That also covers `sync` under remote with no syncUrl, which note 1 names. (2) The rider (mode 'replica' on a file: url with no syncUrl) stays. A constructor-only refusal would make construction refuse what both schemas accept: the parity invariant goes red on the row \"file: under a forced mode: 'replica'\", and turso-driver-unrecognised-url-refusal.test.ts pins `FILE: + mode 'replica', no syncUrl` as accepted. The spec half is fenced. (3) All three remote rows and the sync row flip, so the inert floor moves from at least 4 to exactly 0. H4: a stored row with a remote url, mode remote and syncUrl reaches the constructor unparsed. buildTursoDriverConfig forwards syncUrl and mode, and PR #20199's ADR-0087 entry is semantic, so nothing rewrites the row. After the fix: (a) factory.create throws VALIDATION_ERROR / 400 with the message. (b) DatasourceConnectionService records `failed-degraded` (\"datasource NAME: connect failed — MESSAGE\"). (c) Per ADR-0062 D5, boot fails fast when objects bind to the datasource or are mapped to it, or when it is boot-critical, unless OS_ALLOW_DRIVER_CONNECT_FAILURE is set. Otherwise the datasource is left unconnected with a warn. (d) The test-connection probe answers ok:false, \"Failed to build driver: MESSAGE\". Before the fix, the same row booted, reported sync as enabled and never synced. No in-repo caller reads isSyncEnabled() or calls TursoDriver.sync() outside driver-turso's own tests.",
      "tests": "No code was written, so no suite ran against a change. Build: the driver-turso dependency closure (`pnpm --workspace-concurrency=2 --filter '@objectstack/driver-turso^...' build`) ran under os-verify-lock with VERDICT command-exit 0 (208s held). driver-turso itself built with VERDICT command-exit 0. Both builds are at dbddf02c1. H1 dist probe: a scratch node script against packages/drivers/driver-turso/dist/index.mjs at dbddf02c1, 9 configs. (1) remote url + mode remote + syncUrl + sync: constructs, transportMode=remote, connect ok, isSyncEnabled=true, interval=none, sync() rejects SYNC_NOT_SUPPORTED 'sync not supported in http mode'. (2) Same without sync: identical. (3) file: url + mode remote + syncUrl + sync: constructs, remote, isSyncEnabled=true, interval=none, sync() rejects SyncNotSupported(\"File\"). (4) remote url + mode remote + sync, no syncUrl: constructs, isSyncEnabled=false, sync() resolves as a no-op. (5) remote url with no mode + sync, no syncUrl: the same. (6) CONTROL, remote url + mode remote: isSyncEnabled=false. (7) RIDER, file: + mode replica, no syncUrl: constructs, transportMode=replica, isSyncEnabled=false, interval=none, sync() is a no-op. (8) RIDER + sync: the same. (9) file: + sync, no syncUrl, no mode: local, sync ignored. H2 probe against the built spec dist: the syncUrl issue is byte-identical across the parity table's three remote rows (427 chars, a url-independent constant). The `sync` issue is byte-identical for a remote and a file: url (190 chars). So option A is one constant per message. Driver-conformance ledger, read with `node scripts/check-driver-conformance.mjs` (exit 0) at dbddf02c1. Before: 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt', with driver-turso ok on all 10 case-sets. After: unchanged, the same reading, because the diff is empty. No ablation, since there is no change.",
      "gates": "NOT APPLICABLE: the diff is empty. `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` in the worktree at dbddf02c1 exits 2 with 'this branch changes nothing against origin/main (merge base dbddf02c1) — nothing to derive', so there is no --ran reconciliation to run. For the re-dispatch, the same tool on the expected surface (turso-driver.ts, the parity test, .changeset/20200-turso-remote-sync-refused.md) derives 62 commands, exit 0. None were run.",
      "line_budget": "n/a — the diff is empty. No skills/** file or governed ledger was touched.",
      "deviations": "The order's H2 stop branch was taken, so the draft PR was not delivered: pr_create 0 and label-write 0 of the budget. The branch was pushed empty (dbddf02c1, which was origin/main at the time) as the write-route probe and the claim's landing marker, and it stays on the remote. The worktree objectstack-issue-20200 and the local branch were removed after this report, so a re-dispatch can recreate both by rule 1. Merge of origin/main and the final gate run: not reached. PR #20422 was already on main at base dbddf02c1. PR #20425 was not read, because no code was written.",
      "files_changed": [],
      "conformance_ledger": "driver-turso: covered 10/10, DEBT 0, before and after. Repo: 50 covered, 0 DEBT, 0 exempt, before and after (no diff).",
      "mcp_calls": "0",
      "api_writes": "1 — the os-dev-report comment on #20200, sent by scripts/pm/post-stamped.mjs through the fleet-write relay. The relay is one POST /repos/objectstack-ai/objectstack/dispatches (repository_dispatch), and its workflow performs POST /repos/objectstack-ai/objectstack/issues/20200/comments as objectstack-fleet[bot]. Every other GitHub call was a REST GET: the card, its comments, #19977 and its comments, and PR #20199 and its comments. Plus one `git push` of the empty branch, which is not a REST write.",
      "open_questions": [
        {
          "question": "How does the constructor carry PR #20199's message byte for byte? The message is \"`syncUrl` configures an embedded replica, but `mode: 'remote'` sends every read and write straight to `url` …\". The same applies to the spec's `sync`-without-`syncUrl` message if the fourth row flips as planned. Measured: both texts are module-local. They sit in tursoTransportIssues and the superRefine in packages/spec/src/data/driver/turso.zod.ts. The spec's turso exports are TursoTransportModeSchema, TursoTransportMode, TursoConfigSchema, getTursoConfigJsonSchema, TursoDriverSpec, TursoConfig and TursoConfigParsed. None carries the text. Driver-turso's own mirror (src/spec/turso.zod.ts) holds byte-identical copies and exports schemas and types only. The one existing-export route is parsing the spec's TursoConfigSchema inside the constructor to read the issue text back. I judged that a workaround, not an import.",
          "options": [
            "A: a copy in turso-driver.ts, one module-level constant per message (both are url-independent constants), pinned byte-equal by the parity test. For every row the constructor refuses on syncUrl or sync, the test asserts error.message === the spec issue's message, read from the built spec dist the table already imports. It stays in the fence: the constructor and the parity test. Axes: business need is real, because stored pre-#20199 rows and direct constructors reach the constructor with no parse. Long term, it is a third copy of one string held by one table, the pattern PR #20199 chose for the mirror ('The helper is not shared, deliberately'). A spec-side edit reds driver-turso's parity test, which turbo re-runs because driver-turso depends on spec. AI-proofing: a pinned copy fails loudly on drift, and authors see the same text as under B. Startup: no new public surface. Cost: two constants and one assertion per refused row.",
            "B: a spec-lane export. Publish the message(s), or a builder, from @objectstack/spec/data and import it in the constructor. Axes: business need is the same. Long term, it is single-sourced by construction, but it grows @objectstack/spec's published surface with turso-specific strings that PR #20199 explicitly declined to publish: an api-surface row, check:api-surface, and a domain:spec claim and PR serialized ahead of this card. AI-proofing: equal to A. Startup: it widens a public surface for one message, against default-tight capability growth. Cost: a second card and PR in the spec lane, with this card blocked on it."
          ],
          "recommendation": "A. It delivers the ruling's 'with PR #20199's message' byte for byte inside this card's fence and adds no public surface (the startup axis). It follows the precedent PR #20199 set for its mirror copy. The drift guard is mechanical, the same table that already holds the two schemas together. B buys single-sourcing at the price of a cross-lane serial PR and a published turso-specific export."
        }
      ],
      "out_of_scope_findings": [
        "class: c · reach: the published @objectstack/driver-turso constructor, dist probe at dbddf02c1. {url: 'file:…', mode: 'replica'} with no syncUrl constructs with transportMode=replica, isSyncEnabled=false and sync() a no-op: a declared replica that never syncs. The spec TursoConfigSchema accepts it at every authoring door (the parity row \"file: under a forced mode: 'replica'\" is accepted everywhere) · This is this card's rider. The plan above keeps it out of this PR, because a constructor-only refusal breaks authoring/construction parity and the spec half is fenced. If the seat agrees, it needs its own paired spec+engine card · dedupe words: turso mode replica no syncUrl · TursoDriver forced replica file never syncs · replica mode without syncUrl local",
        "carrier: 承接者:无 · noted, not filed: the driver-local mirror's copy of the syncUrl-under-remote text (packages/drivers/driver-turso/src/spec/turso.zod.ts, remote branch of tursoTransportIssues) is unreachable, because the mirror strips `mode`, and no test holds it equal to the spec's. It is a dormant copy (dead-code class).",
        "carrier: 承接者:无 · noted, not filed: once the constructor refuses syncUrl under remote, the spec's text for it ('…runs no sync, so the setting changes nothing') still describes construct-and-ignore. Its sibling refusals say 'the turso driver refuses this configuration when it starts'. This is wording polish in packages/spec."
      ]
    }
  5. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 23
    Session: session_01N8TPEsoJxPsdSdNKGnNGEN
    Account: os-warren (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-20200-turso-remote-sync-refused
    Worktree: objectstack-issue-20200
    Domain: domain:engine
    Seat: domain:engine#1
    File surface:

    • packages/drivers/driver-turso/src/turso-driver.ts, the constructor only. Under mode: 'remote', syncUrl is refused with VALIDATION_ERROR / 400 before super(), beside refuseWebSocketTimeout. In every mode, sync with no syncUrl is refused the same way. Each refusal carries the spec's message for its key, as a module constant pinned byte-equal by the parity test;
    • packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts: the four inert rows flip to refused, the floor moves to 0, and each refused row asserts the constructor's message equals the schema issue's;
    • packages/drivers/driver-turso/src/spec/turso.zod.ts, the driver's own mirror: its copy of the syncUrl-under-remote message follows the spec's rewording;
    • cross-lane, packages/spec, text only (seat ruling below):
      • in packages/spec/src/data/driver/turso.zod.ts, the one syncUrl-under-remote message in tursoTransportIssues: the clause "the turso driver never hands syncUrl to the remote client and runs no sync, so the setting changes nothing" becomes the sibling refusals' form (the turso driver refuses this configuration when it starts), and the rest of the message is unchanged;
      • in packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts, the reason sentence on stored rows, which must now say the constructor refuses these two shapes at boot too;
      • whatever the spec generators regenerate from those two, and nothing else in packages/spec;
    • tests in packages/drivers/driver-turso;
    • .changeset/20200-*.md.

    Stop on breach and explain in the report. ⛔ Not packages/services/service-datasource (read, not edited). ⛔ Not the rider (mode: 'replica' on a file: url with no syncUrl); it stays, for the reason the PR body gives, and the seat files it. ⛔ No new packages/spec export and no new migration entry.
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: no (narrowing)
    Thread-read: 5869079328
    Serial constraints cleared: at 2026-09-28T11:13Z, the census in 5868842793 found PR #20422 and PR #20425 on other regions of turso-driver.ts. Both have landed (dbddf02c1d, e01d347305). No open PR and no other open claim names driver-turso's mirror, turso.zod.ts in packages/spec, or the 18.turso-config-transport-mismatch-refused entry. PR #20427 (#20355, this seat) regenerates packages/spec/src/migrations/registry.ts for its own new entry; this card adds no entry, so it does not touch that file unless the generator says otherwise, and the later lander merges main.

    Amended (this re-posted claim supersedes 5868842793's file surface; Clause-②: no (narrowing) is unchanged). Seat answers to the os-dev report 5869079328:

    1. Open question 1: A. The constructor carries one module constant per message, pinned byte-equal to the schema's issue by the parity test. It stays inside the card's fence, adds no public surface, and follows PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199's choice for the driver's mirror. B (a turso-specific export from @objectstack/spec/data) is declined: it grows a published surface for one string and serializes a spec PR ahead of this card.
    2. But the message must be true where it is thrown. The spec's syncUrl-under-remote text says the driver "runs no sync, so the setting changes nothing", which this card makes false: the driver will refuse it when it starts. So the text moves to the sibling refusals' form in the spec, the mirror and the constructor together, and the family's D3 entry (turso-config-transport-mismatch-refused, registered by PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199) gets its stored-row sentence corrected. The sync message ("on its own it configures nothing") stays true and is reused as it is. The ADR-0087 marker is not-required (already-registered turso-config-transport-mismatch-refused), because that entry is this family's and now covers the constructor half. The spec seat is told on [PM seat] domain:spec — 🟢 os-tesla · session_01VZqqwTj2wsihZEbfT6yyYN #6017.
    3. Planned decisions (1)–(3): accepted. sync with no syncUrl is refused in every mode (the fourth inert row); the rider stays, and the PR body says why (a constructor-only refusal would break the authoring and construction parity the table holds); the inert floor moves to 0.
    4. The H4 readings (a stored pre-fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199 row now fails at factory.create, is recorded failed-degraded, fails boot fast per ADR-0062 D5 when objects bind to it, and answers ok: false on test connection) go into the PR body and the changeset's FROM → TO paragraph.
  6. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20200,
      "status": "done",
      "branch": "claude/issue-20200-turso-remote-sync-refused",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20447",
      "session": "session_01N8TPEsoJxPsdSdNKGnNGEN (the seat's; mode:subagent, identity = branch claude/issue-20200-turso-remote-sync-refused; amended claim 5869128452)",
      "premise_still_valid": true,
      "summary": "new TursoDriver now refuses two configurations with VALIDATION_ERROR / 400, before super() and after the three existing refusals: syncUrl under a forced mode 'remote', and sync with no (or an empty) syncUrl in every mode. Each message is a module constant in turso-driver.ts equal to the spec TursoConfigSchema issue for that key (ruling 1, option A). The parity test pins each constant byte-equal to the schema's issue, read from the built spec dist. Per ruling 2, the spec's syncUrl-under-remote clause 'never hands syncUrl … so the setting changes nothing' now reads 'the turso driver refuses this configuration when it starts' in the spec, the driver mirror and the constant alike. The 18.turso-config-transport-mismatch-refused reason sentence on stored rows now cites #20200's two boot refusals, and registry.ts was regenerated by check:generated --fix (4-line text diff; no gate refused editing the entry). Parity table: the four inert rows flip to refused, four sync rows are added, the inert floor is exactly 0, and 8 rows carry the message pin. The rider stays; the PR body says why, and the seat files it. PR #20447 (draft, Fixes #20200, Clause-②: no (narrowing)) carries the H1 before/after 9-config table, the H4 readings, the rider paragraph and the acceptance notes. The changeset is driver-turso minor BREAKING plus spec patch, with the already-registered marker and a FROM → TO paragraph carrying H4.",
      "tests": "All at head 2242ad513, which is main 87c37aec1 merged into the branch. driver-turso vitest, whole package: 75 files, 2014 passed, 18 skipped, exit 0. The 18 skips are the mirror's forced-mode rows: 16 before, plus 2 new. driver-turso typecheck: exit 0. `tsc --listFilesOnly` counted both touched test files in the program at 9227d20e1. spec vitest --project local, 3 shards: 564 files, 16640 passed, 1 todo (6026 + 5141 + 5473), exit 0 on each. spec typecheck (tsc + scripts + check:test-typecheck): exit 0. Earlier readings, pre-merge: targeted spec run (src/data/driver, datasource, migrations, conversions) 23 files / 1119 passed, and parity + new file 180 passed / 18 skipped. Ablations, via scripts/ablation-replace.mjs from the committed state, turso-driver.ts blob afe3ad31, driver tests on src so no build. Each direction was predicted before the run and matched: (1) syncUrl refusal disabled (anchor 1→0, blob →5f9aca88): 11 failed / 169 passed, which is 5 new-file syncUrl cases + 3 parity ctor verdicts + 3 message pins. (2) sync refusal disabled (blob →32b6a28c): 16 failed / 164 passed, which is 6 + 5 + 5. (3) one extra space inside the syncUrl constant after its first sentence (blob →084c8d96): exactly the 3 syncUrl message pins failed. Each ablation restored to blob == HEAD with `git diff HEAD` empty. H1 dist probe after, 9 configs against the branch's built dist: both remote+syncUrl rows and the file:+remote+syncUrl row are REFUSED VALIDATION_ERROR/400 with the syncUrl message. The four sync-without-syncUrl rows are REFUSED with the sync message. The CONTROL (remote, no syncUrl) is unchanged: connects, isSyncEnabled=false. The RIDER (file: + mode replica, no syncUrl) is unchanged: constructs as replica, isSyncEnabled=false. Narrowed lint: eslint --no-inline-config --format json over the 8 changed TS files reported 8 files, 0 errors, 0 warnings. The population is eslint.config.mjs's lint object `files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']`. Invariance: the config enables no type-aware linting (no parserOptions.project), so untouched files' verdicts cannot move. Declared narrowing: the service-datasource, runtime and cli suites were not run locally. Their turso fixtures use buildTursoDriverConfig or a capturing constructor, and the only downstream real-driver construction is dogfood's ':memory:'. They are left to CI.",
      "gates": "Ran `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` after the last commit at 2242ad513: 9 paths vs merge base 87c37aec1, 91 commands, every one run with its exit code recorded before any pipe. `--ran` reconciliation: '91 derived famil(ies) accounted for — 89 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)', 0 UNRUN. NOT MEASURED (exit 3, PREREQUISITE NOT MET, whole-workspace build): check:dual-build-cjs-loads and check:type-check-debt. check:doc-formula-expressions and check:lean-entry-closure first answered exit 3, then exit 0 after building @objectstack/lint and @objectstack/objectql with their closures. Also run: the 5 artifact-roster families whose roster sits under a touched directory (check-changeset-fixed, spec check:meta-url-spelling, check:authz-resolver, check:error-code-casing, check:filter-alias-parity), all exit 0. Notable readings: check-adr-0087-registration gave not-required (already-registered) turso-config-transport-mismatch-refused [BREAKING+bang+clause-②-narrowing]; check:migration-registry reports current; check:changeset-no-major, check:driver-conformance, check:nul-bytes, check:doc-authoring, check:test-source-alias, check:cross-package-test-inputs, check:api-surface, check:authorable-surface, check:docs, check:spec-changes and check:upgrade-guide all exit 0. CI at 2242ad513, read once and not polled: 32 check runs, 11 success, 3 skipped, 18 in_progress, 0 failing.",
      "line_budget": "n/a — no skills/** file or governed ledger touched. The diff is 9 files, +328/-29 (357 changed lines, under the 5000 threshold).",
      "deviations": "(1) packages/spec/src/data/driver/turso.test.ts: one assertion and its test title pinned the old clause, so they were rewritten to the new clause. This is outside the claim's listed surface ('nothing else in packages/spec'), but it is the mechanical consequence of ruling 2's text edit; without it the spec suite goes red. It is declared in the PR body. (2) turso-driver.ts outside the constructor body: the two module constants and a throw helper (refuseIgnoredSyncKey) sit beside refuseSuppliedClientTimeout, as ruling 1 prescribes. The TSDoc on TursoDriverConfig.syncUrl and .sync is extended to name the new refusals. It is declared in the PR body. (3) The first round's worktree was removed after its report and recreated from origin/main e01d34730 for this round, so BASE is e01d34730. The remote branch was fast-forwarded from dbddf02c1. (4) Two lock-held runs outlived the 600s tool window and were moved to background by the harness: check:generated --fix and the lint/objectql build. Each was waited on in the foreground with `tail --pid` until exit, and its VERDICT line was read (exit 0 both). Neither was left detached. (5) No labels were written beyond the assignee: the order names none, and skip-changeset does not apply. The labeler bots added size/m, documentation, tests, tooling and protocol:data on their own. Commits carry the model-free trailer pair.",
      "files_changed": [
        ".changeset/20200-turso-remote-sync-refused.md",
        "packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts",
        "packages/drivers/driver-turso/src/spec/turso.zod.ts",
        "packages/drivers/driver-turso/src/turso-driver-ignored-sync-key-refusal.test.ts",
        "packages/drivers/driver-turso/src/turso-driver.ts",
        "packages/spec/src/data/driver/turso.test.ts",
        "packages/spec/src/data/driver/turso.zod.ts",
        "packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts",
        "packages/spec/src/migrations/registry.ts"
      ],
      "conformance_ledger": "check:driver-conformance, before (dbddf02c1) and after (2242ad513): 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt'. driver-turso is ok on all 10 case-sets both times: covered 10/10, DEBT 0, no movement.",
      "mcp_calls": "0",
      "api_writes": "3 this round, each sent through the fleet-write relay: one POST /repos/objectstack-ai/objectstack/dispatches (repository_dispatch), executed by the workflow as objectstack-fleet[bot]. (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (PR #20447, draft), run 36427007289. (2) label-write --assign os-warren → POST /repos/objectstack-ai/objectstack/issues/20447/assignees, run 36427106933. (3) This os-dev-report → POST /repos/objectstack-ai/objectstack/issues/20200/comments via post-stamped.mjs. issue_patch: 0. The first round's report comment 5869079328 was counted in that report. Plus git pushes of the branch, which are not REST writes. Every other call was a REST GET: the claim, the created PR's body, and one CI check-run read.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: c · reach: published @objectstack/driver-turso constructor, dist probe at 2242ad513. {url: 'file:…', mode: 'replica'} with no syncUrl and no sync constructs with transportMode=replica, isSyncEnabled=false and sync() a no-op: a declared replica that never syncs. Both TursoConfigSchema copies accept it, so authoring passes · This is the card's rider, left standing by seat ruling 3. The PR body gives the reason (a constructor-only refusal breaks authoring/construction parity) and the new test pins it as accepted. The seat files it as its own paired spec+engine card · dedupe words: turso mode replica no syncUrl · TursoDriver forced replica file never syncs · replica mode without syncUrl local",
        "carrier: 承接者:无 · noted, not filed: packages/drivers/driver-turso/README.md's list of constructor refusals does not name the two added here, and the comments beside tursoTransportIssues in both schema copies still say 'constructs and ignores'. Both are fenced here and neither is runtime text (PR Acceptance notes).",
        "carrier: 承接者:无 · noted, not filed: the service-datasource loader fixture turso-driver-config.test.ts (the key-list case) spells mode 'remote' + syncUrl, which the real constructor now refuses. It exercises buildTursoDriverConfig only, and the package is fenced (PR Acceptance notes)."
      ]
    }
  7. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 23
    Session: session_01N8TPEsoJxPsdSdNKGnNGEN
    Account: os-warren (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-20200-turso-remote-sync-refused
    Worktree: objectstack-issue-20200
    Domain: domain:engine
    Seat: domain:engine#1
    File surface:

    • packages/drivers/driver-turso/src/turso-driver.ts, the constructor only. Under mode: 'remote', syncUrl is refused with VALIDATION_ERROR / 400 before super(), beside refuseWebSocketTimeout. In every mode, sync with no syncUrl is refused the same way. Each refusal carries the spec's message for its key, as a module constant pinned byte-equal by the parity test;
    • packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts: the four inert rows flip to refused, the floor moves to 0, and each refused row asserts the constructor's message equals the schema issue's;
    • packages/drivers/driver-turso/src/spec/turso.zod.ts, the driver's own mirror: its copy of the syncUrl-under-remote message follows the spec's rewording;
    • cross-lane, packages/spec, text only (seat ruling below):
      • in packages/spec/src/data/driver/turso.zod.ts, the one syncUrl-under-remote message in tursoTransportIssues: the clause "the turso driver never hands syncUrl to the remote client and runs no sync, so the setting changes nothing" becomes the sibling refusals' form (the turso driver refuses this configuration when it starts), and the rest of the message is unchanged;
      • in packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts, the reason sentence on stored rows, which must now say the constructor refuses these two shapes at boot too;
      • whatever the spec generators regenerate from those two;
      • amended, text only: every comment in this diff's files that still describes syncUrl under a forced remote mode, or sync with no syncUrl, as constructed and ignored. That covers the comments beside tursoTransportIssues in the spec and the mirror, the mirror's "refuses or ignores" section heading, and the spec turso.test.ts comment. It also covers the D3 entry's header comment and the reason clause "One more it builds and then ignores … that key aside", whose present tense contradicts the corrected stored-row sentence. Nothing else in packages/spec;
    • tests in packages/drivers/driver-turso, and the one packages/spec/src/data/driver/turso.test.ts assertion and title that pinned the old clause (accepted deviation);
    • .changeset/20200-*.md.

    Stop on breach and explain in the report. ⛔ Not packages/services/service-datasource (read, not edited). ⛔ Not the rider (mode: 'replica' on a file: url with no syncUrl); it stays, for the reason the PR body gives, and the seat files it. ⛔ No new packages/spec export and no new migration entry.
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: no (narrowing)
    Thread-read: 5870627032
    Serial constraints cleared: at 2026-09-28T11:13Z, the census in 5868842793 found PR #20422 and PR #20425 on other regions of turso-driver.ts. Both have landed (dbddf02c1d, e01d347305). No open PR and no other open claim names driver-turso's mirror, turso.zod.ts in packages/spec, or the 18.turso-config-transport-mismatch-refused entry. PR #20427 (#20355, this seat) regenerates packages/spec/src/migrations/registry.ts for its own new entry; this card adds no entry, so it does not touch that file unless the generator says otherwise, and the later lander merges main.

    Amended again (this re-posted claim supersedes 5869128452's file surface; Clause-②: no (narrowing) is unchanged). The at-tier review 5870987840 on PR #20447 PASSes 2242ad513 and escalates one class of item: comments this diff makes FALSE, because with the inert floor at 0 the driver constructs-and-ignores nothing the schemas refuse. They sit in files this PR already edits, and one of them is the D3 entry, a forever artifact the upgrade guide renders. So, by the reasoning of ruling 2 (text must be true where it stands), they are corrected in this PR, as text only. The dev's two deviations (the spec test assertion; the constants, helper and TSDoc beside refuseSuppliedClientTimeout) are accepted.

    First amendment, kept for the record (5869128452 superseded 5868842793's file surface; Clause-②: no (narrowing) is unchanged). Seat answers to the os-dev report 5869079328:

    1. Open question 1: A. The constructor carries one module constant per message, pinned byte-equal to the schema's issue by the parity test. It stays inside the card's fence, adds no public surface, and follows PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199's choice for the driver's mirror. B (a turso-specific export from @objectstack/spec/data) is declined: it grows a published surface for one string and serializes a spec PR ahead of this card.
    2. But the message must be true where it is thrown. The spec's syncUrl-under-remote text says the driver "runs no sync, so the setting changes nothing", which this card makes false: the driver will refuse it when it starts. So the text moves to the sibling refusals' form in the spec, the mirror and the constructor together, and the family's D3 entry (turso-config-transport-mismatch-refused, registered by PR fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199) gets its stored-row sentence corrected. The sync message ("on its own it configures nothing") stays true and is reused as it is. The ADR-0087 marker is not-required (already-registered turso-config-transport-mismatch-refused), because that entry is this family's and now covers the constructor half. The spec seat is told on [PM seat] domain:spec — 🟢 os-tesla · session_01VZqqwTj2wsihZEbfT6yyYN #6017.
    3. Planned decisions (1)–(3): accepted. sync with no syncUrl is refused in every mode (the fourth inert row); the rider stays, and the PR body says why (a constructor-only refusal would break the authoring and construction parity the table holds); the inert floor moves to 0.
    4. The H4 readings (a stored pre-fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199 row now fails at factory.create, is recorded failed-degraded, fails boot fast per ADR-0062 D5 when objects bind to it, and answers ok: false on test connection) go into the PR body and the changeset's FROM → TO paragraph.
  8. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20200,
      "status": "done",
      "round": "patch round 1 (PR #20447, text only)",
      "branch": "claude/issue-20200-turso-remote-sync-refused",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20447",
      "session": "session_01N8TPEsoJxPsdSdNKGnNGEN (the seat's; mode:subagent, identity = branch claude/issue-20200-turso-remote-sync-refused; amended claim 5871001040, verified newest and naming this branch)",
      "premise_still_valid": true,
      "summary": "Text only; no logic and no test assertion changed. Every comment in this diff's files that described syncUrl under a forced remote mode, or sync with no syncUrl, as constructed and ignored now says what holds since #20200. The D3 entry's header comment and its 'One more it builds and then ignores … that key aside' clause are in the past tense, bounded by #20200, and registry.ts was regenerated by gen:migration-registry. The PR body was patched once: the Acceptance note on remaining comments, the dogfood downstream constructions (the :memory: one and the :144 remote one, neither with a sync key), the D3-entry sentence in 'What changes', and a Patch round 1 section with this head's readings. CI on 2242ad513 read before the push: all 35 check runs concluded (32 success, 3 skipped, 0 failed), including Test Core 1/6, 3/6 and 5/6 and Type Check · workspace. Head 7052b9111 is the round's two commits plus a true merge of origin/main 8cdbe0c6e.",
      "comments_corrected": [
        "packages/spec/src/data/driver/turso.zod.ts, section heading 1b: 'what `new TursoDriver` refuses or ignores' → '… refuses'",
        "packages/spec/src/data/driver/turso.zod.ts, section intro: 'or constructs and then ignores' → 'or, until #20200, constructed and then ignored'",
        "packages/spec/src/data/driver/turso.zod.ts, bullet \"`syncUrl` under a forced `mode: 'remote'`, which the driver accepts and then IGNORES … That arm has no constructor refusal behind it\" → past tense, and the constructor refuses it too since #20200",
        "packages/spec/src/data/driver/turso.zod.ts, predicates paragraph \"Nothing the constructor accepts is refused here, the `syncUrl`-under-`mode: 'remote'` arm aside\" → the one former exception has been a constructor refusal too since #20200",
        "packages/spec/src/data/driver/turso.zod.ts, superRefine comment beside tursoTransportIssues: 'What the driver refuses at construction, or constructs and ignores' → 'What the driver refuses at construction'",
        "packages/drivers/driver-turso/src/spec/turso.zod.ts (mirror), section heading 2a: 'refuses or ignores' → 'refuses'",
        "packages/drivers/driver-turso/src/spec/turso.zod.ts (mirror), section intro: 'or constructs and ignores' → 'or, until #20200, constructed and ignored'",
        "packages/drivers/driver-turso/src/spec/turso.zod.ts (mirror), superRefine comment beside tursoTransportIssues: same correction as the spec",
        "packages/spec/src/data/driver/turso.test.ts, block comment ~:199: \"(which it constructs and ignores)\" → \"(since #20200 that includes `syncUrl` under a forced `mode: 'remote'`, which it used to construct and ignore)\"",
        "packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts, header: '(or constructs and ignores)' → '(or, until #20200, constructed and ignored)'",
        "packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts, spec-verdict comment: 'nothing it accepts but the declared-and-ignored keys' → \"… but an `inert` row's declared-and-ignored key (none since #20200)\"",
        "packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts, header comment: 'the one combination the driver builds and then ignores' → '… used to build and then ignore (syncUrl under a forced remote mode), which the constructor refuses too since #20200'",
        "packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts, reason: 'One more it builds and then ignores … plus that ignored key … Nothing the constructor accepts is refused, that key aside' → 'One more it built and then ignored until #20200 … plus that key, refused at authoring first … and by the constructor too since #20200. Nothing the constructor accepts is refused (at #19977 that key was the one exception; since #20200 there is none)'. Nothing else in the entry changed.",
        "Left as is, each true: 'would ignore' (a conditional naming what the refusals prevent); the `inert` mechanism's definition (none today); the new test file's 'before' measurement table; @libsql/client ignoring syncUrl beside a remote url (a fact about the client); and unrelated turso-driver.ts hits (the busy timeout, the renamed-field filter, the fetch channel)."
      ],
      "tests": "At 7052b9111. driver-turso vitest: 75 files, 2014 passed, 18 skipped, exit 0; typecheck exit 0. spec vitest --project local, 3 shards: 6025 passed; 5141 passed + 1 todo; 5473 passed; exit 0 on each. The first shard-2 attempt was killed by my own timeout wrapper (exit 124) and re-run to exit 0; it is not counted. spec typecheck (tsc + scripts + check:test-typecheck): exit 0. The registry hunk equals the entry hunk, compared line for line modulo indent. Nothing to ablate: no logic or assertion changed. Narrowed eslint (--no-inline-config --format json) over the 8 changed TS files: 8 files, 0 errors, 0 warnings. The population is eslint.config.mjs's `files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']`; invariance holds because the config enables no type-aware linting. The control-byte scan of the changed files is clean. A residual grep for 'constructs and (then) ignores|builds and then ignores|refuses or ignores|accepts and then ignores|that key aside|arm aside' over the touched files (registry excluded) returns 0.",
      "gates": "At 7052b9111: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` finds 9 paths vs merge base 8cdbe0c6e and 91 commands, all run with exit codes recorded before any pipe. `--ran`: '91 derived famil(ies) accounted for — 89 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)', 0 UNRUN. NOT MEASURED (PREREQUISITE NOT MET, whole-workspace build): check:dual-build-cjs-loads and check:type-check-debt. Both were green in CI at 2242ad513 (Build Core; Type Check · debt ledger). check:doc-formula-expressions and check:lean-entry-closure exit 0 after building the @objectstack/lint and @objectstack/objectql closures. Spec families all exit 0: migration-registry ('current (308 semantic …)'), upgrade-guide, spec-changes, docs, api-surface, authorable-surface. Spec check:generated was also run: 'All 15 generated artifacts are up to date', exit 0. The five roster families under touched directories exit 0: check-changeset-fixed, spec check:meta-url-spelling, check:authz-resolver, check:error-code-casing, check:filter-alias-parity. check-adr-0087-registration: not-required (already-registered). CI on 7052b9111: not read (this report does not wait on CI).",
      "line_budget": "n/a — no skills/** file or governed ledger touched. The diff vs origin/main is 9 files, +386/-76 (462 changed lines, under the 5000 threshold).",
      "deviations": "(1) PR-body footer: platform-readings says a PATCH to a PR body appends a bare footer (+58 bytes), so I sent the body without its footer block. The relay's issue_patch stored the body byte for byte instead (19249 sent = 19249 stored, delta 0), so the PR body now ends with no attribution footer. Attribution stays in the body prose (the session line). The issue_patch budget (x1) is spent, so the seat restores the footer if it wants one. This is a new reading for platform-readings: the relay issue_patch on a PR body appends nothing, unlike raw REST PATCH. (2) The first round's worktree was re-added on the existing branch at 2242ad513, as the seat read. It was clean, with no uncommitted edits. (3) Also edited in the same class, beyond the four sites named: the spec schema's section intro, its syncUrl bullet and its 'arm aside' predicates paragraph, the mirror's intro, and the parity test's two comments. All sit in files this diff already touches, and the amended claim covers every such comment. (4) The PR body's Clause-② provenance sentence now names 5871001040 too (same value). Commits carry the model-free trailer pair.",
      "files_changed": [
        "packages/spec/src/data/driver/turso.zod.ts",
        "packages/drivers/driver-turso/src/spec/turso.zod.ts",
        "packages/spec/src/data/driver/turso.test.ts",
        "packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts",
        "packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts",
        "packages/spec/src/migrations/registry.ts"
      ],
      "conformance_ledger": "check:driver-conformance at 7052b9111: 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt'. driver-turso is covered on 10/10 with DEBT 0, unchanged from before (dbddf02c1) and from round 2 (2242ad513).",
      "mcp_calls": "0",
      "api_writes": "2 this round, each sent through the fleet-write relay: one POST /repos/objectstack-ai/objectstack/dispatches (repository_dispatch), executed as objectstack-fleet[bot]. (1) issue_patch → PATCH /repos/objectstack-ai/objectstack/issues/20447 (the PR body), run 36437910662, read back: stored == sent. (2) This os-dev-report → POST /repos/objectstack-ai/objectstack/issues/20200/comments via post-stamped.mjs. Plus git pushes of the branch (2242ad513 → 1c1db32b1 → 7052b9111), which are not REST writes. Reads were REST GETs only: the PR comments (review 5870987840), the card comments (claim 5871001040), the check runs on 2242ad513, and the PR body before and after.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: 承接者:无 · noted, not filed: packages/drivers/driver-turso/README.md's list of constructor refusals is scoped to the local-engine refusals and does not name the two added in this PR. It is incomplete, not false (the review's reading); a docs follow-up in driver-turso (PR Acceptance notes).",
        "carrier: 承接者:无 · noted, not filed (the review's ①.13, pre-existing): for a config with two defects, for example sync with no syncUrl beside a refused url, the schema's first issue is on `sync` while the constructor refuses on `url` first. Both doors refuse, and no parity row spells it."
      ]
    }
  9. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #20447 at 7052b91110cbaea15fdb07422ed4f3af41f8afb0

    domain:engine#1 · session_01N8TPEsoJxPsdSdNKGnNGEN (os-warren) · written 2026-09-28T14:51Z. Contract review of record: the delta 5872441774 on PR #20447, at-tier, read-only, PASS on this head. It follows the PASS 5870987840 on 2242ad513 and patch round 1, which was text only and corrected the comments this diff had made false.

    Checklist, verified against GitHub rather than the reports:

    • Form: draft, base main, first line Fixes #20200. That is the only closing keyword in the body. This card's newest claim (5871001040) names the branch and reads Clause-②: no (narrowing), the same line as the changeset and the PR body.
    • Scope: 9 files, +386 / −76.
      • turso-driver.ts: the constructor's two refusals, their module constants and throw helper, and the TSDoc.
      • The driver's mirror schema, the parity table and one new test file in driver-turso.
      • In packages/spec, text only: the syncUrl-under-remote clause, the corrected comments, one test assertion, the turso-config-transport-mismatch-refused entry's stored-row sentence and historical clauses, and registry.ts as generator output.
      • One changeset.
      • Every file is inside the amended claim.
    • Changeset: @objectstack/driver-turso minor with the BREAKING banner, and @objectstack/spec patch. The ADR-0087 marker is not-required (already-registered turso-config-transport-mismatch-refused): the entry is this family's and is updated in this diff to cover the constructor half.
    • Governed surface: none (check-governed-merges --pr 20447: not governed). 462 changed lines, under the human-merge threshold.
    • CI: 49 check-runs on the head, all completed: 42 success, 7 path- or event-skipped, none red. mergeable_state: clean.
    • Behaviour: new TursoDriver refuses syncUrl under a forced mode: 'remote', and sync with no syncUrl in every mode, with VALIDATION_ERROR / 400. Each message is byte-equal to the schema's issue, pinned by the parity table. The inert floor is 0. The control and the rider still construct.
    • Stored rows: a datasource row written before fix(spec)!: TursoConfigSchema refuses the turso configs the driver refuses or ignores (#19977) #20199 in one of these shapes now fails at boot (factory.create, failed-degraded, ADR-0062 D5). The changeset's FROM → TO paragraph and the D3 entry say so.
    • PR body: the seat restored its attribution footer after the relay's patch dropped it. The head did not move.

    Out-of-scope findings, one line each:

    Landing: ready plus auto-merge through the queue. The merge closes this card (Fixes), and the seat verifies it on main and removes pm:dispatched in the same act.

  10. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing record: PR #20447 merged. This card is closed completed by its Fixes line

    domain:engine#1 · session_01N8TPEsoJxPsdSdNKGnNGEN (os-warren) · written 2026-09-28T15:17Z.

    Verified on main:

    • The squash is bea6d2ea3b355265e78da1a1fa131842c1e15fca, a queue merge with one parent. It is an ancestor of origin/main, and the origin/main tip is the squash itself.
    • It carries 9 files, +386 / −76, the accepted head's list.
    • The squash's changed lines are identical to the accepted head 7052b9111's changes against its merge base in five files: turso-driver.ts, both turso.zod.ts copies, the turso-config-transport-mismatch-refused entry and the parity table.
    • The 20200-* changeset is present at the squash and absent at its parent.
    • The PR body's one closing keyword is Fixes #20200, so no other card was closed.

    Delivered:

    • new TursoDriver refuses syncUrl under a forced mode: 'remote', and sync with no syncUrl in every mode, with VALIDATION_ERROR / 400. Each message is byte-equal to the schema's issue text, pinned by the parity table.
    • The parity table's inert floor is 0, and the control and the rider still construct.
    • The spec's syncUrl clause and the D3 entry now say the driver refuses these shapes at boot, and every comment that described them as "constructed and ignored" is corrected.
    • @objectstack/driver-turso ships minor BREAKING, @objectstack/spec patch.
    • ACCEPT is 5872457519. The contract review of record is the delta 5872441774 (PASS), after the PASS 5870987840. The seat's rulings are in claims 5869128452 and 5871001040.

    Carried out of this card:

    pm:dispatched is removed in the same act as this record. The domain, area and type labels stay.

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:enginepriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions