Skip to content

atomic: true is unverifiable on success and undeclinable portably -- record the asymmetry, change nothing in v0.1 #13

Description

@ssilvius

Surfaced while reviewing smugglr PR #308, which reasons about atomic from the
consumer side and got two related things almost right. Recording the asymmetry
here; NOT proposing a v0.1 change.

The two halves

Atomicity is unobservable on success. S6.2's batch success envelope carries no
atomicity field, and S9 defines no atomicity header. A 200 is shape-identical
whether or not the server executed the batch in a transaction. A client that sent
atomic: true can never confirm the MUST at S4.2 was honored.

Declining is not portable. S10.1 item 5 qualifies the obligation with "when not
rejected," but the only rejection clause in S4.2 is statement-count overflow to
413, and the S7 table has no code meaning "atomicity unavailable." A server that
cannot transact may reject with a vendor code (vendor:atomic_not_supported),
which is conforming -- but S7 tells clients to treat unknown codes as the nearest
registered code by HTTP status family, so the signal collapses to
bad_request/sql_error semantics at the client. There is a conforming way to
decline and no portable way to be understood doing it.

Why v0.1 changes nothing

Consumer count for this friction is one (smugglr's migrate), and that consumer's
correct design does not need either capability: it designs as if no transaction
exists, precisely because presence is unobservable. Adding a registered code or a
response field to serve a consumer that does not need it grows permanent surface
for no behavior change. The spec is a future-compat anchor; every registered code
is forever.

The honest statement of the current contract is: atomic: true is a request the
server MUST honor and the client MUST NOT verify.
That is a coherent contract
for a v0.1 transport. It is only a defect if a consumer's correctness comes to
depend on confirmation.

What would reopen it

  • A second independent consumer needing to branch on whether atomicity held.
  • A server implementation that wants to advertise non-support rather than
    fail requests opaquely.

Candidate shapes for that day, recorded so the design is not re-derived:

  1. A registered not_supported code (400 or 501) with error.message naming the
    unsupported feature. Cheapest; declines loudly, still says nothing on success.
  2. An atomic echo field in the S6.2 batch envelope ({"results": [...], "atomic": true}) -- a positive success-path signal, additive, minor-version
    bump per S11.
  3. Capability advertisement (a GET/OPTIONS capabilities document). Largest
    surface, and it invites the negotiation S9 deliberately does not have.

Preference if forced today: (2), because the missing half is the success path, and
an echo is checkable by a client that cares and ignorable by one that does not.

Filed by the platform seat. Deliberately open and deliberately unscheduled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions