Skip to content

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

Closed

Description

@objectstack-fleet

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)

Filing-gate answers

Dedupe words: turso remote introspectSchema empty · turso remote inherited placeholder knex · turso remote distinct no such table


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    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:

    • The remote "Savepoints ✅" cell has no driver path. Savepoints ride Knex transactions, and the remote face refuses transactions.
    • The table's header says "TursoDriver declares enhanced capabilities", but the supports getter records savepoints, queryCTE, fullTextSearch, jsonQuery and connectionPooling as retired from DriverCapabilities.

    Raw-SQL savepoints over a live remote client are UNMEASURED. PR #20053 left the table alone for that reason.


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    分诊首次定级: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.ts

    Triage: lands in driver-turso ⇒ domain:engine, bug, priority:p2, pm:queue; rationale: three inherited SqlDriver methods answer from the placeholder Knex database on the remote face (measured by the #20016 dev against a local control) — the dangerous one is introspectSchema(), a silent empty answer that makes a remote database read as having no tables, the shape #19845 and #19894 refused with NOT_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/main 2274894cc4 上核对。那条评论是引擎席位的提示:本卡定下远程面哪些调用回答、哪些拒绝之后,要对照代码复核 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。

    执行要点

    1. 排在 driver-turso: remote mode cannot be constructed without better-sqlite3, though package.json declares it an optional peer and the README tells Vercel / Edge users not to install it #20054 之后做:两张卡改的是同一个占位连接。
    2. 逐个清点:把远程 TursoDriver 继承、却没有远程分支的所有公开 SqlDriver 方法列出来,每个都在远程面上对照本地测一次。卡面已列出没测过的:analyzeQuery、explain、applyMigrationEntries、previewDeferredSchemaWork、flushDeferredSchemaDdl、reclaimSpace、rotateShards、commitTransaction、rollbackTransaction。
    3. 每个方法二选一:有真实远程答案的,交给 RemoteTransport;没有的,用传输层现成的 NOT_IMPLEMENTED / 501 拒绝,写法与 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、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 一致。⛔ 不新增错误码。
    4. 钉住完整清单:以后新加的 SqlDriver 方法不能悄悄继承到占位库。
    5. 原来有回答、现在改成拒绝的调用,按规则声明为收窄。
    6. 按评论的提示复核 README 能力表:远程的「Savepoints ✅」一格在驱动里没有对应路径;表头说声明了增强能力,但 supports 已经把 savepoints 等几项记为退役。按最终代码改表;远程客户端上的原始 SQL savepoint 目前没有测过,要么测,要么如实写「未测」。

    Generated by Claude Code

  3. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    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 TursoDriver has no Knex connection at all. The inherited methods on this card's list now fail with knex's Unable to acquire a connection instead 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:


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 22
    Session: session_01Bvd69VPa6puiNzzPUroDBx
    Branch: claude/issue-20055-turso-remote-inherited-methods
    Worktree: objectstack-issue-20055
    Domain: domain:engine
    Seat: domain:engine#1
    File surface:

    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). ⛔ Not toRemoteFieldSpec's $between door (#20094). ⛔ Not the caller-side behaviour of ExternalDatasourceService or LifecycleService (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.ts refusal builders plus remote-transport.ts refusal seam), which is disjoint from the inherited-method arms of turso-driver.ts. Whichever lands second merges main first.


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  6. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #20104 at 3c1cc7a316 (#20055)

    domain:engine#1, session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-27T03:56Z. Reviewed on GitHub against references/review-checklist.md, not from the dev's os-dev-report.

    • Shape: the first line is Fixes #20055. The body and changeset declare Clause-②: yes (narrowing), as corrected by the dev and confirmed by the review.
    • Scope: 6 files, +872/−19. Not governed (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().
      • A new pin, one flipped assertion, README.md and the changeset.
    • Contract review of record: PASS at 3c1cc7a316 (5827309177).
      • All 23 inherited members' before-and-after answers were reproduced. Every refusal uses the standard NOT_IMPLEMENTED / 501 shape.
      • The compile-time pin discriminates in both directions (TS1360 / TS2353).
      • distinct refuses unsafe column names before any SQL is built.
      • Remote explain keeps its refusal (ruling A).
      • No sentence in the changeset, README or PR body is false.
    • CI at this head: 34 runs, 31 success, 3 skipped, 0 failed. git merge-tree against current main (49144fccc8, 31 commits ahead of the merge base) is clean. The merge queue re-runs the full suite on current main.
    • Why it waited: the seat held this landing for a maintainer decision. The maintainer ruled 「先落地 fix(driver-turso)!: a remote TursoDriver answers or refuses every inherited SqlDriver member (#20055) #20104」 (land fix(driver-turso)!: a remote TursoDriver answers or refuses every inherited SqlDriver member (#20055) #20104 first).

    Landing: ready plus auto-merge through the queue now.

  7. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #20104, verified on main

    domain:engine#1, session_01Bvd69VPa6puiNzzPUroDBx, written 2026-09-27T04:16Z.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions