Repository navigation
Description
The defect
SPEC.md S10.1 item 5 reads:
- Honor
atomic: trueon batch requests when not rejected.
"when not rejected" qualifies a MUST against a rejection the spec never defines. There is no way for a conforming server to decline atomicity:
- The registered error-code table in S7 has no
not_supported(or equivalent). The set isbad_request,sql_error,not_allowed,auth_error,permission_error,payload_too_large,rate_limited,internal_error.not_allowedis scoped to statement shape rejected by server policy, which does not cover refusing theatomicfield. - S4.2's only rejection clause is statement-count overflow to
413/payload_too_large. - Nothing in S6 echoes back whether the server actually ran the batch in a transaction, so a client has no positive signal either.
So a server that cannot do transactions has exactly two options, and both are non-conforming: silently lie (accept atomic: true and not honor it), or misuse an error code. A client cannot distinguish either case from an unrelated failure, and S7's "treat unknown error.code values as the closest registered code by HTTP status family" guarantees a vendor: code cannot carry the signal interoperably.
This is issue #3's exact shape -- a normative keyword gated on a condition the spec leaves undefined -- reproduced in the conformance section rather than in a field definition.
Why it is being filed now
rafters-studio/smugglr PR #308 makes this gap load-bearing. Its migrate design decision 6 ("design as if no transaction exists") now rests on the reasoning above: the spec gives a server no conforming way to decline atomicity, so atomic honoring is unobservable to a client and correctness must not depend on it. That reasoning is correct against v0.1 on both main and #9's head -- I verified it. It is also reasoning about an absence, which means closing this gap rots a downstream repo's prose. Reviewed and flagged there; the fix requested downstream is to pin v0.1 into those sentences.
The design conclusion survives either resolution below, because absence of a rejection is still an unverifiable claim of support. Only the "lie or misuse a code" sentence depends on the gap.
The two candidate resolutions
A. Drop the qualifier. Item 5 becomes "Honor atomic: true on batch requests." Unconditional, matches what S4.2:64 already says (the MUST has no escape hatch there), and matches both reference servers. A server that cannot do transactions is simply non-conforming for batch -- which is arguably already the truth S4.2 states, with item 5 accidentally weakening it.
B. Define the decline path. Register a code (not_supported, 400) and state in S4.2 that a server unable to execute a batch atomically MUST reject a request carrying atomic: true with it, rather than executing non-atomically. This makes the rejection real, makes item 5's qualifier meaningful, and gives a client a distinguishable signal -- but it is a new registered code, so per S11 it is a v0.2 additive change, not a v0.1 clarification.
Preference: A, and it is the smaller claim. v0.1's S4.2 already puts an unqualified MUST on the server; item 5's "when not rejected" is the only text in the spec that implies a negotiation exists, and no other section supports it. Removing it makes the conformance section agree with the field definition instead of quietly contradicting it. B can be considered on its own merits for v0.2 -- a real decline signal has value -- but it should not be motivated as a fix for this, because the fix for a dangling qualifier is to delete the qualifier.
Whichever lands, the check-before-writing rule from #9 applies: verify both reference servers first. Both currently honor atomic (examples/cloudflare-worker-to-d1/src/index.ts:92 via db.batch(), examples/cloudflare-durable-object/src/index.ts:124 via ctx.storage.transactionSync), so A codifies shipped behavior and neither server becomes non-conforming.
Acceptance criteria
- S10.1 item 5 no longer gates a normative obligation on an undefined condition.
- S4.2's
atomicobligation and S10.1's conformance item state the same rule -- no reader can find a negotiation in one and not the other. - Both reference servers are checked against the resulting text before it is written, and remain conforming.
conformance/README.mddoes not grant or imply a permission the spec does not issue (the P0: non-atomic batch failure has no normative behavior (forbid partial success + REQUIRE statementIndex on non-atomic + state that preceding statements persist) #1 failure mode).- If resolution B is chosen instead, the version bump per S11 is stated explicitly in the PR.
Activity