<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.32 (Ruby 3.3.0) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-ietf-jmap-conditional-02" category="std" consensus="true" submissionType="IETF" updates="8620" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="JMAP Conditional">JMAP Conditional Set</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail</organization>
      <address>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>

    <date year="2026" month="October" day="26"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 31?>

<t>The JMAP base protocol (<xref target="JMAP-CORE"/>) provides the Foo/set method for
creating, updating, and destroying objects.  It offers a single concurrency
control, the "ifInState" argument, which guards an entire object type: if any
object of that type has changed, the whole method is rejected.</t>

<t>This extension adds a finer, per-object conditional mechanism.  A client may
require that an individual update or destroy proceed only if the target object
still matches a set of expected property values, expressed using the JMAP
PatchObject already defined for updates.  This provides optimistic concurrency
control scoped to a single object — the equivalent of an HTTP "If-Match"
precondition — for any JMAP data type.</t>

<t>This extension also defines an optional "atomic" argument that applies an
entire Foo/set as a single unit: either every change it requests takes effect,
or none does.  Combined with the per-object precondition, this lets a client
express a multi-object change that is safe only when applied together — such as
an atomic rename that exchanges two names.</t>



    </abstract>



  </front>

  <middle>


<?line 51?>

<section anchor="introduction"><name>Introduction</name>

<t>The Foo/set method defined in <xref target="JMAP-CORE"/> is the mechanism by which clients
create, update, and destroy objects.  It provides one form of concurrency
control: the optional "ifInState" argument, which aborts the entire method if
the account's state string for that data type does not match the value the
client supplies.</t>

<t>This guard is coarse.  The state string changes whenever <em>any</em> object of that
type changes, by any client.  In a busy account — or one that receives
server-initiated changes, such as the arrival of new mail — the state can
change between a client's read and its write for reasons entirely unrelated to
the object the client is modifying.  Using "ifInState" to protect a single
update therefore leads to frequent spurious rejections and retries.</t>

<t>Clients commonly need a narrower guarantee: "apply this change only if the
specific object I read still holds the values I depend on".  This is the same
need met by the HTTP "If-Match" precondition (<xref target="HTTP-SEMANTICS"/>) and the
entity-tag model of WebDAV (<xref target="WEBDAV"/>): a conditional write scoped to a single
resource.</t>

<t>This document defines a generic, per-object conditional mechanism for Foo/set.
It introduces no new properties and no new version tokens.  Instead it reuses
the PatchObject already defined by <xref target="JMAP-CORE"/> for updates: a client states
its precondition as a PatchObject describing the values it expects the object
to currently hold, and the server performs the change only if applying that
patch would change nothing.</t>

<t>Because the mechanism is defined entirely in terms of an object's properties
and the existing PatchObject semantics, it applies uniformly to every data
type that implements Foo/set, with no per-type additions.</t>

<t>A second, related need is atomicity.  <xref target="JMAP-CORE"/> processes the creations,
updates, and destroys within a Foo/set independently: some may succeed while
others fail, and the method gives no guarantee that a set of related changes
takes effect together.  The only all-or-nothing control Core offers is
"ifInState", which — like the concurrency problem above — is scoped to the
entire object type rather than to the changes the client actually requested.
This document therefore also defines an optional "atomic" argument that commits
a Foo/set as a single unit, evaluated against the state that results from
applying all of its changes together (see <xref target="atomic"/>).</t>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

<t>The terms "Id", "PatchObject", "SetError", and "Foo/set" are defined in
<xref target="JMAP-CORE"/>.  A "pointer" is a JSON Pointer as used within a PatchObject
(see <xref target="JMAP-CORE"/>, Section 5.3).</t>

</section>
</section>
<section anchor="addition-to-the-capabilities-object"><name>Addition to the Capabilities Object</name>

<section anchor="urnietfparamsjmapconditional"><name>urn:ietf:params:jmap:conditional</name>

<t>The presence of the "urn:ietf:params:jmap:conditional" property in the
"capabilities" object of the JMAP Session resource indicates support for the
conditional Foo/set behaviour defined in this document.  The value of this
property <bcp14>MUST</bcp14> be an empty object.</t>

<t>A client indicates that it wishes to use this extension by including the
capability URI in the "using" array of a request.  When a server that
advertises this capability receives a request whose "using" array includes
this URI, it <bcp14>MUST</bcp14> honour the "ifUnchangedBy" argument (<xref target="conditional-set"/>) on
every Foo/set method it implements.  It <bcp14>MUST</bcp14> also honour the "atomic" argument
(<xref target="atomic"/>): either applying the method atomically, or, if it cannot, rejecting
it with a "cannotApplyAtomically" error (<xref target="atomic"/>).  A server <bcp14>MUST NOT</bcp14> apply
the changes of a method requested with "atomic" only in part.</t>

<t>The capability is generic: it does not depend on any particular data type, and
its presence applies to all types for which the server implements Foo/set.</t>

<section anchor="capability-example"><name>Capability Example</name>

<figure><artwork><![CDATA[
"urn:ietf:params:jmap:conditional": {}
]]></artwork></figure>

</section>
</section>
</section>
<section anchor="conditional-set"><name>Conditional Foo/set</name>

<t>This document adds the following arguments to the standard Foo/set method
(<xref target="JMAP-CORE"/>, Section 5.3):</t>

<t><list style="symbols">
  <t>ifUnchangedBy: "Id[PatchObject|null]" (default: an empty object)  <vspace blankLines='1'/>
A map of object id to a PatchObject expressing a precondition on that
object.  For each entry, the precondition is satisfied if and only if
applying the given PatchObject to the current server-side object would
leave the object unchanged.  <vspace blankLines='1'/>
Equivalently: for every pointer in the PatchObject, the object's current
value at that pointer <bcp14>MUST</bcp14> equal the value given in the PatchObject.  A
JSON "null" value matches a property that is not present (it asserts that
removing the property would be a no-op).  Comparison uses the same
representation the server would return for that property from Foo/get.  <vspace blankLines='1'/>
As in an update (<xref target="JMAP-CORE"/>, Section 5.3), a PatchObject with a
pointer whose parent does not exist in the current object cannot be
applied.  Such a precondition is never satisfied, whatever the value,
including "null": for example "participants/p1/name" cannot be satisfied
by an object with no "participants" property.  The server rejects the
method as for an invalid pointer (rule 4 of <xref target="evaluation-rules"/>).  <vspace blankLines='1'/>
A "null" value instead of a PatchObject asserts that the object does not
exist: the precondition is satisfied if and only if no object with that
id exists or is visible to the client, for example because it has been
destroyed.  <vspace blankLines='1'/>
An empty PatchObject ("{}") is valid and asserts only that the object
exists: the precondition is satisfied if and only if an object with that
id exists and is visible to the client.</t>
  <t>atomic: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the Foo/set is applied as a single unit: the server <bcp14>MUST</bcp14> either
commit every creation, update, and destroy the method requests, or make no
change at all.  See <xref target="atomic"/>.</t>
</list></t>

<section anchor="evaluation-rules"><name>Evaluation Rules</name>

<t><list style="numbers" type="1">
  <t>Preconditions are evaluated against the state of each object as it exists
at the start of the method, before any create, update, or destroy in the
same method is applied.</t>
  <t>Each key in "ifUnchangedBy" is the id of an object of the same type as the
method (the "Foo" of "Foo/set").  The object need not be one the method
changes.  A client <bcp14>MAY</bcp14> set a precondition on an object the method does not
change, for example its parent.  A PatchObject precondition is not
satisfied if its object does not exist, or is not visible to the client;
a "null" precondition is not satisfied if it does.  The server then
handles it as in <xref target="effect"/>.  A creation id (an id prefixed with "#") <bcp14>MAY</bcp14>
be a key.  It references an object created by an earlier method call in the
same request (<xref target="JMAP-CORE"/>, Section 5.3), and stands for the id that
creation produced.  If no object of this type has that id, because the
creation failed, created an object of a different type, or its object has
since been destroyed, the precondition is evaluated as for an object that
does not exist.  This lets a client require that an object it created
earlier in the request has not changed since then, or that it has since
been destroyed.</t>
  <t>Unlike the PatchObject supplied in the "update" argument, which may only
reference properties the client is permitted to set, the PatchObject in
"ifUnchangedBy" <bcp14>MAY</bcp14> reference any property of the object, including
server-set and otherwise read-only properties (for example a content
identifier, a size, or a server-maintained change timestamp).  This allows
a client to condition a change on properties it cannot itself modify.</t>
  <t>If a pointer in an "ifUnchangedBy" PatchObject is not a valid pointer for
the object's type, or the PatchObject is otherwise malformed, the server
<bcp14>MUST</bcp14> reject the whole method, with either an "invalidArguments" error or
a "stateMismatch" error as for an unsatisfied precondition.  A server need
not distinguish an invalid pointer from one that does not apply cleanly to
the current object.</t>
  <t>The "ifUnchangedBy" and "ifInState" arguments are both method-level guards
and compose.  If both are supplied, the server checks "ifInState" first and
then the "ifUnchangedBy" preconditions; if either does not hold, the method
is rejected with a "stateMismatch" error and no change is made.</t>
</list></t>

</section>
<section anchor="effect"><name>Effect</name>

<t>If every precondition in "ifUnchangedBy" is satisfied, the method proceeds
exactly as it would without this extension.</t>

<t>If any precondition is not satisfied, the server <bcp14>MUST</bcp14> make no change — no
creation, update, or destroy in the method takes effect — and <bcp14>MUST</bcp14> reject the
whole method with a method-level "stateMismatch" error (<xref target="statemismatch"/>).
The state string for the type <bcp14>MUST</bcp14> be unchanged.</t>

<t>This is all-or-nothing at the method level, by design: a single Foo/set is
the unit of conditional application.  A client that wants changes to succeed or
fail independently of one another places them in separate method calls within
the same request, each with its own "ifUnchangedBy".</t>

</section>
<section anchor="statemismatch"><name>The "stateMismatch" error</name>

<t>A failed "ifUnchangedBy" precondition is reported using the method-level
"stateMismatch" error already defined by <xref target="JMAP-CORE"/> for a failed "ifInState"
guard.  It is returned as an "error" response in place of the Foo/set response,
so no create, update, or destroy result is returned and the client knows the
method made no change.</t>

<t>The error discloses no object data: a client that needs the current values
fetches them with Foo/get or Foo/changes before deciding how to proceed.  A
server <bcp14>MAY</bcp14> include a "description" for debugging, and <bcp14>MAY</bcp14> include:</t>

<t><list style="symbols">
  <t>failed: "Id[]"  <vspace blankLines='1'/>
The ids of the objects whose preconditions were not satisfied.  This lets a
client re-fetch only what it needs, without disclosing any values.  A server
that does not wish to distinguish which precondition failed <bcp14>MAY</bcp14> omit this
property.</t>
</list></t>

</section>
</section>
<section anchor="atomic"><name>Atomic Foo/set</name>

<t>When the "atomic" argument is true, the server <bcp14>MUST</bcp14> apply the Foo/set as a
single unit: either every creation, update, and destroy the method requests
takes effect, or none of them does.</t>

<section anchor="evaluation"><name>Evaluation</name>

<t>The server evaluates the method as though all of its changes were applied
together.  Any constraint that <xref target="JMAP-CORE"/> or a data-type extension evaluates
on the resulting object set — for example a uniqueness constraint on a name
within a parent — is checked once, against the state produced by applying all
the changes, not against any intermediate state.</t>

<t>This guarantees that a set of changes that is valid only as a whole can
succeed.  For example, exchanging two names — renaming object A to the name
currently held by B and B to the name currently held by A — collides if applied
one change at a time, but the combined result is conflict-free.  <xref target="JMAP-CORE"/>,
Section 5.3 already permits a server to accept such a change when the final
state is valid, but also permits it to process the changes sequentially and
reject one of them, possibly after committing the other.  With "atomic", the
client can rely on the server evaluating the final state, and on the changes
succeeding or failing together (see <xref target="exchange"/>).</t>

</section>
<section anchor="failure"><name>Failure</name>

<t>If any part of an atomic method fails — an invalid patch, a name collision, a
permission error, a violated constraint, or any other SetError that would place
an id in "notCreated", "notUpdated", or "notDestroyed" — the server <bcp14>MUST</bcp14> make
no change and <bcp14>MUST</bcp14> reject the whole method with a method-level "atomicFailure"
error.  The state string for the type <bcp14>MUST</bcp14> be unchanged.</t>

<t>A failed "ifUnchangedBy" precondition is reported as a "stateMismatch" error
(<xref target="statemismatch"/>) whether or not "atomic" is set; preconditions are already
all-or-nothing at the method level.  The "atomicFailure" error is specific to
the method's own creations, updates, and destroys not being committable
together.</t>

<t>The "atomicFailure" error object <bcp14>MAY</bcp14> carry "notCreated", "notUpdated", and
"notDestroyed" maps — of the same form as a Foo/set response — identifying the
ids whose processing failed and the SetError for each.  Ids that would have
succeeded are omitted; they were not committed, because the method as a whole
was rejected.  A server <bcp14>MAY</bcp14> report only the first failure it encounters.</t>

</section>
<section anchor="cannotapply"><name>Servers That Cannot Apply Atomically</name>

<t>A server that advertises this capability but cannot apply a given method
atomically — either at all, or because this particular method is beyond what it
can commit as a unit — <bcp14>MUST</bcp14> reject the method with a method-level
"cannotApplyAtomically" error and make no change.  It <bcp14>MUST NOT</bcp14> fall back to
applying the changes non-atomically.</t>

<t>A client that receives "cannotApplyAtomically" <bcp14>MAY</bcp14> retry without "atomic" if it
can tolerate partial application, or surface the failure otherwise.  A client
that does not recognise the error treats it as "serverFail" (<xref target="JMAP-CORE"/>):
since a rejected atomic method makes no change, this fallback is safe, if less
informative.</t>

</section>
</section>
<section anchor="examples"><name>Examples</name>

<section anchor="force-with-lease-on-file-content"><name>Force-with-lease on file content</name>

<t>A client last synchronised a file node "f42" with content blob "G_old".  It has
since produced new content "G_new", and wishes to replace the content only if no
other client has changed it in the meantime.  It conditions on the server-set
"blobId" (<xref target="JMAP-FILENODE"/>):</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "f42": { "blobId": "G_old" } },
  "update":       { "f42": { "blobId": "G_new",
                             "modified": "2026-05-01T09:30:00Z" } }
}, "0" ]]
]]></artwork></figure>

<t>If "f42" still references "G_old", the update succeeds.  If another client has
already replaced the content (so "blobId" is now, say, "G_other"), the
precondition fails and the server makes no change, returning a method-level
"stateMismatch" error:</t>

<figure><artwork><![CDATA[
[[ "error", {
  "type": "stateMismatch",
  "failed": [ "f42" ]
}, "0" ]]
]]></artwork></figure>

<t>The client fetches "f42", resolves the conflict (for instance by preserving its
own version as a separate file), and retries.</t>

</section>
<section anchor="conditional-destroy"><name>Conditional destroy</name>

<t>Destroy a message only if it has not been read on another device.  In
<xref target="JMAP-MAIL"/>, an unread message has no "$seen" keyword, so the client asserts
that "keywords/$seen" is absent:</t>

<figure><artwork><![CDATA[
[[ "Email/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "M7": { "keywords/$seen": null } },
  "destroy":      [ "M7" ]
}, "0" ]]
]]></artwork></figure>

<t>If the message has since been marked "$seen", the precondition fails, the whole
method is rejected with a "stateMismatch" error, and "M7" is not deleted.</t>

</section>
<section anchor="a-condition-that-ignores-unrelated-changes"><name>A condition that ignores unrelated changes</name>

<t>Because the precondition references only the pointers the client supplies,
concurrent changes to other properties of the same object do not cause it to
fail.  Here a client removes a grantee's access, but only if that grantee
currently holds exactly the rights the client saw:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "d3": { "shareWith/bob/mayRead": true } },
  "update":       { "d3": { "shareWith/bob": null } }
}, "0" ]]
]]></artwork></figure>

<t>The change applies only if Bob currently has "mayRead" of "true".  A concurrent
change to an unrelated property of "d3" (its name, or another grantee's rights)
does not trigger a "stateMismatch".</t>

</section>
<section anchor="conditioning-on-an-object-the-method-does-not-change"><name>Conditioning on an object the method does not change</name>

<t>A precondition may name an object the method is not creating, updating, or
destroying.  Here a client updates the content of file "f42", but only if it is
still in the parent directory the client last saw ("d3"), so the write does not
land in an unexpected place after a concurrent move:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "f42": { "parentId": "d3" },
                     "d3":  { "name": "Reports" } },
  "update":       { "f42": { "blobId": "G_new",
                             "modified": "2026-05-01T09:30:00Z" } }
}, "0" ]]
]]></artwork></figure>

<t>If either "f42" has been reparented or "d3" has been renamed, the method is
rejected with a "stateMismatch" error and the content is not written, even
though "d3" itself is not being changed.</t>

</section>
<section anchor="conditioning-on-an-object-having-been-destroyed"><name>Conditioning on an object having been destroyed</name>

<t>A "null" precondition requires that an object no longer exists.  Here a client
renames "t" to "report.txt", but only if the file "r" that used to hold that
name has already been destroyed, by this client or another:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "r": null },
  "update":       { "t": { "name": "report.txt" } }
}, "0" ]]
]]></artwork></figure>

<t>If "r" still exists, the method is rejected with a "stateMismatch" error and
"t" keeps its name.</t>

</section>
<section anchor="conditioning-on-an-object-still-existing"><name>Conditioning on an object still existing</name>

<t>An empty PatchObject requires only that an object still exists, whatever its
current values.  Here a client has generated a thumbnail of the file "f42" and
uploads it as a new file, but only if "f42" has not been destroyed in the
meantime, so that no orphaned thumbnail is left behind:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "ifUnchangedBy": { "f42": {} },
  "create": { "th1": { "parentId": "thumbs",
                       "name": "f42.png",
                       "blobId": "G_thumb" } }
}, "0" ]]
]]></artwork></figure>

<t>If "f42" no longer exists, the method is rejected with a "stateMismatch" error
and no thumbnail is created.  Changes to "f42" that leave it in place, such as
a rename, do not cause the precondition to fail.</t>

</section>
<section anchor="whole-object-compare-and-swap"><name>Whole-object compare-and-swap</name>

<t>A data type that maintains a server-set change token can be used to require
that nothing at all has changed.  For example, a type with a server-maintained
"changed" timestamp that is updated on every modification:</t>

<figure><artwork><![CDATA[
"ifUnchangedBy": { "f42": { "changed": "2026-04-30T12:00:00Z" } }
]]></artwork></figure>

<t>Because the server updates "changed" on any modification to the object, this
asserts that the entire object is unchanged since the client last read it,
recovering the coarse "If-Match" behaviour as a special case of the general
mechanism.</t>

</section>
<section anchor="exchange"><name>Atomic exchange of two names</name>

<t>Two file nodes, "a" (named "current.txt") and "b" (named "previous.txt"), are
to swap names.  Applied one at a time, either rename collides with the name the
other still holds; applied together, the result is conflict-free.  A server
conforming only to <xref target="JMAP-CORE"/> may accept this swap, but is not required to.
With "atomic" set, the rule that sibling names are unique is evaluated only
against the resulting state:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "atomic": true,
  "update": {
    "a": { "name": "previous.txt" },
    "b": { "name": "current.txt" }
  }
}, "0" ]]
]]></artwork></figure>

<t>Both renames take effect, or — if either is rejected for any reason — neither
does, and the server returns an "atomicFailure" error identifying the offending
id.</t>

</section>
<section anchor="replace"><name>Atomic replace of one file by another</name>

<t>A common pattern in POSIX applications is to write new content to a temporary
file and then rename it over the original, so that other readers see either the
complete old file or the complete new one, never a partial write.  Here "t"
(named "report.txt.tmp") holds the new content, and "r" (named "report.txt",
with content "G_old") is the file to be replaced:</t>

<figure><artwork><![CDATA[
[[ "FileNode/set", {
  "accountId": "u1",
  "atomic": true,
  "ifUnchangedBy": { "r": { "blobId": "G_old" } },
  "update":  { "t": { "name": "report.txt" } },
  "destroy": [ "r" ]
}, "0" ]]
]]></artwork></figure>

<t>Without "atomic", a server may process each change sequentially against the
current state (<xref target="JMAP-CORE"/>, Section 5.3), so the rename of "t" could be
rejected because "r" still holds the name, while the destroy of "r" succeeds,
leaving neither file named "report.txt".  With "atomic", the sibling-name
uniqueness rule is evaluated only against the resulting state, in which "r" no
longer exists, and the two changes succeed or fail together.</t>

<t>The "ifUnchangedBy" precondition additionally ensures that "r" is replaced only
if no other client has changed its content since this client read it; if it has,
the method is rejected with a "stateMismatch" error and neither file is changed.
A client that wants the unconditional behaviour of POSIX rename(2) omits the
precondition.</t>

</section>
</section>
<section anchor="implementation-considerations"><name>Implementation Considerations</name>

<section anchor="evaluating-preconditions"><name>Evaluating Preconditions</name>

<t>A server can implement "ifUnchangedBy" generically, without code specific to any
data type.  For each entry, the server reads the current object in the
representation it would return from Foo/get, applies the PatchObject to a copy
of it using the same logic it uses for the "update" argument, and compares the
result with the original.  Any difference means the precondition is not
satisfied.  Every data type that supports Foo/set already has both a Foo/get
representation and PatchObject application, so no new per-type machinery is
required.</t>

<t>If the PatchObject does not apply cleanly, the precondition is not satisfied,
and the server may report it either way rule 4 of <xref target="evaluation-rules"/> allows.</t>

<t>A server <bcp14>MAY</bcp14> instead compare the referenced values directly, or use any cheaper
method, provided the outcome is the same.</t>

<t>The precondition check is only meaningful if no other change to the referenced
objects can occur between evaluating the preconditions and applying the
method's changes.  A server therefore evaluates the preconditions and applies
the changes within the same lock or transaction.</t>

</section>
<section anchor="applying-methods-atomically"><name>Applying Methods Atomically</name>

<t>A server backed by a transactional store can implement "atomic" by performing
the whole Foo/set within a single transaction, deferring constraint checks such
as name uniqueness until all of the changes have been applied, and rolling the
transaction back if any part fails.  A server that cannot do this for some or
all of its data types still supports this extension by returning
"cannotApplyAtomically" (<xref target="cannotapply"/>) for those methods.</t>

</section>
</section>
<section anchor="implementation-status"><name>Implementation Status</name>

<t>EDITOR: please remove this section before publication.</t>

<t>This section records the status of known implementations of the protocol
defined by this specification at the time of posting of this Internet-Draft,
and is based on a proposal described in <xref target="IMPL-STATUS"/>.  The description of
implementations in this section is intended to assist the IETF in its
decision processes in progressing drafts to RFCs.  Please note that the listing
of any individual implementation here does not imply endorsement by the IETF.
Furthermore, no effort has been spent to verify the information presented here
that was supplied by IETF contributors.  This is not intended as, and must not
be construed to be, a catalog of available implementations or their features.
Readers are advised to note that other implementations may exist.</t>

<section anchor="cyrus-imap"><name>Cyrus IMAP</name>

<t><list style="symbols">
  <t>Organization: Cyrus IMAP project</t>
  <t>Description: "ifUnchangedBy" and "atomic" for all JMAP data types implemented
by Cyrus.  "cannotApplyAtomically" is returned only for operations that
cannot be undone: immediate sends, and destroys that would remove data at
once under the server's configured delete or expunge mode.</t>
  <t>Level of maturity: complete, under review
(https://github.com/cyrusimap/cyrus-imapd/pull/6104)</t>
  <t>Licensing: BSD-style</t>
  <t>Contact: Bron Gondwana <eref target="mailto:brong@fastmailteam.com">brong@fastmailteam.com</eref></t>
</list></t>

</section>
<section anchor="fastmail"><name>Fastmail</name>

<t><list style="symbols">
  <t>Organization: Fastmail</t>
  <t>Description: "ifUnchangedBy" in Fastmail's internal JMAP server</t>
  <t>Level of maturity: in development</t>
  <t>Licensing: proprietary</t>
  <t>Contact: Bron Gondwana <eref target="mailto:brong@fastmailteam.com">brong@fastmailteam.com</eref></t>
</list></t>

</section>
</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="jmap-capability-registration-for-conditional"><name>JMAP Capability Registration for "conditional"</name>

<t>IANA is requested to register the "conditional" JMAP Capability as follows, in
the "JMAP Capabilities" registry established by <xref target="JMAP-CORE"/>:</t>

<dl>
  <dt>Capability Name:</dt>
  <dd>
    <t>urn:ietf:params:jmap:conditional</t>
  </dd>
  <dt>Specification document:</dt>
  <dd>
    <t>this document</t>
  </dd>
  <dt>Intended use:</dt>
  <dd>
    <t>common</t>
  </dd>
  <dt>Change Controller:</dt>
  <dd>
    <t>IETF</t>
  </dd>
  <dt>Security and privacy considerations:</dt>
  <dd>
    <t>this document, <xref target="security"/></t>
  </dd>
</dl>

</section>
<section anchor="jmap-error-code-registration-for-atomicfailure"><name>JMAP Error Code Registration for "atomicFailure"</name>

<t>IANA is requested to register the "atomicFailure" JMAP Error Code in the "JMAP
Error Codes" registry established by <xref target="JMAP-CORE"/>:</t>

<dl>
  <dt>JMAP Error Code:</dt>
  <dd>
    <t>atomicFailure</t>
  </dd>
  <dt>Intended use:</dt>
  <dd>
    <t>common</t>
  </dd>
  <dt>Change Controller:</dt>
  <dd>
    <t>IETF</t>
  </dd>
  <dt>Description:</dt>
  <dd>
    <t>A Foo/set requested with "atomic" set to true could not commit all of its
changes together; no change was made.  Returned as a method-level error.</t>
  </dd>
  <dt>Reference:</dt>
  <dd>
    <t>this document</t>
  </dd>
</dl>

</section>
<section anchor="jmap-error-code-registration-for-cannotapplyatomically"><name>JMAP Error Code Registration for "cannotApplyAtomically"</name>

<t>IANA is requested to register the "cannotApplyAtomically" JMAP Error Code in
the "JMAP Error Codes" registry established by <xref target="JMAP-CORE"/>:</t>

<dl>
  <dt>JMAP Error Code:</dt>
  <dd>
    <t>cannotApplyAtomically</t>
  </dd>
  <dt>Intended use:</dt>
  <dd>
    <t>common</t>
  </dd>
  <dt>Change Controller:</dt>
  <dd>
    <t>IETF</t>
  </dd>
  <dt>Description:</dt>
  <dd>
    <t>A Foo/set was requested with "atomic" set to true, but the server cannot
apply this method atomically; no change was made.  Returned as a method-level
error.</t>
  </dd>
  <dt>Reference:</dt>
  <dd>
    <t>this document</t>
  </dd>
</dl>

</section>
</section>
<section anchor="security"><name>Security Considerations</name>

<section anchor="information-disclosure"><name>Information Disclosure</name>

<t>The conditional mechanism returns no object data.  A failed precondition yields
only a "stateMismatch" error, optionally naming the ids whose preconditions did
not hold, but never their values — nothing beyond what the client could already
obtain by reading the objects with Foo/get.</t>

<t>A precondition does not bypass access control.  A server <bcp14>MUST</bcp14> require the same
permissions to read the properties referenced in an "ifUnchangedBy" PatchObject
as it would to return them from Foo/get.  In particular, a server <bcp14>MUST NOT</bcp14>
evaluate a precondition on a property the requesting client is not permitted to
read; such a condition <bcp14>MUST</bcp14> cause the method to fail with a "forbidden" error,
so that the mechanism cannot be used as an oracle to probe the values of
properties the client cannot otherwise see.</t>

<t>This differs deliberately from a precondition on an object that does not exist
or is not visible to the client, which is reported as "stateMismatch"
(<xref target="effect"/>).  For a client, an invisible object is indistinguishable from one
that does not exist, and reporting it differently would disclose its existence.
A property the client may not read, by contrast, belongs to an object the client
can see; the restriction depends only on the client's rights, not on the
property's value, so "forbidden" discloses nothing about the value and tells the
client that the request cannot succeed however it is retried.</t>

</section>
<section anchor="atomic-methods-and-resource-consumption"><name>Atomic Methods and Resource Consumption</name>

<t>Applying a method atomically may require the server to hold a transaction, or
equivalent locks, across all of its changes, and so a very large atomic Foo/set
can hold resources longer than the same changes made independently.  The limits
a server already applies to the number of objects in a single Foo/set
(<xref target="JMAP-CORE"/>) continue to apply, and a server <bcp14>MAY</bcp14> reject an atomic method it
considers too large rather than attempt it.</t>

</section>
<section anchor="resource-consumption"><name>Resource Consumption</name>

<t>Evaluating a precondition is comparable in cost to validating an update
PatchObject and imposes no significant additional load.</t>

</section>
</section>
<section anchor="changes"><name>Changes</name>

<t>EDITOR: please remove this section before publication.</t>

<t>The source of this document exists on github at:
https://github.com/brong/draft-gondwana-jmap-conditional/</t>

<t><strong>draft-ietf-jmap-conditional-02</strong></t>

<t><list style="symbols">
  <t>Clarified that a precondition with a pointer whose parent does not exist in
the current object is never satisfied, whatever its value.</t>
  <t>Allowed a server to reject such a precondition, an invalid pointer, or a
malformed PatchObject with either "invalidArguments" or "stateMismatch".</t>
  <t>A creation id stands for the id it produced; if no object of the method's
type has that id, the precondition is evaluated as for an object that does
not exist, rather than rejecting the method.</t>
  <t>Allowed "null" in place of a PatchObject, asserting that the object does not
exist.</t>
  <t>Clarified that an empty PatchObject is valid and asserts only that the
object exists, and added an example.</t>
  <t>Updated the Cyrus IMAP implementation status: "atomic" is now implemented.</t>
</list></t>

<t><strong>draft-ietf-jmap-conditional-01</strong></t>

<t><list style="symbols">
  <t>Moved the examples into their own section; they were previously nested under
the "Atomic Foo/set" section.</t>
  <t>Added an example of atomically replacing one file with another (the POSIX
write-then-rename pattern).</t>
  <t>Added Implementation Considerations, describing a generic way to evaluate
preconditions and to apply methods atomically.</t>
  <t>Added an Implementation Status section.</t>
  <t>Explained why a precondition on an unreadable property yields "forbidden"
while a precondition on an invisible object yields "stateMismatch".</t>
  <t>Clarified that <xref target="JMAP-CORE"/> already permits, but does not require, a server
to accept changes such as a name exchange whose final state is valid;
"atomic" makes this a guarantee.</t>
</list></t>

<t><strong>draft-ietf-jmap-conditional-00</strong></t>

<t><list style="symbols">
  <t>Upload with working-group adopted name.</t>
</list></t>

<t><strong>draft-gondwana-jmap-conditional-01</strong></t>

<t><list style="symbols">
  <t>Added the "atomic" argument to Foo/set: a method requested with "atomic" is
applied as a single unit, with constraints evaluated against the resulting
state (enabling changes valid only as a whole, such as an atomic name
exchange).</t>
  <t>Added the "atomicFailure" method-level error (the method's changes could not
be committed together) and the "cannotApplyAtomically" method-level error
(the server cannot apply the method atomically), both registered with IANA.
A server <bcp14>MUST NOT</bcp14> apply an atomic method's changes only in part.</t>
  <t>Generalised "ifUnchangedBy" to allow a precondition on any object of the
method's type, including objects the method does not itself create, update,
or destroy (for example a parent or container).</t>
  <t>Changed the effect of a failed precondition from a per-object "stateMismatch"
SetError to a method-level "stateMismatch" error that rejects the whole
method and makes no change; a client wanting independent application uses
separate method calls.  Removed the bespoke per-object SetError definition in
favour of Core's method-level "stateMismatch", optionally carrying the
"failed" ids.</t>
</list></t>

<t><strong>draft-gondwana-jmap-conditional-00</strong></t>

<t><list style="symbols">
  <t>Initial proposal.</t>
</list></t>

</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="JMAP-CORE">
  <front>
    <title>The JSON Meta Application Protocol (JMAP)</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2019"/>
    <abstract>
      <t>This document specifies a protocol for clients to efficiently query, fetch, and modify JSON-based data objects, with support for push notification of changes and fast resynchronisation and for out-of- band binary data upload/download.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8620"/>
  <seriesInfo name="DOI" value="10.17487/RFC8620"/>
</reference>

<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>

<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>




    </references>

    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="JMAP-MAIL">
  <front>
    <title>The JSON Meta Application Protocol (JMAP) for Mail</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="August" year="2019"/>
    <abstract>
      <t>This document specifies a data model for synchronising email data with a server using the JSON Meta Application Protocol (JMAP). Clients can use this to efficiently search, access, organise, and send messages, and to get push notifications for fast resynchronisation when new messages are delivered or a change is made in another client.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8621"/>
  <seriesInfo name="DOI" value="10.17487/RFC8621"/>
</reference>

<reference anchor="HTTP-SEMANTICS">
  <front>
    <title>HTTP Semantics</title>
    <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
    <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
    <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
    <date month="June" year="2022"/>
    <abstract>
      <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
      <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="97"/>
  <seriesInfo name="RFC" value="9110"/>
  <seriesInfo name="DOI" value="10.17487/RFC9110"/>
</reference>

<reference anchor="WEBDAV">
  <front>
    <title>HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)</title>
    <author fullname="L. Dusseault" initials="L." role="editor" surname="Dusseault"/>
    <date month="June" year="2007"/>
    <abstract>
      <t>Web Distributed Authoring and Versioning (WebDAV) consists of a set of methods, headers, and content-types ancillary to HTTP/1.1 for the management of resource properties, creation and management of resource collections, URL namespace manipulation, and resource locking (collision avoidance).</t>
      <t>RFC 2518 was published in February 1999, and this specification obsoletes RFC 2518 with minor revisions mostly due to interoperability experience. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="4918"/>
  <seriesInfo name="DOI" value="10.17487/RFC4918"/>
</reference>


<reference anchor="JMAP-FILENODE">
   <front>
      <title>JMAP File Storage extension</title>
      <author fullname="Bron Gondwana" initials="B." surname="Gondwana">
         <organization>Fastmail</organization>
      </author>
      <date day="20" month="October" year="2026"/>
      <abstract>
	 <t>   The JMAP base protocol (RFC8620) provides the ability to upload and
   download arbitrary binary data.  This binary data is called a &quot;blob&quot;,
   and can be used in all other JMAP extensions.

   This extension adds a method to expose blobs as a filesystem along
   with the types of metadata that are provided by other remote
   filesystem protocols.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-jmap-filenode-18"/>
   
</reference>

<reference anchor="IMPL-STATUS">
  <front>
    <title>Improving Awareness of Running Code: The Implementation Status Section</title>
    <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
    <author fullname="A. Farrel" initials="A." surname="Farrel"/>
    <date month="July" year="2016"/>
    <abstract>
      <t>This document describes a simple process that allows authors of Internet-Drafts to record the status of known implementations by including an Implementation Status section. This will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.</t>
      <t>This process is not mandatory. Authors of Internet-Drafts are encouraged to consider using the process for their documents, and working groups are invited to think about applying the process to all of their protocol specifications. This document obsoletes RFC 6982, advancing it to a Best Current Practice.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="205"/>
  <seriesInfo name="RFC" value="7942"/>
  <seriesInfo name="DOI" value="10.17487/RFC7942"/>
