spec(#12): make the atomic obligation unconditional and record its asymmetry - #18
Merged
Conversation
S10.1 item 5 read "Honor `atomic: true` on batch requests when not rejected." The qualifier gated a MUST on a rejection mechanism the spec never defines: S7 registers no code meaning "atomicity unavailable," and S4.2's only rejection clause is statement-count overflow to 413. Drop the qualifier so the conformance section agrees with S4.2's already-unqualified MUST. Both reference servers already honor atomic, so this codifies shipped behavior and neither becomes non-conforming: examples/cloudflare-worker-to-d1/src/index.ts:92 (db.batch) and examples/cloudflare-durable-object/src/index.ts:124 (ctx.storage.transactionSync). Also adds a clearly-marked non-normative note near S4.2 stating the v0.1 contract honestly: atomic: true cannot be declined conformingly and cannot be verified by the client, and the candidate shapes for a future version live in issue #13. Closes #12 Closes #13 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ssilvius
added a commit
that referenced
this pull request
Aug 3, 2026
…tIndex; scope 170 to statement failures Review findings on PR #9: the minimal reference server dispatched batches with Promise.all (violating the new sequential-execution MUST) and returned batch errors without statementIndex (violating the new REQUIRED). Now a sequential loop stamps the index on non-atomic failures and the handler threads it into the envelope -- the same shape as both Cloudflare servers. Also the reviewer's one-word scoping fix: SPEC.md's REQUIRED applies to non-atomic batch STATEMENT failures, so pre-execution rejections on a request that happens to carry a batch are not swept in. Merge of main resolved the S10.1 conflict with #18 (item 5 keeps the unconditional MUST; the 6.2.1 items renumber after it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
S10.1 item 5 read "Honor
atomic: trueon batch requests when not rejected," qualifying a MUST against a rejection mechanism the spec never defines -- S7 registers no code meaning "atomicity unavailable," and S4.2's only rejection clause is statement-count overflow to 413. This applies Resolution A as approved by the spec owner: the qualifier is deleted, item 5 becomes unconditional, and the conformance section now agrees with S4.2's already-unqualified MUST instead of quietly weakening it. Folded in alongside it is issue #13's ask: a clearly-marked non-normative note near S4.2 that states the v0.1 contract honestly --atomic: truecannot be declined conformingly, cannot be verified by the client on success, and the three candidate shapes for closing that asymmetry in a future version are recorded in issue #13 rather than implemented here. Issue #3 was closed as superseded by this resolution: it was the same defect shape (a normative keyword gated on an undefined condition), and deleting the qualifier is the fix for both. This PR closes #12 and #13; nothing else normative changed.Acceptance criteria mapping
1. S10.1 item 5 drops "when not rejected" and becomes an unconditional MUST
The bullet now reads "Honor
atomic: trueon batch requests." with no trailing condition. This is the only text in the spec that implied a negotiation over atomicity existed; with it gone, the conformance list and the field definition state the same obligation. A server that cannot execute batches transactionally is now plainly non-conforming for batch, which is what S4.2 already said.Evidence: SPEC.md:229 (post-diff) -- item 5 under "A v0.1 conforming server MUST" reads "Honor
atomic: trueon batch requests."; compare SPEC.md:64, theatomicfield definition, whose MUST was already unqualified.2. Both reference servers verified to honor atomic, so neither becomes non-conforming
I read both reference implementations at their current state on origin/main and confirmed each branches on the
atomicflag and routes the true case through a real transaction primitive. The change therefore codifies shipped behavior rather than invalidating either example.Evidence: examples/cloudflare-worker-to-d1/src/index.ts:87-93 --
runBatch(..., atomic)prepares all statements and dispatches them throughawait db.batch(prepared)at line 92 whenatomicis true. examples/cloudflare-durable-object/src/index.ts:122-125 --runBatch(..., atomic)returnsthis.ctx.storage.transactionSync(() => batch.map((s) => this.runOne(s)))at line 124 whenatomicis true. Both fall through to a per-statement loop otherwise.3. A short, clearly-marked NON-NORMATIVE note records the asymmetry (issue #13)
A blockquote immediately after the S4.2 batch-limit sentence opens with "Non-normative note (not part of the v0.1 contract)." and states both halves of the asymmetry: there is no conforming way to decline (the obligation is unqualified and S7 registers no suitable code; a
vendor:decline collapses to the nearest registered code by status family per S7), and no way to confirm on success (S6.2 carries no atomicity field, S9 defines no header, so a 200 is shape-identical either way). It closes by pointing at issue #13 by full URL for the three candidate future shapes. The note deliberately contains no RFC 2119 keywords of its own, so the non-normative marker is not undercut by text that reads as fresh contract, and it leads with the post-Resolution-A truth rather than issue #13's pre-resolution framing that implied declining was an available option.Evidence: SPEC.md:68-89 (post-diff), the blockquote between the
payload_too_largesentence at SPEC.md:66 and the "## 5. Parameter types" heading.4. Nothing else normative changed
The diff touches exactly one file. No error code was registered, no response field added, no conformance test case altered -- all of which would be v0.2 additive changes under S11 and none of which this clarification needs.
Evidence:
git diff --name-only origin/main...HEADreturnsSPEC.mdalone. conformance/README.md is untouched, and its batch cases B-2 and B-3 already assumeatomic: trueis honored, so they remain correct under the unconditional obligation without edit.Not done
Resolution B is not implemented: no
not_supportederror code was registered and no decline path was defined. Per S11 a new registered code is a v0.2 additive change, not a v0.1 clarification, and per the issue's own reasoning the fix for a dangling qualifier is to delete the qualifier, not to invent the negotiation it gestured at. Relatedly, all three candidate shapes from issue #13 -- a registerednot_supportedcode, anatomicecho field in the S6.2 batch envelope, and a capability-advertisement document -- are recorded only, not built.--closes 13here means "the asymmetry is now written down as #13 asked," not "the capability was added"; #13 explicitly argued that v0.1 should change nothing, and this PR honors that. I also did not touch conformance/README.md, S1's "the normative content is the prose" sentence (amending it to carve out non-normative blocks would itself be a normative change), or implementations.md.Closes #13