Skip to content

spec(#12): make the atomic obligation unconditional and record its asymmetry - #18

Merged
ssilvius merged 2 commits into
mainfrom
fix/12-drop-atomic-qualifier
Aug 3, 2026
Merged

spec(#12): make the atomic obligation unconditional and record its asymmetry#18
ssilvius merged 2 commits into
mainfrom
fix/12-drop-atomic-qualifier

Conversation

@ssilvius

@ssilvius ssilvius commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

S10.1 item 5 read "Honor atomic: true on 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: true cannot 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: true on 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: true on batch requests."; compare SPEC.md:64, the atomic field 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 atomic flag 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 through await db.batch(prepared) at line 92 when atomic is true. examples/cloudflare-durable-object/src/index.ts:122-125 -- runBatch(..., atomic) returns this.ctx.storage.transactionSync(() => batch.map((s) => this.runOne(s))) at line 124 when atomic is 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_large sentence 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...HEAD returns SPEC.md alone. conformance/README.md is untouched, and its batch cases B-2 and B-3 already assume atomic: true is honored, so they remain correct under the unconditional obligation without edit.

Not done

Resolution B is not implemented: no not_supported error 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 registered not_supported code, an atomic echo field in the S6.2 batch envelope, and a capability-advertisement document -- are recorded only, not built. --closes 13 here 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

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
ssilvius merged commit c66f482 into main Aug 3, 2026
1 check passed
@ssilvius
ssilvius deleted the fix/12-drop-atomic-qualifier branch August 3, 2026 05:28
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant