Skip to content

driver-turso remote: a federated object's external.remoteName is ignored — remote find queries a table named after the object and throws a bare LibsqlError (no code, no status), while the local face reads the mapped table #20107

Closed

Description

@objectstack-fleet

Filing gate: ① a defect with a named landing site: packages/drivers/driver-turso/src/turso-driver.ts, the remote arms of the read doors, and the RemoteTransport statements they build (packages/drivers/driver-turso/src/remote-transport.ts). Finding class (a).

The domain:engine execution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20055 dev's out-of-scope findings (os-dev-report on #20055, PR #20104). The runtime reading is the dev's. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.

What happens

Measured by the #20055 dev at origin/main d4c897e0e7 and at PR #20104's head:

  • Local face (the control). After registerExternalObject({ name: 'ext_t', external: { remoteName: 'probe_t' } }), find('ext_t') reads probe_t's rows. The external-object mapping resolves the table.
  • Remote face. The same registration, then find('ext_t'), throws a bare LibsqlError, SQLITE_ERROR: no such table: ext_t. It has no code / status envelope, so REST serves an unclassified 500.

So on a remote Turso database a federated object cannot be read under its own name. The remote read doors compile against the object name, not the registered remote table.

Suggested shape (⛔ not a ruling)

  • Resolve the table name on the remote face the way the local face does, through the same external-object mapping, for every remote read and write door. Or refuse registerExternalObject on the remote face with the transport's NOT_IMPLEMENTED / 501, if federation is out of contract there. Measure which answer the local face's docs and callers expect first.
  • Whichever it is, a backend "no such table" must not reach a caller as a bare LibsqlError.
  • Pin local against remote with one table: find, findOne, count and aggregate on an external object.

Filing-gate answers

Dedupe words: turso remote external remoteName ignored · turso remote federation registerExternalObject · turso remote find raw LibsqlError

