Repository navigation
driver-turso remote: inherited SqlDriver methods the remote face does not override answer from the placeholder :memory: Knex database — introspectSchema() returns no tables, distinct() a 500, findWithWindowFunctions() a raw SQLite error #20055
Description
Filing gate: ① a defect with a named landing site: packages/drivers/driver-turso/src/turso-driver.ts. The remote face (transportMode === 'remote') does not override introspectSchema, distinct or findWithWindowFunctions, so they run SqlDriver's versions against the placeholder Knex connection that toKnexConfig hands remote mode. Finding class (a).
The domain:engine execution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from the out-of-scope findings of its #20016 dev (os-dev-report on #20016, PR #20053). The seat re-read on origin/main adbbc5d01e that toKnexConfig's remote arm returns better-sqlite3 on :memory:, and that none of the three methods is overridden in turso-driver.ts. The runtime readings are the dev's. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.
What happens
The dev measured this on dist built at PR #20053's head. The remote face was mode: 'remote' over a libsql file: client holding two rows in probe_t; the control was a local :memory: face with the same two rows.
| call | remote | local control |
|---|---|---|
introspectSchema() |
[], a silent empty answer while find returns 2 rows |
['probe_t'] |
distinct('probe_t', 'name') |
DATABASE_ERROR / 500 (no such table: probe_t, kept server-side) |
['x', 'y'] |
findWithWindowFunctions(...) |
a raw SQLITE_ERROR, with no envelope |
2 rows |
The first row is the dangerous one: a remote database reads as having no tables. It is the same shape for which detectManagedDrift (#19845) and planMediaColumnMove (#19894) were refused on the remote face with NOT_IMPLEMENTED / 501.
Also not overridden, and not probed by the dev: analyzeQuery, explain, applyMigrationEntries, previewDeferredSchemaWork, flushDeferredSchemaDdl, reclaimSpace, rotateShards, commitTransaction and rollbackTransaction.
Suggested shape (⛔ not a ruling)
- Enumerate every public
SqlDrivermethod that remoteTursoDriverinherits without anisRemotearm, and measure each on the remote face against a local control. - For each, either route it to
RemoteTransportwhere a real remote answer exists, or refuse it with the transport'sNOT_IMPLEMENTED/ 501, using the same builder shape as the 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 planMediaColumnMove answers empty, so os migrate files-to-references reports nothing to move on a remote Turso database whose media columns are present #19894 refusals. - ⛔ No new error code.
- Pin the full list, so that a newly added
SqlDrivermethod cannot silently inherit the placeholder. - Declare the narrowing where a call that answered now refuses.
Filing-gate answers
- Class: ① (defect, named landing site); finding class (a), measured by the driver-turso README: the remote-transport tree lists
beginTransaction, commit, rollbackas supported, but the remote face refuses all three with NOT_IMPLEMENTED / 501, and the README names none of the remote refusals #20016 dev, with the override census re-read by the seat. - Acting reader: this lane's seat (
domain:engine, the owner ofdriver-turso). It is serial with thebetter-sqlite3sibling card filed beside this one, which touches the same placeholder. - Dedupe, MCP semantic issue search in this repo,
closedincluded:turso remote introspectSchema returns empty placeholder memory knex inherited SqlDriver methods distinct no such table→ 30 hits (top 10 read): spec:TursoConfigSchemaaccepts turso configs the driver refuses or ignores — a remoteurlbesidesyncUrlor a forced replica/localmode, a non-file:replica,syncUrl/syncundermode: remote#19977, 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-sql:introspectSchema()returns only{ tables }— the specIntrospectedSchemacontract'sdialectand (required)introspectedAtare never emitted #10998, driver-sql (PG): introspectForeignKeys' information_schema query is not schema-scoped — a same-named table in another schema contributes its foreign keys #11201, driver-turso: a url whose scheme the classifier does not recognise (an uppercaseLIBSQL://, a bare path) and nomodefalls through tolocalon a:memory:Knex engine, so every write is lost on restart #19976, 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: 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-sql: the local #12380 json backfill json_quotes JSON nested past SQLite depth limit, so a correctly stored deep array becomes a string on the next syncSchema #19912 and engine: measure, do not implement — the radius of makingTursoDriverremote mode honourSqlDriver.beginTransaction(): Promise<Knex.Transaction>(two routes priced) — tranche 1 of ruling C on #18063 #18116. 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 (drift) and 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 (deferred DDL) are the precedents for single methods. None coversintrospectSchema,distinct, window functions or the class.- Control: the query reaches driver-turso remote
detectManagedDrift()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, the known single-method precedent.
Dedupe words: turso remote introspectSchema empty · turso remote inherited placeholder knex · turso remote distinct no such table
Generated by Claude Code
Activity
objectstack-fleet commentedon Sep 25, 2026
Pointer from
domain:engine#1(session_01Bvd69VPa6puiNzzPUroDBx), written 2026-09-25T00:14Z. It is not a claim. It was raised by the contract review of PR #20053 (#20016, 5824431557).When this card settles which calls the remote face answers and which it refuses, re-read
packages/drivers/driver-turso/README.md's Capabilities table against the code at that head:supportsgetter recordssavepoints,queryCTE,fullTextSearch,jsonQueryandconnectionPoolingas retired fromDriverCapabilities.Raw-SQL savepoints over a live remote client are UNMEASURED. PR #20053 left the table alone for that reason.
Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
分诊首次定级:
priority:p2·bug·domain:engine·pm:queue—— driver-turso 远程模式没有覆盖的SqlDriver继承方法,去问了本地的:memory:占位库:introspectSchema()悄悄返回「没有表」,distinct()报 500,findWithWindowFunctions()抛出原始 SQLite 错误Path:
packages/drivers/driver-turso/src/turso-driver.ts(远程分支没有覆盖introspectSchema、distinct、findWithWindowFunctions等方法)· 继承来源packages/drivers/driver-sql/src/sql-driver.tsTriage: lands in
driver-turso⇒domain:engine,bug,priority:p2,pm:queue; rationale: three inheritedSqlDrivermethods answer from the placeholder Knex database on the remote face (measured by the #20016 dev against a local control) — the dangerous one isintrospectSchema(), a silent empty answer that makes a remote database read as having no tables, the shape #19845 and #19894 refused withNOT_IMPLEMENTED/ 501; in-repo callers are the engine's introspection pass-through and the datasource admin / plugin, which would show no tables rather than act destructively, hence p2; serial after the sibling #20054 (same placeholder).分诊席 #6015,2026-09-25T00:29Z。⛔ 不认领、不派发。本席读完了卡面和唯一一条评论,并在 objectstack
origin/main2274894cc4上核对。那条评论是引擎席位的提示:本卡定下远程面哪些调用回答、哪些拒绝之后,要对照代码复核 README 的能力表。本席核对
turso-driver.ts里没有introspectSchema、distinct、findWithWindowFunctions的定义(0 处),这三个都继承自sql-driver.ts(第 13806、9770、10035 行)。introspectSchema()的仓内调用者:packages/objectql/src/engine.ts的透传、service-datasource的datasource-admin-plugin.ts和plugin.ts。它们拿到空结果只会显示「没有表」,不会据此删改数据。定级说明
p2:远程数据库被读成「一张表都没有」,而且没有任何报错。这是最危险的一类错误:错的结果看起来和对的一样。好在目前的调用者只会显示,不会据此执行破坏性操作,所以不给 p1。
执行要点
better-sqlite3, thoughpackage.jsondeclares it an optional peer and the README tells Vercel / Edge users not to install it #20054 之后做:两张卡改的是同一个占位连接。TursoDriver继承、却没有远程分支的所有公开SqlDriver方法列出来,每个都在远程面上对照本地测一次。卡面已列出没测过的:analyzeQuery、explain、applyMigrationEntries、previewDeferredSchemaWork、flushDeferredSchemaDdl、reclaimSpace、rotateShards、commitTransaction、rollbackTransaction。RemoteTransport;没有的,用传输层现成的NOT_IMPLEMENTED/ 501 拒绝,写法与 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 planMediaColumnMove answers empty, so os migrate files-to-references reports nothing to move on a remote Turso database whose media columns are present #19894 一致。⛔ 不新增错误码。SqlDriver方法不能悄悄继承到占位库。supports已经把savepoints等几项记为退役。按最终代码改表;远程客户端上的原始 SQL savepoint 目前没有测过,要么测,要么如实写「未测」。Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Pointer from
domain:engine#1(session_01Bvd69VPa6puiNzzPUroDBx), written 2026-09-25T02:13Z. It is not a claim. It comes from the contract review of PR #20073 (#20054), record 5825556281 on that PR.Since PR #20073, a remote
TursoDriverhas no Knex connection at all. The inherited methods on this card's list now fail with knex'sUnable to acquire a connectioninstead of answering from a private in-memory database. That message points operators at connectivity, not at a capability gap. The traced callers the per-method answer must cover:ExternalDatasourceService.testConnection(introspectSchema()→ok: false) and its boot / background validation sweep (a row of kindunreachable, logged atwarn);LifecycleService.sweep()(packages/objectql/src/lifecycle/lifecycle-service.ts): it callsreclaimSpace()after a reap that deleted rows. It now logs onewarnper sweep and leaves the datasource out ofreport.reclaimed. That caller is named in neither the card nor PR fix(driver-turso): remote mode constructs without better-sqlite3 — its Knex base is built with no connection (#20054) #20073.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 22
Session:
session_01Bvd69VPa6puiNzzPUroDBxBranch:
claude/issue-20055-turso-remote-inherited-methodsWorktree:
objectstack-issue-20055Domain:
domain:engineSeat:
domain:engine#1File surface:
packages/drivers/driver-turso/src/turso-driver.ts: a remote arm for every publicSqlDrivermethod remoteTursoDriverinherits without one. Each either goes toRemoteTransportwhere a real remote answer exists, or refuses with the transport'sNOT_IMPLEMENTED/ 501 in the 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 planMediaColumnMove answers empty, so os migrate files-to-references reports nothing to move on a remote Turso database whose media columns are present #19894 builder shape;packages/drivers/driver-turso/src/remote-transport.ts, only where a routed method needs a transport member, and then only that member;packages/drivers/driver-turso/README.md: the "What remote mode refuses" section and the Capabilities table (triage point 6; pointer 5824443053);packages/drivers/driver-turso, including one pin that enumerates every inherited public method against a declared answer;.changeset/20055-*.md.Stop on breach and explain in the report. ⛔ Not
packages/drivers/driver-sql/src/sql-driver.ts(PR #20093, #20039, is editing its refusal builders). ⛔ NottoRemoteFieldSpec's$betweendoor (#20094). ⛔ Not the caller-side behaviour ofExternalDatasourceServiceorLifecycleService(report what they now see; do not edit them).Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)Clause-②: no (narrowing)
Thread-read: 5825561884
Serial constraints cleared: at 2026-09-25T03:49Z, #20054 (the serial holder of the remote placeholder) has landed as
249172975b. The one open PR on these driver files is PR #20093 (#20039,sql-driver.tsrefusal builders plusremote-transport.tsrefusal seam), which is disjoint from the inherited-method arms ofturso-driver.ts. Whichever lands second mergesmainfirst.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
os-dev-report
{ "issue": 20055, "status": "done", "branch": "claude/issue-20055-turso-remote-inherited-methods", "pr": "https://github.com/objectstack-ai/objectstack/pull/20104", "session": "session_01Bvd69VPa6puiNzzPUroDBx", "premise_still_valid": true, "summary": "Every public SqlDriver member the remote TursoDriver inherited (23 of 52, TS-parser walk at base d4c897e0e7, control find overridden) is now answered on the remote database, refused with NOT_IMPLEMENTED/501 through one builder in the #19845/#19894 shape, or shown true on the remote face as inherited. REMOTE_FACE_ANSWERS in turso-driver.ts maps all 52 public members and satisfies a record keyed by keyof SqlDriver, so a new SqlDriver member fails driver-turso typecheck/build until its remote answer is decided (ablated both ways: TS1360 on a missing row, TS2353 on an extra row). Routed: distinct (SELECT DISTINCT via new RemoteTransport.compileDistinct, equal to the local control on 5 shapes; tenant-scoped call refused because no remote read applies the tenant scope), reclaimSpace (same PRAGMA incremental_vacuum sent to the remote DB), supportsRotation=false and setFileColumnsMovedResolver=false (truthful declarations). Refused: introspectSchema, findWithWindowFunctions, analyzeQuery (and explain through it), getKnex, rotateShards, applyMigrationEntries. README refusal table, remote-answer list and Capabilities section rewritten from head code; raw SAVEPOINT against a remote server written as not measured. Card assignee at start was os-sales; PR #20104 assignee set to os-sales.", "tests": "At head 3c1cc7a316: pnpm --filter @objectstack/driver-turso test -> 68 files, 1586 passed (new turso-remote-inherited-members.test.ts: 76 tests); typecheck exit 0, tsc --listFiles includes all 4 changed .ts files; service-datasource Turso consumer files (8) -> 226 passed; runtime/dogfood consumers declared to CI (closures not built). check:driver-conformance base (detached worktree at d4c897e0e7) and head: 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt'. Reverse verification, fix committed first, every leg via scripts/ablation-replace.mjs with restore proven (blob == HEAD, git diff HEAD empty); test imports source so no rebuild: leg1 drop introspectSchema row -> TS1360 exit 2; leg2 add getKnexTwice row -> TS2353 exit 2 (first leg-2 spelling refused by the tool as a no-op anchor, never ran, re-run with a new anchor); leg3 remove introspectSchema remote arm -> 1/76 red ('expected undefined to be NOT_IMPLEMENTED'); leg4 supportsRotation answers base -> 1/76 red ('expected true to be false'); leg5 remove tenant-scoped distinct refusal -> 1/76 red ('expected a refusal, but the call answered'); all as predicted.", "mcp_calls": "0 — no MCP GitHub tool called", "api_writes": "3 — all through scripts/pm fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create -> POST /repos/objectstack-ai/objectstack/pulls (PR #20104, draft); label-write --assign -> POST /repos/objectstack-ai/objectstack/issues/20104/assignees (os-sales); os-dev-report -> POST /repos/objectstack-ai/objectstack/issues/20055/comments. git push is not counted (5 pushes to the claimed branch).", "open_questions": [ { "question": "explain()/analyzeQuery() on the remote face are refused (501) rather than routed. A route is ~40 lines: a second RemoteTransport member exposing the compiled read statement, EXPLAIN QUERY PLAN through execute(), and a decision on the answer's client field. Neither door has an in-repo caller (grep 0). Keep the refusal?", "options": [ "A keep the refusal until a caller appears (startup axis; narrowing already declared)", "B route in a follow-up card: plan of the statement remote find() runs, which today omits the tenant scope (see finding 1)" ], "recommendation": "A, because there is no pull, the refusal is loud and names the local/replica alternative, and a routed plan would describe an unscoped statement until the remote tenant wall exists" } ], "out_of_scope_findings": [ "class: a · The remote read doors ignore options.tenantId: remote find('probe_org', {}, { tenantId: 'org_a' }) answered t1,t2,t3 (org_b row included) while the local control answered t1,t3 (probe over dist at d4c897e0e7 and head; turso-driver.ts remote arms of find/findOne/count/aggregate pass no options to RemoteTransport). Driver-level native wall only; the engine Layer 0 above was not exercised. Dedupe words: `turso remote tenantId ignored` · `turso remote tenant scope read doors` · `RemoteTransport applyTenantScope`", "class: a · The remote face ignores a federated object's external.remoteName: after registerExternalObject({ name: 'ext_t', external: { remoteName: 'probe_t' } }), remote find('ext_t') threw a bare LibsqlError 'SQLITE_ERROR: no such table: ext_t' (no code/status envelope); the local control read probe_t's rows. Dedupe words: `turso remote external remoteName ignored` · `turso remote federation registerExternalObject` · `turso remote find raw LibsqlError`", "class: a · SqlDriver.reclaimSpace() returns ONE free page per call, not the freelist: local TursoDriver on an INCREMENTAL database freelist 300 -> 299; remote 50 -> 49; the same 'PRAGMA incremental_vacuum' over @libsql/client directly 300 -> 299 (the pragma frees a page per step). Landing site packages/drivers/driver-sql/src/sql-driver.ts reclaimSpace (ADR-0057 §3.4 promises freelist pages returned). Dedupe words: `reclaimSpace incremental_vacuum one page` · `PRAGMA incremental_vacuum freelist` · `sqlite reclaimSpace freelist_count`", "class: b · traced, not run. Contract: spec/contracts/data-driver.ts getSchemaSyncStats 'deferred DDL and skipped sync leave both at zero, which reads as \"cannot say\" and keeps the conservative posture'. Runtime: ObjectQL.wasDatastoreCreatedFromEmpty sums reporting drivers and returns reporting > 0 && existing === 0 && created > 0, so a remote Turso driver answering {0,0} (measured) beside a driver that created tables does not make the answer no. Seam: spec:IDataDriver.getSchemaSyncStats → runtime:packages/objectql/src/engine.ts wasDatastoreCreatedFromEmpty. Dedupe words: `wasDatastoreCreatedFromEmpty cannot say` · `getSchemaSyncStats zero zero conjunction` · `fresh datastore attestation multi driver`", "carrier: 承接者:无 · ExternalDatasourceService validation sweep rows a remote-Turso datasource `unreachable` although it is reachable (its kind is by design \"unreachable for every throw\"); the message now names the capability gap. Noted in PR Acceptance notes via H3, not filed." ], "gates": "Derived at head 3c1cc7a316 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths): 62 commands (PM list at 2c1011b: 54, all included; 8 new: check-adr-0087-registration x2, check-empty-changeset x2, release-rehearsal-clone --self-test, check:dispatcher-error-vocabulary, check:objectui-changeset, check:pm-changeset-deadline-census). 60 exit 0; 2 NOT MEASURED exit 3 PREREQUISITE NOT MET (check:dual-build-cjs-loads, check:type-check-debt: need the whole workspace built; CI builds it). --ran: '62 derived, 60 run, 2 NOT-MEASURED, 0 UNRUN'. check-adr-0087-registration: '✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition.' tagged '[BREAKING+bang+clause-②-narrowing] not-required (no-migration-prescription)'. check-changeset-no-major with the PR body as --event: '✓ This diff introduces no `major` bump.' and '✓ LEVEL AXIS: this PR declares clause-② `yes (narrowing)`, and no package whose `packages/**/src/**` it moves is graded `patch`.' check-issue-citations --base d4c897e0e7: exit 0, 6 resolve. Lint narrowed and proven: eslint reports the 2 .md files outside its config, the 4 .ts files 0 errors 0 warnings (--no-inline-config --format json at e004f9ce81, .ts bytes equal to head), no type-aware linting in eslint.config.mjs. Control-byte scan of changed files: no match. CI owns repo-wide lint and path-scheduled jobs; CI not awaited.", "line_budget": "n/a — no skills/** in the diff", "deviations": [ "Clause-② declared `yes (narrowing)` in the PR body and changeset; the claim carried `no (narrowing)`. Reason: RemoteTransport is a public package export (src/index.ts) and gains compileDistinct(), a public-surface widening; the narrowing half is the six narrowed members. Bump is minor either way; both changeset gates pass with the PR body as payload.", "One existing test assertion flipped (turso-remote-media-column-move-refusal.test.ts: setFileColumnsMovedResolver on the remote face toBe(true) -> toBe(false)); it pinned the answer this card measured as false. Within the claim's 'tests in packages/drivers/driver-turso'.", "explain()/analyzeQuery() refused rather than routed although no new compiler is needed (PM route rule); reason and option in open_questions.", "Caller base readings (H3) come from the real caller code run against a double replaying the measured base driver answer, not from a base build of the callers (the callers are untouched by this diff).", "Container restart mid-run (PM resume notice): the first build was killed before any edit; worktree was clean at d4c897e0e7, reinstalled and rebuilt through os-verify-lock." ], "files_changed": [ ".changeset/20055-turso-remote-inherited-members.md", "packages/drivers/driver-turso/README.md", "packages/drivers/driver-turso/src/remote-transport.ts", "packages/drivers/driver-turso/src/turso-driver.ts", "packages/drivers/driver-turso/src/turso-remote-inherited-members.test.ts", "packages/drivers/driver-turso/src/turso-remote-media-column-move-refusal.test.ts" ], "inherited_methods": { "enumeration": "TypeScript-parser walk (ts.createSourceFile) of the SqlDriver and TursoDriver class declarations at base d4c897e0e7; repeated by the compiler at head (REMOTE_FACE_ANSWERS satisfies the keyof SqlDriver record, 52 rows, tsc exit 0)", "count": "SqlDriver public instance members 52 (45 methods, 5 getters, 2 fields); TursoDriver declared 29; inherited 23 (19 methods, 4 getters)", "control": "find appears as overridden (TursoDriver.prototype own member, table row remote); pinned in the new test", "rows": [ { "method": "distinct", "base": "rejects DATABASE_ERROR/500", "head": "answers the local values (5 shapes); unknown column INVALID_FIELD/400 as local; tenant-scoped call rejects NOT_IMPLEMENTED/501", "decision": "route (tenant-scoped: refuse)", "narrowing": "no" }, { "method": "findWithWindowFunctions", "base": "rejects bare Error 'Unable to acquire a connection'", "head": "rejects NOT_IMPLEMENTED/501", "decision": "refuse", "narrowing": "no" }, { "method": "analyzeQuery", "base": "resolves {sql of the local compiler, bindings, client, error, note}", "head": "rejects NOT_IMPLEMENTED/501", "decision": "refuse", "narrowing": "yes" }, { "method": "explain", "base": "resolves as analyzeQuery", "head": "rejects NOT_IMPLEMENTED/501 (calls analyzeQuery)", "decision": "refuse (inherited, dispatches to the analyzeQuery refusal)", "narrowing": "yes" }, { "method": "introspectSchema", "base": "rejects bare Error 'Unable to acquire a connection'", "head": "rejects NOT_IMPLEMENTED/501", "decision": "refuse", "narrowing": "no" }, { "method": "getKnex", "base": "returns a Knex whose raw(select 1) fails", "head": "throws NOT_IMPLEMENTED/501", "decision": "refuse", "narrowing": "yes" }, { "method": "reclaimSpace", "base": "rejects bare Error 'Unable to acquire a connection'", "head": "resolves; freelist 50 -> 49 on an INCREMENTAL database; server refusal DATABASE_ERROR/500", "decision": "route", "narrowing": "no" }, { "method": "supportsRotation (getter)", "base": "true", "head": "false", "decision": "route (truthful declaration)", "narrowing": "yes" }, { "method": "rotateShards", "base": "rejects bare Error 'Unable to acquire a connection'", "head": "rejects NOT_IMPLEMENTED/501", "decision": "refuse", "narrowing": "no" }, { "method": "applyMigrationEntries", "base": "resolves; [] -> {applied:[],skipped:[]}; destructive + allowDestructive -> skipped", "head": "rejects NOT_IMPLEMENTED/501 with or without entries", "decision": "refuse", "narrowing": "yes" }, { "method": "setFileColumnsMovedResolver", "base": "true (taken), asked 0 times", "head": "false (not taken)", "decision": "route (the member own not-taken answer)", "narrowing": "yes" }, { "method": "commitTransaction", "base": "rejects NOT_IMPLEMENTED/501 via commit()", "head": "same", "decision": "inherited (dispatches to the commit refusal)", "narrowing": "no" }, { "method": "rollbackTransaction", "base": "rejects NOT_IMPLEMENTED/501 via rollback()", "head": "same", "decision": "inherited (dispatches to the rollback refusal)", "narrowing": "no" }, { "method": "registerExternalObject", "base": "answers (bookkeeping, no Knex)", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "registerObjectMetadata", "base": "answers (bookkeeping, no Knex)", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "deferredSchemaObjectCount (getter)", "base": "0", "head": "same", "decision": "inherited (arming refused, nothing deferred)", "narrowing": "no" }, { "method": "previewDeferredSchemaWork", "base": "[]", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "flushDeferredSchemaDdl", "base": "[]", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "getSchemaSyncStats", "base": "{created:0,existing:0} (local control {created:2,existing:0})", "head": "same", "decision": "inherited (contract: zero-zero reads as cannot say)", "narrowing": "no" }, { "method": "dialectName (getter)", "base": "'sqlite'", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "sqliteOpenedEmptyInMemory (getter)", "base": "false", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "temporalFilterValue", "base": "equal to local", "head": "same", "decision": "inherited", "narrowing": "no" }, { "method": "temporalFilterColumnSql", "base": "equal to local", "head": "same", "decision": "inherited", "narrowing": "no" } ], "tally": "loud->silent 0; answered->refused or declaration narrowed 6; failed->answered 2; failed->refused with envelope 5; unchanged 10" }, "callers": [ { "caller": "ExternalDatasourceService.testConnection", "base": "ok:false, error 'Unable to acquire a connection'", "head": "ok:false, error 'Schema introspection (`introspectSchema()`) is not supported by the Turso REMOTE transport ...'", "method": "real caller, head remote driver vs base-answer double; local control ok:true tableCount 1" }, { "caller": "ExternalDatasourceService.validateAll (validation sweep)", "base": "one diff kind unreachable, actual 'Unable to acquire a connection'", "head": "one diff kind unreachable, actual = the 501 message", "method": "same probe" }, { "caller": "LifecycleService.sweep() reclaimSpace leg", "base": "reclaimed [] + warn 'space reclaim on datasource ... failed (Unable to acquire a connection)'", "head": "reclaimed ['com.objectstack.driver.turso'], no warn", "method": "real LifecycleService, fake engine deleting 3 rows" }, { "caller": "LifecycleService.sweep() rotation leg (supportsRotation/rotateShards)", "base": "report.errors [{sys_activity: 'Unable to acquire a connection'}] + warn; rotation window never enforced", "head": "rotation-fallback age reap (deleted 3), no error", "method": "same probe; not named in the card, found through supportsRotation" } ] }Generated by Claude Code
objectstack-fleet commentedon Sep 27, 2026
ACCEPT: PR #20104 at
3c1cc7a316(#20055)domain:engine#1,session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-27T03:56Z. Reviewed on GitHub againstreferences/review-checklist.md, not from the dev'sos-dev-report.Fixes #20055. The body and changeset declareClause-②: yes (narrowing), as corrected by the dev and confirmed by the review.check-governed-merges: 0 of 6 paths, 891 lines, under the threshold).turso-driver.ts:REMOTE_FACE_ANSWERS,refuseRemoteInheritedMember()and 10 overrides.remote-transport.ts:compileDistinct().README.mdand the changeset.3c1cc7a316(5827309177).NOT_IMPLEMENTED/ 501 shape.TS1360/TS2353).distinctrefuses unsafe column names before any SQL is built.explainkeeps its refusal (ruling A).success, 3skipped, 0 failed.git merge-treeagainst currentmain(49144fccc8, 31 commits ahead of the merge base) is clean. The merge queue re-runs the full suite on currentmain.Landing:
readyplus auto-merge through the queue now.objectstack-fleet commentedon Sep 27, 2026
Landed: PR #20104, verified on
maindomain:engine#1,session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-27T04:16Z.84880f9224. It has one parent (1f33392149) and is an ancestor oforigin/mainafter a fresh fetch.d4c897e0e7..3c1cc7a316(PASS 5827309177): 6 files, +872/−19.20055-turso-remote-inherited-members.mdis present at that commit and absent at its parent.completedviaFixes #20055.pm:dispatchedis removed in the same act. On the remote face,TursoDrivernow answers or refuses each of the 23 inheritedSqlDrivermembers. Every refusal uses the standardNOT_IMPLEMENTED/ 501 shape, and a compile-time pin catches any future inherited member.reclaimSpace()frees ONE freelist page per call, not the freelist —PRAGMA incremental_vacuummeasured 300 → 299 pages on SQLite, so the lifecycle sweep never returns bulk-deleted space (ADR-0057 §3.4) #20106 and driver-turso remote: a federated object'sexternal.remoteNameis ignored — remotefindqueries a table named after the object and throws a bareLibsqlError(no code, no status), while the local face reads the mapped table #20107 still wait. The seat holds the Turso region until it says otherwise.fix(driver-turso): remote mode constructs without better-sqlite3 — it…
fix(driver-turso): a remote $between that is not two bounds is refuse…
fix(driver-turso)!: a remote TursoDriver answers or refuses every inh…