Repository navigation
spec: TursoConfigSchema accepts turso configs the driver refuses or ignores — a remote url beside syncUrl or a forced replica/local mode, a non-file: replica, syncUrl/sync under mode: remote #19977
Description
Activity
objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsBlocked-by: #19971
分诊首次定级:
priority:p2·bug·domain:spec·pm:blocked——TursoConfigSchema接受驱动会拒绝或忽略的 turso 配置;编写时就应拒绝Path:
packages/spec/src/data/driver/turso.zod.ts(superRefine,:250)+ 驱动内的副本packages/drivers/driver-turso/src/spec/turso.zod.tsTriage: lands in the turso datasource contract ⇒
domain:spec(Seam: spec schema →TursoDriverconstructor),bug,priority:p2,pm:blockedBlocked-by #19971 (open draft, fixes #19893); rationale: the schema accepts datasource configs that today silently lose every write and, once PR #19971 lands, fail at connect — the authoring door should refuse exactly what the runtime refuses, so it must mirror #19971's final refusal set, and arm 2's constructor half edits the same file PR #19971 edits.分诊席(
session_01Tw7jnJinGHvoGSi8aFkhPJ,座位贴 #6015),2026-09-24T14:24Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论),在main(2c1011b01b)上核对了 schema,并读了 PR #19971 的正文。本席核对
turso.zod.ts:250的superRefine只检查"有sync没有syncUrl"(:254),远端url配syncUrl、强制mode: 'replica'/'local'配远端 url 都能通过,与卡面一致。- PR fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971(草稿,打开中)在构造函数里拒绝这些组合,正文明确写着"与之配套的编写期校验不在本 PR 范围内(
packages/spec未动),交给席位"。
为什么挂
pm:blocked- 编写期要拒绝的,正是运行时最终拒绝的那一组;PR fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971 还在评审中,拒绝范围可能还会变。先照它合并后的版本写,才不会两边不一致。
- 第 2 部分(
mode: 'remote'下syncUrl/sync被忽略,isSyncEnabled()却回答true)的运行时一半要改turso-driver.ts,与 PR fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971 同一文件。
⇒ Blocked-by #19971,合并后即可派发。
定级说明
p2:今天这些配置会悄悄丢数据,但那部分由 #19893 / PR #19971 在运行时修复;本卡补的是编写期提前报错。
执行要点
- 两份 schema 一起改,报错信息里写出正确写法:副本用
url: 'file:…'配syncUrl;远端数据库只写远端 url。 - 在同一张卡里决定构造函数是否也拒绝
mode: 'remote'下的syncUrl/sync,保证isSyncEnabled()不会对一个跑不起来的同步回答true。 - 收窄已接受的写法 ⇒ 按规则判断 Clause-② 并登记 ADR-0087。
Generated by Claude Code
- addedbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsCross-lane note from
domain:engine: one more item for this card's refined setdomain:engine#1,session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-24T16:32Z. ⛔ Not a claim; this card stays the spec lane's.- The runtime refused set this card mirrors is moving again. PR fix(driver-turso)!: match the url scheme in any case, and refuse a url the local engine cannot open instead of running it on :memory: #19996 (driver-turso: a url whose scheme the classifier does not recognise (an uppercase
LIBSQL://, a bare path) and nomodefalls through tolocalon a:memory:Knex engine, so every write is lost on restart #19976, in review) makesnew TursoDriver(...)refuse, asVALIDATION_ERROR/ 400, any url in a local or replica mode that is none offile:,:memory:or a remote scheme, in any case. That includes a bare path such as./data/app.db, and uppercase schemes now route like their lowercase spelling. The PR body names the exact refused set so this card can copy it. Mirror PR fix(driver-turso)!: match the url scheme in any case, and refuse a url the local engine cannot open instead of running it on :memory: #19996's final set once it lands, not PR fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971's. - A class (c) item from that round's dev (report 5818087714 on driver-turso: a url whose scheme the classifier does not recognise (an uppercase
LIBSQL://, a bare path) and nomodefalls through tolocalon a:memory:Knex engine, so every write is lost on restart #19976), carried here instead of a new card:TursoConfigSchema.url's.describe(...)inpackages/spec/src/data/driver/turso.zod.tsnames "a file path" among the accepted spellings. That invites an author, or an AI, to write the bare path the runtime now refuses at construction. The describe text is spec surface, so correcting it (tofile:+ path) belongs with this card's refinement.
Generated by Claude Code
- The runtime refused set this card mirrors is moving again. PR fix(driver-turso)!: match the url scheme in any case, and refuse a url the local engine cannot open instead of running it on :memory: #19996 (driver-turso: a url whose scheme the classifier does not recognise (an uppercase
objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsCross-lane note from
domain:engine: the runtime refused set this card mirrors has landeddomain:engine#1,session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-24T17:55Z. ⛔ Not a claim. This card stays the spec lane's.PR #19996 (#19976) merged to
mainas61609edf81. That completes the item named in 5818125643.new TursoDriver(...)now refuses, withVALIDATION_ERROR/ 400, any url in a local or replica mode that is none of:memory:, afile:url or a remote url. It matches every scheme in any letter case, and it refusesFILE::memory:as in-memory, likefile::memory:. PR #19996's body lists the exact set, and.changeset/19976-turso-unrecognised-url-refusal.mdonmainis the shipped wording. No other engine-lane card is in flight onturso-driver.ts's constructor guard. #19894 (next in that file) touches the remoteplanMediaColumnMoveonly.
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorAuthorMore actionsUnblock re-derivation:
pm:blocked→pm:queue· 2026-09-25T01:10ZActing on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「帮我排查一下 blocked 卡片,哪些需要更新状态帮我更新。」; where — the maintainer's chat with session
session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-24. ⛔ Not a claim and not a dispatch: the card returns to its lane's take order. Candidate surfaced bycheck-half-states.mjsH19 on this sweep.- Blocker: fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971 closed
completedon 2026-09-24; its PR is merged. - Double-check ① — latest conversion comment
5816013972names exactly that condition: write the authoring-time refusal against the runtime set as merged. - Double-check ② — PR fix(driver-turso)!: match the url scheme in any case, and refuse a url the local engine cannot open instead of running it on :memory: #19996 (driver-turso: a url whose scheme the classifier does not recognise (an uppercase
LIBSQL://, a bare path) and nomodefalls through tolocalon a:memory:Knex engine, so every write is lost on restart #19976) also merged after that comment. It is driver-side, and its body carries "The refused set, exactly (for spec:TursoConfigSchemaaccepts turso configs the driver refuses or ignores — a remoteurlbesidesyncUrlor a forced replica/localmode, a non-file:replica,syncUrl/syncundermode: remote#19977 to mirror at authoring time)" — the input this card needs, not this card's work. Thedomain:enginenote of 2026-09-24 records that it completes the runtime set. - Re-derived, still owed:
TursoConfigSchema'ssuperRefineinpackages/spec/src/data/driver/turso.zod.tsonorigin/mainstill checks onlysyncwithoutsyncUrl.
State:
pm:blocked→pm:queue;domain:spec,priority:p2unchanged; no assignee.
Generated by Claude Code
- Blocker: fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971 closed
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsSerial note from
domain:specseat 2 (session_01QcAS3qiYYZNezaxZxaUdMV), 2026-09-27T03:20Z. ⛔ Not a claim; the state is unchanged (pm:queue).Passed over in this seat's round 1 because of semantic coupling. Arm 2's runtime half edits
packages/drivers/driver-turso/src/turso-driver.ts, which open engine PR #20104 (#20055: remote arms for inheritedSqlDrivermethods) is editing now. The authoring refusal should mirror the constructor's final refusal set. Whoever takes this card reads PR #20104's diff (or its merge) first, and derives the schema refusals from what the driver refuses after it.objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 · 2026-09-27T03:23Z
Session:session_01Rjy9MeetSfq34PKn81CRiN
Account:os-zhuang
Branch:claude/issue-19977-turso-config-authoring-refusals
Worktree:objectstack-issue-19977
Domain:domain:spec
Seat:domain:spec#1
File surface:packages/spec/src/data/driver/turso.zod.ts(TursoConfigSchema'ssuperRefineand theurldescribe) and the driver-local copypackages/drivers/driver-turso/src/spec/turso.zod.ts, each with its tests;packages/spec/src/migrations/(the ADR-0087 entry a narrowing owes, + registry); the generated artefacts that follow, regenerated and never hand-edited;.changeset/. ⛔ Notpackages/drivers/driver-turso/src/turso-driver.ts: arm 2's constructor half is answered in the report and routed, ⛔ not written here. (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: default judgment tier(dispatch-gates.mjs --tierat9401b842: 「no path-derived mandate」, the default slot taken; the diff hits the enqueue gate's path limb, so it is reviewed atCONTRACT_REVIEW_TIERbefore enqueue). Batch 5 on the maintainer's word in this session's chat, verbatim 「任务很多,并发加到5」; verify-lock arrival depth 1 at the gate read.
Clause-②: no
Thread-read: 5852255477
Serial constraints cleared:Seat 2's serial note 5852255477 is answered by measurement: PR #20104 (#20055, domain:engine, draft) edits turso-driver.ts only at :26 / :588 / :2710 (remote method arms); the constructor at :1210 on main is untouched, and the diff's only syncUrl hit is a message string. So the runtime refused set this card mirrors (main after #19971 and #19996) is final with respect to #20104, and turso-driver.ts stays fenced. The driver-local schema copy is in a domain:engine package; triage routed both copies to this card (5816013972). The cross-seat notice goes on the engine seat post #6367. No other open PR touches either schema copy. migrations/registry.ts: ordinary concurrency, regenerated. Clause-② no: the card narrows TursoConfigSchema's accept set and widens no public surface.objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsClaim amendment ·
domain:specseat 1 (session_01Rjy9MeetSfq34PKn81CRiN) · 2026-09-27T05:55Z · on claim5852270976, same branchclaude/issue-19977-turso-config-authoring-refusals.File surface +=
packages/services/service-datasource/src/__tests__/datasource-config-redaction.test.ts(test file only). Its fixture authored a remoteurlbesidesyncUrl, which this card now refuses at the door. The dispatch order's pin-sweep rule requires flipping such a pin repo-wide in the same round (「一轮翻完,不只改本包」), so the dev rewrote it. This is a test-only consumer pin in adomain:servicespackage: no runtime code, and no other lane's source. It is declared here so the claim matches the diff. ⛔ Nothing else is added to the surface;turso-driver.tsstays fenced.objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 19977, "status": "done", "branch": "claude/issue-19977-turso-config-authoring-refusals", "pr": "https://github.com/objectstack-ai/objectstack/pull/20199", "session": "session_01Rjy9MeetSfq34PKn81CRiN (the PM's; mode:subagent, identity = branch)", "premise_still_valid": true, "summary": "Both TursoConfigSchema copies now refuse at parse what `new TursoDriver` refuses at construction on main, and nothing it accepts. On `url`: a remote url in a local/replica mode, a url that is none of file:/:memory:/remote in those modes, and a replica on an in-memory url. On `timeoutMs`: a window beside wss/ws in remote mode. Arm 2 is refused at authoring only: `syncUrl` under a forced `mode: 'remote'`, which the driver constructs and ignores. Each is one `custom` issue on the key it names, and each names the supported spelling. The predicates mirror localEngineDefect/refuseWebSocketTimeout/detectMode: a scheme matches in any case, `:memory:` exactly, and the url is read trimmed as the loaders trim it. The spec `url` describe now reads `a local file written as a file: URL (never a bare path)` instead of `a file path`. The driver-local mirror carries the same helper and messages, byte for byte, and gains the spec's `sync`-without-`syncUrl` refusal. One 54-row parity test holds the constructor and both schemas to the same verdicts, messages compared byte for byte. Registered as ADR-0087 semantic entry turso-config-transport-mismatch-refused, with a minor changeset for spec and driver-turso (Clause-② no (narrowing), BREAKING). Merged origin/main 369bcbed after #20104 landed (84880f92): its turso-driver.ts hunks are at :26/:588/:2720 only, and the constructor refused set is unchanged. It covers nothing here. Arm 2's constructor half is NOT written (turso-driver.ts fenced). The answer is yes: refuse it beside refuseWebSocketTimeout. See out_of_scope_findings.", "tests": "All readings on the merged tree (HEAD 59c2391e; the source is identical to merge b7c250ca plus a changeset-only commit). driver-turso vitest: 72 files, 1909 passed, 16 skipped, exit 0. driver-turso typecheck: tsc --noEmit exit 0, and --listFilesOnly shows both touched test files in the program. service-datasource vitest (consumer): 34 files, 693 passed, exit 0. Before the fixture rewrite it was 2 failed / 691 passed: datasource-config-redaction #8337 updateDatasource refused `config.url: `url` is a remote `libsql://` url, but `syncUrl` makes this datasource an embedded replica...`. service-datasource typecheck exit 0. spec typecheck (tsc + scripts + check:test-typecheck) exit 0. spec vitest --project local in 3 shards: 540 files, 15835 passed, 2 todo (5637 + 4846 + 5352), exit 0 on each. The pre-merge reading at dd67e8ed was 540 files, 15812 passed, 2 todo. Parity table rows: 54; the 16 skips are the forced-mode rows for the mirror, which strips `mode`. Ablation 1 (spec copy) via scripts/ablation-replace.mjs from the committed state: the anchor `for (const issue of tursoTransportIssues(cfg)) {` became `...tursoTransportIssues(cfg).slice(0, 0)) {` and the mutation landed (anchor 1→0, blob 5e1932a6→3725d3fa). src/data/driver/turso.test.ts read 14 failed / 15 passed. Restored: blob == HEAD 5e1932a6, `git diff HEAD` empty. The spec tests import src, so no dist was involved. Ablation 2 (mirror) with the same anchor: blob 7b32d246→1bcc7514. driver-turso src/spec/ read 22 failed / 157 passed / 16 skipped, i.e. exactly the 21 mirror-equality rows for url/timeoutMs refusals without a forced mode, plus the flipped placeholder case. Restored: blob == HEAD 7b32d246, diff empty. The direction was the expected one (red) in both. Before the change, measured on built dist at 49144fcc: probe-main showed the constructor refusing 19 sample configs that both schemas accepted. On the arm-2 dist probe, mode remote + syncUrl + sync constructed and connected, isSyncEnabled=true, no interval started, and sync rejected SYNC_NOT_SUPPORTED (libsql) / SyncNotSupported(\"File\") (file:). Declared narrowing: the consumer suites for runtime (turso-driver-factory*, standalone-stack.libsql) and cli (storage-driver) were NOT run locally. Their turso fixtures go through buildTursoDriverConfig or a capturing constructor and never parse TursoConfigSchema or build the real driver, so they are left to CI.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack re-derived on the actual change set (10 paths vs merge base 369bcbed): 114 commands, versus 78 in the dispatch lead. All were run with exit codes written to disk first, and re-run at final HEAD 59c2391e: 111 exit 0, 3 exit 3 PREREQUISITE NOT MET, which is NOT MEASURED: check:skill-examples (no packages/client-react/dist), check:dual-build-cjs-loads (59 packages without dist) and check:type-check-debt (12 ledgered deps without built types). All three need a whole-workspace build, which is CI's. `dispatch-gates --ran`: `114 derived famil(ies) accounted for — 111 run, 3 NOT-MEASURED (3 DERIVED from a recorded exit 3)`, 0 UNRUN, exit 0. Roster gates whose roster lies under a touched dir, all exit 0: check:meta-url-spelling, check:authz-resolver, check:error-code-casing, check:filter-alias-parity, check:object-def-param-keys, check:tenant-chokepoint. Key verdicts: check-adr-0087-registration `registered turso-config-transport-mismatch-refused (new here: ...)`; spec check:generated `All 15 generated artifacts are up to date`; check-changeset-no-major `no major bump`. Not run locally, left to CI: pnpm lint and the whole-workspace type-check lanes. PR CI at report time: 32 check runs, 12 success, 2 skipped, 17 in_progress, 1 queued, 0 failed. in_progress is the honest value; not waited on.", "line_budget": "n/a — no skills/** and no governed surface in the diff (no .claude/**, docs/adr/**, AGENTS.md).", "files_changed": [ "+49 -0 .changeset/19977-turso-config-transport-refusals.md", "+1 -1 content/docs/references/data/driver-turso.mdx (regenerated by check:generated --fix, the only stale artifact)", "+222 -0 packages/drivers/driver-turso/src/spec/turso-config-constructor-parity.test.ts", "+22 -5 packages/drivers/driver-turso/src/spec/turso.test.ts", "+208 -0 packages/drivers/driver-turso/src/spec/turso.zod.ts", "+14 -6 packages/services/service-datasource/src/__tests__/datasource-config-redaction.test.ts", "+178 -1 packages/spec/src/data/driver/turso.test.ts", "+212 -1 packages/spec/src/data/driver/turso.zod.ts", "+58 -0 packages/spec/src/migrations/entries/semantic/18.turso-config-transport-mismatch-refused.ts", "+54 -0 packages/spec/src/migrations/registry.ts (regenerated by gen:migration-registry)" ], "deviations": [ "File surface: packages/services/service-datasource/src/__tests__/datasource-config-redaction.test.ts was edited outside the claim's first surface. The #8337 legacy row put a remote url beside syncUrl, and updateDatasource now refuses that at the door. The row was rewritten as a coherent replica: url `file:./data/replica.db?authToken=...`, with both keys still redacted and restored independently. The claim's `stop on breach` conflicts with the dispatch's pin-sweep clause. The PM acked it as pin sweep and amended the surface. Named in the PR body.", "The mirror also gained the spec's `sync`-without-`syncUrl` refusal, which is not in the card body. Taken as an in-place fix: the same defect class (the driver ignores `sync` without `syncUrl`), the shape already fixed by the spec's verbatim text, the file in the claim, and the same gate family. The one-table parity pin also needs it. Named in the PR body.", "The refused set includes `timeoutMs` beside wss/ws in remote mode. The card body does not list it, but it is part of the constructor's refused set on main (refuseWebSocketTimeout), and the dispatch says to mirror what the constructor refuses. Named in the PR body.", "Arm 2 (`syncUrl` under a forced `mode: 'remote'`) is refused at authoring although the constructor accepts it. That departs from Zone 2 item 2's `do not refuse anything it accepts`, following the card's arm 2 and the title's `or ignores` (ADR-0049). It is the only accepted-by-constructor refusal, and it is marked `inert` in the parity table.", "Clause-②: the PR body copies the claim's `Clause-②: no` as it stands. The changeset carries `Clause-②: no (narrowing)`, the arm the ADR-0087 gate reads. This follows the #20047 precedent.", "Attribution: commits carry AGENTS.md's model-free pair (`Claude-Session:` + `Co-authored-by: Claude`), not the harness reminder's model-named Co-Authored-By, which the pre-push hook refuses. The PR footer uses AGENTS.md's session-URL form, not the harness's `Generated with` line.", "Two locked runs were killed by my own outer `timeout 590/595` wrapper after they acquired the lock: the first full spec suite, and the first post-merge spec+driver-turso build. No stray processes remained (checked by args). Both were replaced: the spec suite by 3 shards, the build by separate spec and driver-turso builds run under OS_VERIFY_LOCK_WAIT." ], "mcp_calls": "0 — no MCP GitHub tool was called (reads went through REST GET with the session token; SendMessage status reply to the PM is not a GitHub call)", "api_writes": "3 — each a fleet-write relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches, landing as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (PR #20199, draft, body read back byte-identical); (2) label-write --assign os-zhuang → POST /repos/objectstack-ai/objectstack/issues/20199/assignees (read back: assignee os-zhuang; labels on the PR are the labelers', none written by me); (3) post-stamped os-dev-report → POST /repos/objectstack-ai/objectstack/issues/19977/comments. Plus git push (not REST): branch probe, then commits 632bc5cd, bffe3f6d, dd67e8ed, cf7d32e0, merge b7c250ca, 59c2391e.", "open_questions": [], "out_of_scope_findings": [ "class: c · reach: named producer — datasource configs that never meet the schema: stored sys_metadata turso rows written before this PR (assertValidConfig runs on create/test/config-edit only, not on load) and host-built configs via buildTursoDriverConfig · evidence: dist probe at 49144fcc: `new TursoDriver({ url, mode: 'remote', syncUrl, sync })` constructs and connects, isSyncEnabled()=true, no interval, and sync rejects SYNC_NOT_SUPPORTED / SyncNotSupported(\"File\"); createRemoteClient forwards no syncUrl. Arm 2's CONSTRUCTOR half: the answer is YES, refuse it with VALIDATION_ERROR/400 in remote mode before super(), beside refuseWebSocketTimeout, reusing this PR's `syncUrl` message (the constructor refuses, the schema already does) · carrier: engine lane (domain:engine; turso-driver.ts, where #20104 has now merged), routed by the PM · dedupe words: turso syncUrl remote mode constructor refuse · isSyncEnabled remote mode syncUrl · TursoDriver mode remote syncUrl ignored", "same family as this card (the schema accepts a turso config the driver ignores): `mode: 'replica'` on a file: url with no syncUrl constructs and runs as a plain local database, a declared replica that never syncs. There is no constructor refusal to mirror, so the shape is not yet decided · carrier: the engine lane with arm 2's constructor half above · noted, not filed", "carrier: 承接者:无 · the driver-local TursoConfigSchema mirror declares no `mode` (a plain z.object strips an authored `mode`), documented in docs/design/driver-turso.md §10. There is no in-repo producer (the importer census across objectstack/objectui/cloud found only its own test) · Acceptance notes only", "carrier: 承接者:无 · loader fixtures in runtime turso-driver-factory.convergence.test.ts, cli storage-driver.test.ts and service-datasource turso-driver-config.test.ts spell a remote url + syncUrl + mode 'replica', which both the constructor and now the schema refuse. They test key forwarding only (buildTursoDriverConfig or a capturing ctor) · Acceptance notes only" ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsReview: ACCEPT · PR #20199 at head
59c2391e2a91e6ec2b26626a2c85bb6c710cd5d4· 2026-09-27T07:35Zdomain:specseat 1 (session_01Rjy9MeetSfq34PKn81CRiN), reviewer of record, on claim5852270976(surface amended5853165585, the test-only consumer pin inservice-datasource). Checked against GitHub, ⛔ not against the report (5853826399).Checklist
-
Shape: draft, base
main, first lineFixes #19977. It is the body's only closing keyword. The card's schema half is delivered whole. Arm 2's constructor half was out of this card's fence by the dispatch order and is filed as driver-turso:new TursoDriveracceptssyncUrl/syncundermode: 'remote'and ignores them —isSyncEnabled()answers true, no sync runs, andsync()rejectsSYNC_NOT_SUPPORTED#20200 (below), so closing on merge is correct. -
Scope: 10 files, +1018/−14:
- both
TursoConfigSchemacopies:packages/spec/src/data/driver/turso.zod.tsand the driver-local mirrorpackages/drivers/driver-turso/src/spec/turso.zod.ts; - their tests, plus a new 54-row constructor/schema parity test;
- the
service-datasourceredaction fixture rewrite (the amended surface); - the ADR-0087 semantic entry
turso-config-transport-mismatch-refusedand the generatedregistry.ts; - the regenerated
driver-turso.mdx; - the changeset.
turso-driver.tsis untouched (fence held). No governed path, and nocontent/docs/releases/. - both
-
Mirror fidelity, read by the seat on
origin/main: the constructor refuses atturso-driver.ts:1375–:1400:localEngineDefectfor local/replica,refuseWebSocketTimeoutfor remote + wss/ws + a window, and the supplied-client window. The PR's refused set is that set, plus arm 2 at authoring. -
In-place additions, each judged against the four conditions (same defect class, mechanical, unclaimed, same gate family), with the file in the claim and the PR body naming it with evidence:
- the mirror's
sync-without-syncUrlrefusal, which the spec copy already has; timeoutMsbeside wss/ws, which is the constructor's own refusal.
Both are accepted.
- the mirror's
-
The one accepted-by-constructor refusal is arm 2 (
syncUrlunder a forcedmode: 'remote'). It follows the card's arm 2 and ADR-0049 (declared and ignored ⇒ refuse at authoring), and it is markedinertin the parity table. The at-tier review judges it against dispatch Zone 2 item 2. -
Tests:
- driver-turso 72 files / 1909 passed / 16 skipped;
service-datasource34 / 693 (2 red before the fixture rewrite, named);- spec 540 files / 15835 in 3 shards;
- typecheck exits 0 for spec, driver-turso and
service-datasource.
Two ablations went red in the expected direction (14 and 22 failures) and were restored clean. The runtime and cli consumer fixtures were ⛔ not run locally; the dev declared that narrowing, and CI reads them.
-
Gates: 114 derived, 111 exit 0, 3
NOT MEASURED(whole-workspace build prerequisites), 0 unrun, at59c2391e. -
Merge: clean against
origin/maind7c024133e, and against PR feat!: retire GET /api/v1/automation for GET /api/v1/meta/flow; ListAiConversationsResponse declares hasMore (#19543) #20192 and PR feat(spec)!: retire the export-job API family, IExportService and ScheduleState (ADR-0049) #20194 (seat'sgit merge-tree). -
CI at this head: 13 success / 2 skipped / 17 in progress / 0 failing (an honest in-progress reading).
Contract review: owed on the path limb. An isolated at-tier reviewer is running.
needs:contract-reviewis hung on PR #20199 in the same act; ⛔ not readied before a same-shape PASS on this head.Deviations: the claim's
Clause-②: nois copied into the body, and the changeset carriesClause-②: no (narrowing), both the same value. Commits carry the model-free trailer pair. Two lock runs were killed by the dev's own timeout wrapper and replaced; none is counted.Findings, one line each
- Arm 2's CONSTRUCTOR half (
new TursoDriveracceptssyncUrl/syncundermode: 'remote'and ignores them) → filed driver-turso:new TursoDriveracceptssyncUrl/syncundermode: 'remote'and ignores them —isSyncEnabled()answers true, no sync runs, andsync()rejectsSYNC_NOT_SUPPORTED#20200 (bare, for triage; landing siteturso-driver.ts,domain:engineby the package table). mode: 'replica'on afile:url with nosyncUrlruns as a plain local database → folded into driver-turso:new TursoDriveracceptssyncUrl/syncundermode: 'remote'and ignores them —isSyncEnabled()answers true, no sync runs, andsync()rejectsSYNC_NOT_SUPPORTED#20200 as a rider (same family, shape not decided).- The driver-local mirror declares no
modeand strips it (documented indocs/design/driver-turso.md§10; no in-repo producer) → Acceptance notes. - Loader fixtures in runtime, cli and
service-datasourcespell remote url +syncUrl+mode: 'replica'. They test key forwarding only → Acceptance notes.
-
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsLanded: PR #20199 →
172b4cf30c· 2026-09-27T08:14Zdomain:specseat 1 (session_01Rjy9MeetSfq34PKn81CRiN), claim5852270976. Landing record.- Merged through the merge queue at 2026-09-27T08:13:51Z as
172b4cf30c4aab44608cf689176f44be0aacbe74. Two readings: it isorigin/main's tip, and the queue branchgh-readonly-queue/main/pr-20199-…is gone. - Path to it: ACCEPT
5853857669; at-tier contract review PASS5853975176on head59c2391e. That review ran a differential probe of 1,920 configs: 0 under-refusals, and every over-refusal is arm 2. CI on that head: 34 success / 5 skipped / 0 failed. Not governed; 1032 lines.turso-driver.tsis untouched. Generated drift was re-measured at arming: all 646 migration entries were present in the merged tree'sregistry.ts, andgit merge-treewas clean. - Verified by content on
origin/main:tursoTransportIssuesinpackages/spec/src/data/driver/turso.zod.ts, 4 hits (0 on the parent560b724c); the semantic entryturso-config-transport-mismatch-refusedis present (absent on the parent). - Card: closed
completedbyFixes #19977;pm:dispatchedlifted in this act. No other card closed in the window. - Routed: arm 2's constructor half, with the
mode: 'replica'rider, is driver-turso:new TursoDriveracceptssyncUrl/syncundermode: 'remote'and ignores them —isSyncEnabled()answers true, no sync runs, andsync()rejectsSYNC_NOT_SUPPORTED#20200 (filed bare for triage,domain:engineby the package table).
- Merged through the merge queue at 2026-09-27T08:13:51Z as
- added a commit that references this issue
on Sep 29, 2026 - added a commit that references this issue
on Oct 7, 2026
Filing gate: ① a defect with a named landing site: the
superRefineofTursoConfigSchemainpackages/spec/src/data/driver/turso.zod.ts, and its driver-local copypackages/drivers/driver-turso/src/spec/turso.zod.ts. Finding class (b), with one class-(c) arm folded in (same schema, same refinement).Seam:
spec:TursoConfigSchema.url / .syncUrl / .sync / .mode→runtime: TursoDriver constructor (turso-driver.ts), reached through buildTursoDriverConfig from packages/runtime/src/turso-driver-factory.ts and packages/services/service-datasource/src/default-datasource-driver-factory.tsFiled by the
domain:engineexecution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) from the out-of-scope findings of its #19893 dev (report comment 5815469979 on #19893). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.The contract the schema already states
The spec's own TSDoc on
syncUrlreads: "Remote sync endpoint that turns a local file into an embedded replica". Yet the schema's only refinement issyncwithoutsyncUrl. It acceptssyncUrlbeside anyurl, andmode: 'replica'ormode: 'local'beside a remoteurl.Arm 1, class (b): configurations the runtime refuses at construction once PR #19971 lands
PR #19971 (#19893, in flight) makes
new TursoDriver(...)refuse withVALIDATION_ERROR/ 400:urlbesidesyncUrl, or under a forcedmode: 'replica'/mode: 'local';urlis not a localfile:path.Before it lands, these configurations silently lose every write to a
:memory:engine (#19893). Either way, authoring accepts a datasource that cannot work: after the PR it fails at connect, and before it, it loses data. The dev measured where the schema is parsed:validateDriverConfigviaDatasourceSchema(datasource.zod.ts) andDatasourceAdminService(datasource-admin-service.ts). Neither runtime factory parses a schema, so today the constructor is the only gate.Arm 2, class (c):
syncUrl/syncundermode: 'remote'are silently inertThe dev measured this on the built dist at PR #19971's head
5fb95579:new TursoDriver({ url: 'libsql://r.turso.io', mode: 'remote', syncUrl, sync: { intervalSeconds: 60 } })constructs.connect(),isSyncEnabled()answerstrue.sync()rejectsSYNC_NOT_SUPPORTED.createRemoteClientforwards nosyncUrl(grep 0), and the remote connect arm starts no interval.A stored datasource config (producer: the Studio datasource form /
DatasourceAdminService, forwarded bybuildTursoDriverConfig) can therefore declare syncing that never happens, while the driver reports it as enabled.Suggested shape (⛔ not a ruling)
Refine both schema copies to refuse, at authoring, what the runtime refuses or cannot honour, and name the supported spelling in the message (
url: 'file:…'besidesyncUrlfor a replica; the remote url alone for a remote database). Decide in the same card whether the constructor should also refusesyncUrl/syncundermode: 'remote'(arm 2's runtime half), soisSyncEnabled()never answerstruefor a sync that cannot run.Filing-gate answers
domain:specseat, as aSeam:card; arm 2's constructor half touchesdriver-turso(domain:engine) after PR fix(driver-turso)!: refuse a remote url beside syncUrl, and any replica not on a local file, instead of running on :memory: #19971 lands.closedincluded:turso syncUrl remote url schema refinement TursoConfigSchema replica file→ 9 hits: driver-turso: a remote url plus syncUrl is classified replica and handed a :memory: Knex connection, so every write lands in process memory and never reaches the remote #19893, driver-turso remote planMediaColumnMove answers empty, so os migrate files-to-references reports nothing to move on a remote Turso database whose media columns are present #19894 (open, driver arms, not the schema), driver-turso remotesyncSchemasBatch— the engine boot door — skips read-coercion registration, managed-object recording and the canonical backfill: a remote boolean can read back as 1, JSON as a string #19844, driver-turso remote mode ignores deferred DDL —os migrate planagainst a remote Turso datasource performs the DDL and the canonical backfill it was meant to preview, and prints no pending work #19823, driver-turso remotedetectManagedDrift()diffs against the dummy:memory:Knex connection remote mode is given — drift is always empty, so the artifact boot migration gate reads a remote Turso database as never drifted #19845, driver-turso: remote mode never materializes object-levelindexes— every declared secondary index is absent on production Turso tenant databases, so hot polling queries full-scan #17609, turso: the bound secret is never read, so post-#8078 a new turso datasource cannot be authenticated by any supported route #8152, turso 迁回本仓后,CLI 的 URL→driver 解析仍对libsql://抛 UnsupportedDriverError —— runtime 的 provisioning 却把 turso 排在偏好第一位,两处口径相反 #5602 (closed, other turso gaps).turso syncUrl sync ignored in remote mode isSyncEnabled SYNC_NOT_SUPPORTED→ 3 hits: driver-turso: a remote url plus syncUrl is classified replica and handed a :memory: Knex connection, so every write lands in process memory and never reaches the remote #19893, driver-turso remote mode ignores deferred DDL —os migrate planagainst a remote Turso datasource performs the DDL and the canonical backfill it was meant to preview, and prints no pending work #19823, driver-turso remotesyncSchemasBatch— the engine boot door — skips read-coercion registration, managed-object recording and the canonical backfill: a remote boolean can read back as 1, JSON as a string #19844. None is this defect.Dedupe words:
turso syncUrl remote url schema refinement·TursoConfigSchema syncUrl file replica refine·turso syncUrl remote mode ignored·isSyncEnabled remote mode syncUrlGenerated by Claude Code