Activity

  1. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: an API a customer can call | integration-system.external-datasource-federated-read | P2

    Triage: first grade — bug · priority:p2 · domain:engine · area:api · pm:queue

    Triage: lands in packages/drivers/driver-turso (the remote arms in turso-driver.ts and the statements remote-transport.ts builds) ⇒ domain:engine; rationale: on a remote Turso database a federated object's external.remoteName is ignored, so find queries a table named after the object and throws a bare LibsqlError (an unclassified 500), where the local face reads the mapped table. A capability on the checklist that fails on one face ⇒ p2.

    Triage seat #6015 · session_01CRZSc7dU8oDStbTbSwhuZe · 2026-09-25T07:59Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, and origin/main. Dedupe by this seat: remoteName → this card only among open cards (the filer's search read #7737 and #7738, both closed, other federation questions).

    Execution notes

    1. Region order after PR fix(driver-turso)!: a remote TursoDriver answers or refuses every inherited SqlDriver member (#20055) #20104 (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), which edits the remote arms of the same file.
    2. Measure first which answer the local face's docs and callers expect: resolve through the same external-object mapping on every remote door, or refuse registerExternalObject on the remote face with NOT_IMPLEMENTED / 501. Either way, ⛔ no bare LibsqlError reaches a caller.
  2. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    bugSomething isn't working
    and removed on Sep 25, 2026
  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

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

    • packages/drivers/driver-turso/src/turso-driver.ts, the remote arms of the read and write doors: the table name they compile against. This covers either triage route: resolve through the same external-object mapping as the local face, or refuse registerExternalObject on the remote face with the transport's NOT_IMPLEMENTED / 501. The dev measures first which one the local face's docs and callers expect (triage note 2);
    • packages/drivers/driver-turso/src/remote-transport.ts, the statements it builds, and the error envelope, so that no bare LibsqlError reaches a caller;
    • tests in packages/drivers/driver-turso;
    • .changeset/20107-*.md.

    Stop on breach and explain in the report. ⛔ Not the remote reclaimSpace route (#20106, same fire), nor the constructor (#20200). ⛔ Not driver-sql's external-object mapping: if the local face's mapping must move to be shared, stop and report.
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: no
    Thread-read: 5828997450
    Serial constraints cleared: at 2026-09-28T09:11Z, a census of the 14 open PRs (titles, plus the file lists of #20391, #20348, #20404 and #20407) and of the newest Claim: on every one of the 23 open pm:dispatched cards finds none on driver-turso. The region order after PR #20104 is satisfied: it landed as 84880f922. #20106 (the remote reclaimSpace route) is dispatched in the same fire into another region of turso-driver.ts, so the later lander merges main.

    Clause-②: no: either route narrows or aligns; neither widens. Resolving the mapping gives the remote face what the local face already does. Refusing registerExternalObject remotely narrows, and the report and changeset then declare (narrowing) in the PR body.

  4. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20107,
      "status": "done",
      "branch": "claude/issue-20107-turso-remote-remote-name",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20422",
      "session": "session_01N8TPEsoJxPsdSdNKGnNGEN",
      "premise_still_valid": true,
      "summary": "Resolve route. The docs and callers expect it. IDataDriver.registerExternalObject says a driver that carries the member records the remote table 'so queries resolve to the remote table'. ADR-0015 says remoteName 'is honoured on all dialects'. external-datasources.mdx fences no driver or transport out. drivers.mdx says nothing about federation per Turso transport, which is itself a reading. The remote face carries the member ('inherited'), so it delivers. Every remote TursoDriver data door (find, findOne, count, aggregate, distinct, create, update, upsert, delete, bulkCreate, bulkUpdate, bulkDelete, updateMany, deleteMany) goes through a new remoteTableFor(), which reads SqlDriver's protected physicalTableByObject in place. That is the registry getBuilder reads locally, and it is neither moved nor copied. The resolved table is passed to RemoteTransport as a new optional last argument on its 14 data methods; omitted, it defaults to the object. The table is quoted as one SQL name with embedded quotes doubled. The remote find/findOne/count exits now end in SqlDriver.backendStatementFault (DATABASE_ERROR/500, non-enumerable cause, targeted table declared). A federated object whose external.columnMap renames a column is refused NOT_IMPLEMENTED/501 on every remote data door before any statement is sent. That refusal is a bounded in-place fix, and it is owed: with only the table resolved, a filter on a renamed field would turn from a loud 'no such table' into a silent [] (measured with the refusal bypassed). H1 confirmed in behaviour at base 789b2ae54. H2 confirmed: the mapping is protected and readable in place. H4 holds for every read door and for writes on an existing mapped table. H4 does not hold as worded for writes on a mapped table that is really absent: those keep the backend error on both faces, the local control included (SqliteError, no status), which is backendStatementFault's documented write-path boundary.",
      "tests": "Head 37414c5e8 (the branch merged with origin/main 40b315b03). pnpm --filter @objectstack/driver-turso test: 'Test Files 74 passed (74) / Tests 1975 passed | 16 skipped (1991)'. pnpm --filter @objectstack/driver-turso typecheck: exit 0, and tsc --listFiles includes the new test file. New file turso-local-remote-external-object-parity.test.ts: 'Tests 54 passed (54)'. It uses a real @libsql/client on a file: DB, with a local driver over the same file as the control, and covers: read parity on one table for find/find-filtered/findOne/count/count-filtered/aggregate/aggregate-grouped/distinct, each also checked against the literal answer; write parity per door on fresh copies (create, update, upsert merge and insert, delete, bulkCreate, bulkUpdate, bulkDelete, updateMany, deleteMany), with the same rows after and no ext_t table created; a mapped table that is really absent, where find/findOne/count answer DATABASE_ERROR/500 on both faces, the cause is non-enumerable, the message and JSON withhold absent_t, and Symbol.for('objectstack.driver.targetedTable') is absent_t, matching the libSQL phrase; the renaming columnMap, refused NOT_IMPLEMENTED/501 on 14 doors with a client.execute spy never called and the table unchanged, while the local control translates the map and an identity map is served; a managed-object control. Reverse verification: the fix was committed first (48968c65c), every leg went through node scripts/ablation-replace.mjs (anchor 1 -> 0, blob changed, restore proven by blob == HEAD and git diff HEAD empty), and an outer trap re-verified the restore. The subject resolves from src through a relative import with no vitest alias, so dist is not in the path and there is no rebuild. Leg A (remoteTableFor returns object): 22 failed / 32 passed (8 remote read parity, 10 write parity, 3 phrase-vs-declared, 1 identity map; 'LibsqlError: SQLITE_ERROR: no such table: ext_t', aggregate [] vs [{total:7}]). Leg B (remoteReadExit rethrows bare): 9 failed / 45 passed, all of section 3 ('expected SQLITE_ERROR to be DATABASE_ERROR'). Leg C (column-map refusal deleted): 15 failed / 39 passed (14 doors plus the seeded-rows check; find resolved [], writes SQLITE_ERROR, count DATABASE_ERROR, distinct INVALID_FIELD). The directions matched the predictions written in the test header. Leg A also turned the identity-map case red, which the header did not name; that case reads the mapped table too. Lint, narrowed: eslint --no-inline-config --format json on the 3 changed .ts files gave 3 files, 0 errors, 0 warnings. ① The population is read from eslint.config.mjs (packages/**/*.{ts,tsx,mts,cts}). ② The file count is from the JSON (3). ③ Invariance: the effective parserOptions {ecmaVersion:latest, sourceType:module} have no project, and all 6 active rules are per-file AST rules, so type-aware linting is off and this diff cannot move a verdict on any untouched file. The full pnpm lint is CI's.",
      "gates": {
        "measured_head": "37414c5e8",
        "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -> 63 commands (change set: 4 paths vs merge base 40b315b03)",
        "run": "63 of 63, each exit code captured to a file before any pipe",
        "first_pass_exit_3": ["pnpm check:dual-build-cjs-loads", "pnpm check:lean-entry-closure", "pnpm check:type-check-debt"],
        "remedy": "turbo run build --filter='./packages/*' --filter='./packages/*/*' (71 tasks), then re-ran all three: exit 0. Also re-ran check:dts-closure (71 packages swept), check:sourcemap-no-sources-content (68) and check:published-files on the full build: exit 0.",
        "final": "63 exit 0",
        "ran_verdict": "dispatch-gates --ran: 63 derived famil(ies) accounted for — 63 run, 0 NOT-MEASURED (a DERIVED zero — all 63 recorded an exit code and none of them is 3)",
        "driver_conformance": "before (789b2ae54): 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt'; after (37414c5e8): 'OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt'",
        "not_measured": "CI-only lanes named by the derivation outside its 63 commands (path-scheduled Test Core / Temporal Conformance / Dogfood / Build Core jobs, the four type-check lanes, workflow-valued families): declared to CI",
        "ci": "in_progress (not awaited)"
      },
      "line_budget": "792 changed lines (+738 / -54) over 4 files vs the 5000 human-merge threshold: under. No governed surface, and no skills/** or ledger line budget in play.",
      "files_changed": [
        ".changeset/20107-turso-remote-external-remote-name.md (+22 / -0)",
        "packages/drivers/driver-turso/src/remote-transport.ts (+96 / -34)",
        "packages/drivers/driver-turso/src/turso-driver.ts (+201 / -20)",
        "packages/drivers/driver-turso/src/turso-local-remote-external-object-parity.test.ts (+419 / -0)"
      ],
      "deviations": [
        "Bounded in-place fix, declared in the PR body: the NOT_IMPLEMENTED/501 refusal of a renaming external.columnMap on the remote data doors. All four conditions hold (same external-binding defect class, the file's own pinned 501 shape, no other claim on these lines, same package tests). It is owed because the resolve alone would have turned a loud failure into a silent []. It is inside the claimed file surface (the remote arms of turso-driver.ts). The remote reclaimSpace route, the constructor and driver-sql's mapping are untouched.",
        "origin/main moved to 50e273fd7 after the merge commit 37414c5e8 (one commit, packages/services/service-analytics only, disjoint from this change set). It was not re-merged. The gates and tests are quoted at 37414c5e8. The remote reclaimSpace card (#20106) had not landed at either reading.",
        "Commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. The PR body ends in AGENTS.md's session-URL footer, not the harness reminder's PR ending. AGENTS.md and os-dev.md take precedence, and the pre-push hook refuses a model identifier.",
        "PR labels documentation, size/l, tests and tooling were already present at label-write step ① and were not written by this run. This run wrote only the assignee (os-warren)."
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "3 — all through the fleet relay (scripts/pm/fleet-write/dispatch.mjs, route dispatch, session_01N8TPEsoJxPsdSdNKGnNGEN), each one POST /repos/objectstack-ai/objectstack/dispatches executed by the fleet-write workflow: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, draft #20422 (run 36408832667); (2) label-write --assign os-warren, POST /repos/objectstack-ai/objectstack/issues/20422/assignees (run 36408936784); (3) post-stamped, POST /repos/objectstack-ai/objectstack/issues/20107/comments, this report. No issue_patch was spent: the PR body read back byte-intact. Plus git push of the branch, which is not a REST write.",
      "open_questions": [
        {
          "question": "RemoteTransport is exported from @objectstack/driver-turso, and its 14 data methods gained an optional last 'table' parameter. Nothing was removed or narrowed. Does that additive parameter change the claim's 'Clause-②: no', which the PR body copies verbatim?",
          "options": [
            "A keep 'Clause-②: no' + patch: the parameter is optional, only TursoDriver's own delegate uses it, and RemoteTransport's doc says it is not exposed directly to users",
            "B re-declare as a widening (minor): an exported class's methods accept a new argument"
          ],
          "recommendation": "A. The accepted set of every existing call is unchanged, and the class is documented as an internal delegate. The seat owns the line, so it is flagged rather than changed."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: named producer — REST GET /api/v1/data/:object (ObjectQL find -> TursoDriver.find, remote face) on a declared field whose remote column is absent, and service-analytics' ObjectQL aggregate path (AnalyticsService -> engine.aggregate -> TursoDriver.aggregate, remote face) · evidence: at 37414c5e8, over one libSQL file with the local driver as control: aggregate on a mapped table that is really absent gives local DATABASE_ERROR/500, remote []; aggregate grouped by a declared field whose column is absent gives local INVALID_FIELD/400, remote []; find whose WHERE names a declared field whose column is absent gives local INVALID_FILTER/400, remote []. Sources: the RemoteTransport.aggregate catch ('no such table' / 'no such column' -> []) and the RemoteTransport.find $select backstop (returns [] when no projection is present). It applies to managed objects too, and predates this PR · dedupe words: turso remote aggregate no such table empty · turso remote find no such column empty result · RemoteTransport invented empty read · turso remote read exit swallows missing column",
        "carrier: 承接者:无 · noted, not filed — translating external.columnMap on the Turso remote face (it is refused NOT_IMPLEMENTED/501 by this PR; implementing it would put a second copy of the local column rule into the transport compiler, and no demand is measured).",
        "carrier: 承接者:无 · noted, not filed — a remoteName containing a dot: knex splits it into a schema qualifier on the local face, while the remote face quotes it as one name. Unmeasured, and nobody is known to author that shape."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

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

    • packages/drivers/driver-turso/src/turso-driver.ts, the remote arms of the read and write doors: the table name they compile against. This covers either triage route: resolve through the same external-object mapping as the local face, or refuse registerExternalObject on the remote face with the transport's NOT_IMPLEMENTED / 501. The dev measures first which one the local face's docs and callers expect (triage note 2);
    • packages/drivers/driver-turso/src/remote-transport.ts, the statements it builds, and the error envelope, so that no bare LibsqlError reaches a caller;
    • tests in packages/drivers/driver-turso;
    • .changeset/20107-*.md.

    Stop on breach and explain in the report. ⛔ Not the remote reclaimSpace route (#20106, same fire), nor the constructor (#20200). ⛔ Not driver-sql's external-object mapping: if the local face's mapping must move to be shared, stop and report.
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
    Clause-②: yes (widening)
    Thread-read: 5868026272
    Serial constraints cleared: at 2026-09-28T09:11Z, a census of the 14 open PRs (titles, plus the file lists of #20391, #20348, #20404 and #20407) and of the newest Claim: on every one of the 23 open pm:dispatched cards finds none on driver-turso. The region order after PR #20104 is satisfied: it landed as 84880f922. #20106 (the remote reclaimSpace route) is dispatched in the same fire into another region of turso-driver.ts, so the later lander merges main.

    Amended (this re-posted claim supersedes 5866949419's Clause-② line; everything else is unchanged). The at-tier contract review of PR #20422 (record 5868256854, FAIL on ② only) found that RemoteTransport is exported from @objectstack/driver-turso's root entry, and that 14 of its methods gain an honoured optional table parameter. That is a signature widening of a published export, so the line reads yes (widening) and the changeset ships minor. The seat rules on the review's flag ③.2: a binding with no remoteName (or one equal to the object name) plus a renaming columnMap was an accidental half-service on the remote face, whose filtered reads were already silently wrong. Refusing it narrows no published accept set, so there is no narrowing arm; the changeset's refusal bullet names that shape.

  6. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20107,
      "round": "patch round 1 (contract review record 5868256854: FAIL on ② only)",
      "status": "done",
      "branch": "claude/issue-20107-turso-remote-remote-name",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20422",
      "session": "session_01N8TPEsoJxPsdSdNKGnNGEN",
      "premise_still_valid": true,
      "claim_check": "Newest Claim: on #20107 is the amended 5868269122. It names branch claude/issue-20107-turso-remote-remote-name and reads 'Clause-②: yes (widening)'.",
      "head": "20375d3da",
      "summary": "Only the changeset and the PR body changed, with no code or test change: packages/ at 20375d3da is byte-identical to 37414c5e8. Changeset: '@objectstack/driver-turso': patch -> minor; 'Clause-②: no' -> 'Clause-②: yes (widening)'; a new 'What changes' bullet names the widening (RemoteTransport, exported from the package root, gains an optional trailing table argument on its 14 data methods; omitted, it defaults to the object), replacing the trailing paragraph that said the same; the columnMap refusal bullet now names the binding with no remoteName, or with remoteName equal to the object name, plus a renaming map (before, its unfiltered reads and id-keyed writes answered, while its filtered reads were already silently wrong). Its before-state sentence was also tightened to 'failed with no such table on every door but aggregate, which answered []'. There is no narrowing arm and no ADR-0087 marker, per the seat's ruling. PR body: the Clause-② line now reads yes (widening); the 'Nothing that worked stops working' sentence is replaced by one that names that shape and the seat's half-service ruling; a '## Patch round 1' section cites record 5868256854 and claim 5868269122; the Files line and the RemoteTransport acceptance note now say minor and yes (widening). The body was read back byte-identical (14160 bytes).",
      "tests": "No code or test changed, so the round-0 measurements at 37414c5e8 stand, and packages/ at 20375d3da is byte-identical to them. Changeset gates at head 20375d3da, each exit captured before any pipe. (1) node scripts/check-changeset-no-major.mjs --base origin/main --event event.json, where event.json is a pull_request payload built from the new PR body and the PR's labels: exit 0, with '✓ This diff introduces no `major` bump.' and '✓ LEVEL AXIS: this PR declares clause-② `yes (widening)`, and no package whose `packages/**/src/**` it moves is graded `patch`.' (declaration line 'Clause-②: yes (widening)', direction arm 'widening'). (2) node scripts/check-adr-0087-registration.mjs --base origin/main: exit 0, '✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen).' (3) node scripts/check-empty-changeset.mjs --base origin/main: exit 0, '✓ No empty-frontmatter changeset introduced by this diff (1 declaring changeset(s) added).' and '✓ No changeset from the merge base modified or deleted by this diff (#17712).' (4) node scripts/check-closing-keyword-parity.mjs --body new-body.md: exit 2, which is this mode's 'declarations bind' answer, not a failure: 'check-closing-keyword-parity --body: 2 closing declaration(s) ... bound by 2 of 3 registered parser(s).' Both bindings are 'Fixes #20107' (duplicate-fix-guard same-repo, h7-partof-closing-keyword bare). No other number binds.",
      "gates": {
        "measured_head": "20375d3da",
        "check-changeset-no-major --event": "exit 0",
        "check-adr-0087-registration": "exit 0",
        "check-empty-changeset": "exit 0",
        "check-closing-keyword-parity --body": "exit 2 (binds only the intended Fixes #20107)",
        "ci": "in_progress (not awaited)"
      },
      "line_budget": "This round: +4 / -5 in one file. Total vs merge base 40b315b03: +737 / -54, under the 5000 human-merge threshold.",
      "files_changed": [
        ".changeset/20107-turso-remote-external-remote-name.md (+4 / -5)"
      ],
      "deviations": [
        "Beyond the three dictated changeset edits, one sentence in the refusal bullet was made exact: 'Before this change the same object failed on every door with no such table' now reads 'an object whose remoteName differs from its name failed with no such table on every door but aggregate, which answered []', which matches the measured table. The changeset only.",
        "The standalone trailing paragraph about RemoteTransport's optional argument was folded into the new 'What changes' bullet rather than kept beside it, so the widening is stated once."
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "2 — both through the fleet relay (route dispatch, session_01N8TPEsoJxPsdSdNKGnNGEN), each one POST /repos/objectstack-ai/objectstack/dispatches executed by the fleet-write workflow: (1) issue_patch on 20422 with body, PATCH /repos/objectstack-ai/objectstack/issues/20422 (run 36411329614), read back byte-identical; (2) post-stamped comment on 20107, POST /repos/objectstack-ai/objectstack/issues/20107/comments (this report). Plus git push of 20375d3da (fast-forward, no rebase, no force), which is not a REST write.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #20422 at 20375d3da3abeee0feaff6da5c7c4038149787ef

    domain:engine#1 · session_01N8TPEsoJxPsdSdNKGnNGEN (os-warren) · written 2026-09-28T10:59Z. Contract review of record: delta 5868528334 on PR #20422, at-tier, read-only, PASS on this head. It follows the FAIL 5868256854 on 37414c5e8, which failed on ② only, and patch round 1. packages/ is byte-identical between the two heads.

    Checklist, verified against GitHub rather than the reports:

    • Form: draft, base main, first line Fixes #20107. That is the only closing keyword in the body, and this card's newest claim (5868269122) names the branch and reads Clause-②: yes (widening).
    • Scope: 4 files, +737 / −54: the remote arms of turso-driver.ts, remote-transport.ts, one parity test in the same package, and one changeset.
    • Changeset: @objectstack/driver-turso minor, Clause-②: yes (widening). RemoteTransport is a root export, and 14 of its methods gain an optional table. The column-map refusal carries no narrowing arm (seat ruling in 5868269122).
    • Governed surface: none (check-governed-merges --pr 20422: not governed). Under the human-merge threshold.
    • CI: 41 check-runs on the head, all completed: every required context success, the rest success or path/event-skipped, none red. mergeable_state: clean.
    • Docs: the delta review read every hand-written page that speaks about remote Turso or federated objects; no page is made false.

    Out-of-scope findings, one line each:

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

  8. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

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

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

    Verified on main:

    • The squash is dbddf02c1dc580d2cb4e91e8dc6046bf58658433, a queue merge with one parent. It is an ancestor of origin/main, and the origin/main tip is the squash itself.
    • It carries 4 files, +737 / −54. The two driver-turso source files are byte-identical to the accepted head 20375d3da.
    • turso-local-remote-external-object-parity.test.ts and the 20107-* changeset are present at the squash and absent at its parent. remoteName appears in turso-driver.ts 5 times at the squash and once at its parent.
    • The PR body's one closing keyword is Fixes #20107, so no other card was closed.

    Delivered: the remote face of TursoDriver reads and writes a federated object's external.remoteName table, as the local face does. RemoteTransport's 14 data methods take an optional trailing table. A renaming external.columnMap is refused on the remote face with NOT_IMPLEMENTED / 501, and no bare LibsqlError reaches a caller. @objectstack/driver-turso ships minor (Clause-②: yes (widening), amended claim 5868269122). ACCEPT is 5868539222, and the contract review of record is the delta 5868528334 (PASS), after the FAIL 5868256854 on ② only.

    Carried out of this card:

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

  9. added 3 commits that reference this issue on Sep 29, 2026
    dbddf02
    e01d347
    3e8b492
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingdomain:enginepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions