Skip to content

fix(driver-turso): refuse auto_number writes on the remote transport (#6944) - #7089

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-6944-turso-remote-autonumber-refusal
Aug 9, 2026
Merged

fix(driver-turso): refuse auto_number writes on the remote transport (#6944)#7089
os-zhuang merged 2 commits into
mainfrom
claude/issue-6944-turso-remote-autonumber-refusal

Conversation

@claude

@claude claude Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Closes #6944.

Ruling carried out

Triage ruled this card at 06:46Z on 2026-08-09 (comment 5230216863): disposition B — explicit refusal, per the #3724 precedent for "a driver face that boots but silently fails to deliver a declared capability". Implementing autonumber on the remote transport (A) stays behind the appetite door. The issue body still poses A-or-B; it is stale and the comment governs.

The defect

TursoDriver picks its transport from url. Local and embedded-replica inherit SqlDriver's write path and issue record numbers from _objectstack_sequences. Remote overrides the write path to RemoteTransport, which builds its own INSERT and never enters fillAutoNumberFields — so auto_number was only a column mapped to TEXT there. Measured on main @ 2f3e79351:

REMOTE create      -> RESOLVED case_number=null
REMOTE bulkCreate  -> RESOLVED [null, null]
REMOTE upsert      -> RESOLVED case_number=null
LOCAL  create      -> RESOLVED case_number="CASE-00001"

Nothing upstream catches it: supports.autonumber is true on this face (inherited via ...super.supports), so the engine defers generation to the driver and never runs its own fallback.

The change

TursoDriver.create / bulkCreate / upsert refuse, in remote mode, a write that would need a number this face cannot issue — NOT_IMPLEMENTED / 501, the same class this package already gives an uncompilable aggregate function (#5907) or an unemittable date bucket (#6212), per ADR-0112. Refused before the statement is built, so it costs no round trip.

Raised on the driver, not the transport — measured, not assumed. RemoteTransport.create(object, data) takes no schema and caches none (arity pinned in the suite), so it cannot tell an auto_number column from any other TEXT one. TursoDriver can: registerRemoteFieldMetadataregisterExternalObject classifies fields at remote schema-sync time and populates autoNumberFields — verified live in remote mode.

Deliberately not refused: a caller-supplied number (seed replay / preserveAudit import — the generate predicate is fillAutoNumberFields' own, reused verbatim); and a merging upsert, which keeps the number already in the column. Only the provably-inserting upsert shape is refused. The residue — an id-bearing upsert that turns out to insert — is pinned as a [known residue, not fixed] assertion rather than left in a comment.

The two absence-assertions, rewritten rather than deleted

#6932 (turso-autonumber-resync.test.ts) and #6943 (turso-autonumber-batch-resync.test.ts) each pinned "RemoteTransport has no autonumber surface at all". Deleting either would remove the only guard against a future silent half-implementation inside the transport; leaving them unchanged would keep a green assertion beside a claim that no longer holds. Both keep the surface probe verbatim and gain the refusal pin (code and status, never a bare toThrow — ADR-0112 / #6144).

Scope

packages/drivers/driver-turso only. All three faces pinned (#6203): local and replica still generate. driver-memory / driver-mongodb are inside the #5499 freeze, declare no supports.autonumber, and are unrelated.

Reverse verification

Predicted before running: with the refusal body emptied, every REMOTE refusal case fails through the harness's "it resolved" branch, not on a code/status comparison; everything else stays green. Measured: 8 failed | 923 passed — the 6 cases in the new suite plus the 2 rewritten pins, all through "it resolved"/"expected a refusal", and each failure message reprints the defect with "case_number":null inside it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UtmF8wiWUuHFcezsXhYygb


Generated by Claude Code

os-dev and others added 2 commits August 9, 2026 14:24
…6944)

WIP checkpoint — refusal + dedicated suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtmF8wiWUuHFcezsXhYygb
…6944)

Remote overrides the write path to RemoteTransport, which builds its own
INSERT and never enters fillAutoNumberFields — so auto_number slots were
silently written NULL on that face while local/replica generated numbers.
Triage ruled disposition B (explicit refusal, per #3724).

- TursoDriver.create / bulkCreate / upsert refuse with NOT_IMPLEMENTED/501
  when a slot the driver would have had to fill is empty. Raised on the
  driver, not the transport: RemoteTransport.create(object, data) sees no
  schema, while the driver's autoNumberFields IS populated in remote mode.
- Caller-supplied numbers (seed replay / preserveAudit import) and merging
  upserts are deliberately untouched.
- The two absence-assertions from #6932/#6943 are rewritten to pin the
  refusal rather than deleted, keeping the transport-surface guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtmF8wiWUuHFcezsXhYygb
@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 9, 2026 2:30pm

Request Review

@github-actions github-actions Bot added the size/l label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-turso.

6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/data-modeling/drivers.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/cli.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/environment-variables.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/self-hosting.mdx (via @objectstack/driver-turso)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-turso)
  • content/docs/plugins/packages.mdx (via @objectstack/driver-turso)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TursoDriver remote 面根本不生成自增号:RemoteTransport.create 自建 INSERT,auto_number 只是个 TEXT 列

1 participant