</reference>




    </references>

</references>



  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA8192ZLbVprm/XkKDDURlhRkarFqMVVRPanFVdlhWWot7elx
OTpAEsxEiwQ4OGCm2RpVzEPMA8yzzKP0k/T//ctZAGam7PDF1EU5RQJn+fed
s9nM9XW/qebFP746fVM8b5tV3ddtU26Kd1XvysWiqy7HX7pVu2zKLb226sp1
P6urfj37t225my3jQ7OHj53fL7a19/Tv94cdPX728v23bln21XnbHeaF71du
v1vRv/28+OPvHz907cK3mwr/dvWumxd9t/f944cPv6HFPlaHq7Zb0SpNX3VN
1c9eYHfn+7JZ/Wu5aRva4VB5t6vnxY99u5wWvu36rlp7+uuwxR8/OVfu+4u2
m7ti5gr6X93Q3s9Oir/Qya/KpuQP5XLPurbJP2+783nxben7bVlv+JMKf82L
BT16/t/W+k1flduTZbt1rmm7bdnXl9WcnwYgZ89fv305L95++5xv7OpmfeSh
V6dn39lDj/jjv75//2b27uWr0+/fnz1/x9998+jRQ/7uh5fPXpz+M3/25JtH
f4zLfHv23cvvX7+g/c5mL04intb1pmraVcVPnr16893s3fvT9x9k2T988+Sx
c7PZrCgXvu/KZe/c+4tKyGBR+qrYdS3Bt90Udz99Cnf6/PkevrisV5Uvenr+
27Z94Ku+2FYE8VVB13TLrqKbNufTgvHOfxH2Cnql79oD/btoF/9WLXt/Qufq
i3a9rjpflIWnrzZVQfS13Hdd1SwPjv6mdzZT3mtSr8+adz2R0qQou/P9tmr6
aXF1US8vivN92a1okaagD+uu0i2KnmmyXtM3B6eftWtarpTviovSF8uLsjmv
VrLL1QVRp92n9kVX4aVqdQIA0b+rn/uqAbkX5Qo7Fuu6qbppsau6mW6QcAgt
hNVrv6XLnhbLTU3nK7blwXXV/9zjoHwUOndN7xBc9/SO8AtRosEMMF9W1apo
m80Bt8FBe4IBQV72JA6pN7Rb2S8vKgZmxRetft7x6bECnbA/FJflZl8Rt9A3
XeU9fbUH4HlJ4Nm9wRqv5SblhpC5OtA5cEvGr54OyGN4BHJod31NkqCvl8dQ
WPglHWBV9G3EtILrP/73/+HdARA6HQDUAmHMDsXkbD17hSNNHB04gJbfwnEI
sUK1dKqScXoEUxvf6h2YRnBUxs6k7NttvYz0pOjY7QhReNQpORmdlwmh7pu6
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
Ih5zfAAA

-->

</rfc>

