[JMAP] Re: Status of JMAP Metadata, RefPlus and Mail Sharing drafts ahead of IETF 125
Mauro De Gennaro <mauro@stalw.art> Wed, 27 May 2026 18:47 UTC
Return-Path: <mauro@stalw.art>
X-Original-To: jmap@mail2.ietf.org
Delivered-To: jmap@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 03207F624D9C for <jmap@mail2.ietf.org>; Wed, 27 May 2026 11:47:21 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ietf.org; s=ietf1; t=1779907641; bh=doBcGHhUdLbvPAuHvLjdIG2lgahiPXmMp4ih7nNuV3o=; h=From:Subject:Date:References:To:In-Reply-To; b=GbsUpzqRQeKAvdET3KqkHMr2dZn4pgGj+nAk5hIaOg990HCuQBujBrdKb61vQx39L Uhbb1uPywkZbPwXY+H68vHhyvriTA9k2gTf1xc1jo2vxL5Dmw6RLDh4XYUvb0ExL2b K2MPZS7vwYqb5nj9mllbzwVB1/2Da2nNET/AmwCk=
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -2.099
X-Spam-Level:
X-Spam-Status: No, score=-2.099 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=neutral reason="invalid (unsupported algorithm ed25519-sha256)" header.d=stalw.art header.b="vWSGUFUg"; dkim=pass (2048-bit key) header.d=stalw.art header.b="Njh+UDaP"
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YdKUdPk9BlmU for <jmap@mail2.ietf.org>; Wed, 27 May 2026 11:47:19 -0700 (PDT)
Received: from mail.stalw.art (mail.stalw.art [135.181.195.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id 2F052F624D8E for <jmap@ietf.org>; Wed, 27 May 2026 11:47:19 -0700 (PDT)
DKIM-Signature: v=1; a=ed25519-sha256; s=v1-ed25519-20260418; d=stalw.art; c=relaxed/relaxed; r=y; h=Message-Id:To:Date:Subject:From; t=1779907637; bh=nG2m2CYvWvz7aKckwfwbe/i EYGWDnVv/0n5PpWwfOuw=; b=vWSGUFUg6hR1/YAFdwIFaULpSpxQYJHYkAKVE0jSPw3jo+qwi1 9ghAfAz6qYFeokZ9zkZDT9pz++UZaRwxpVDA==;
DKIM-Signature: v=1; a=rsa-sha256; s=v1-rsa-20260418; d=stalw.art; c=relaxed/relaxed; r=y; h=Message-Id:To:Date:Subject:From; t=1779907637; bh=nG2m2CYvWvz7aKckwfwbe/i EYGWDnVv/0n5PpWwfOuw=; b=Njh+UDaPX3i6+4xRQdRchi3Pnc88nJoztwCHBmugoKdd9ePfxl zvlAQXcnG1orklCqyOBBlGaINTfq9//87pyTZXAqZK+DdeyGH32KG3fgjTnn9RMVnpygMZP7AbI yOssGw+Rx+PyeUi4Yts1rNn64mkxnWaiFgeF/g9fSKmUr22P5DDeW45RpWbH03GyrtX7RUtczCf t9CGraRVHPlVrDRxQcY9Ru2N++ulvazl4Gz3BVxq+6bUqqM0gRJhLg+ekHqjErvJldTuAD+z+u5 n/PHbCqioJL/lffnzvTVjJ80bx9uBrqIDxFSSfVgnuuFesmxc+LzMBzg5wi5f7x5AqA==;
From: Mauro De Gennaro <mauro@stalw.art>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.500.181\))
Date: Wed, 27 May 2026 20:47:07 +0200
References: <8397988B-24C5-42D7-BD1E-45CEDD009AC5@stalw.art> <9e8b403c-e0d3-4af6-ac47-c1af06f27e1e@dogfoodapp.fastmail.com>
To: JMAP IETF <jmap@ietf.org>
In-Reply-To: <9e8b403c-e0d3-4af6-ac47-c1af06f27e1e@dogfoodapp.fastmail.com>
Message-Id: <727134A4-1BA7-4F25-AAD8-307F8DDB6BAC@stalw.art>
X-Mailer: Apple Mail (2.3864.500.181)
Message-ID-Hash: 2EYAKS7T56ZSVIG54ZK4VIWQGECH323L
X-Message-ID-Hash: 2EYAKS7T56ZSVIG54ZK4VIWQGECH323L
X-MailFrom: mauro@stalw.art
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-jmap.ietf.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [JMAP] Re: Status of JMAP Metadata, RefPlus and Mail Sharing drafts ahead of IETF 125
List-Id: JSON Meta Access Protocol <jmap.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/b9onajuGvYW1P8ZDyWxtXAXR__Q>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Owner: <mailto:jmap-owner@ietf.org>
List-Post: <mailto:jmap@ietf.org>
List-Subscribe: <mailto:jmap-join@ietf.org>
List-Unsubscribe: <mailto:jmap-leave@ietf.org>
Hi Neil, Thank you for reviewing all three drafts and apologies for taking over a month to reply, much longer than I'd intended. On the three drafts: - JMAP Mail Sharing: I've just bumped it to -01 to keep it alive (the -00 was about to expire), but I haven't added anything new. Happy to take it to WG last call if the everyone agrees. - JMAP refplus: We can discuss this in Vienna if you like. On the use-case question, while implementing a JMAP CLI and a JMAP web UI I came across cases where refplus would be quite helpful. However, I agree that if I'm the only one with a real use case, that's not enough to justify standardisation. I'd like to ask around in Vienna and see if others are interested before pushing further; if there's no general interest for it, I'm fine to drop it. - JMAP Metadata: I've taken all your suggestions on board and just published -02. The biggest change is the move to the property-on-object design you proposed. The separate Metadata data type and its methods are gone. I also ended up dropping the imap and webdav bridge namespaces, leaving them for future extensions if metadata bridging is ever needed. Best, Mauro > On 15 Apr 2026, at 06:50, Neil Jenkins <neilj=40fastmailteam.com@dmarc.ietf.org> wrote: > > I've read through all of these again. > >> https://datatracker.ietf.org/doc/draft-ietf-jmap-mail-sharing/ > > This looks great, I think it should go to WG last call and be submitted for publication. > >> https://datatracker.ietf.org/doc/draft-ietf-jmap-refplus/ > > My overall view of this is still that the added complexity (and execution performance concerns) of this outweighs the performance benefits of reducing a few extra round trips. I'm not objecting to the document moving forward, but I'd love to see some evidence that someone has a real use case for it. Regardless, some more specific concerns: > > §1.2.1. The value of this property in the JMAP Session "accountCapabilities" property is an empty object. > > I don't think the capability should be included in accountCapabilities, just the top-level capabilities. These changes are not things within a particular account; they apply at a higher level (like JMAP Core). (Caveat, see comment on /set below.) > > §2.2.1 The nodelist produced by JSON Path evaluation MUST be resolved according to the expected type of the target property > > I really don't like this. Instead of being a pure syntactical transformation, the dispatching server must now understand the full expected structure of the method being called in order to apply the result reference. This is a layering violation, and could be impossible for a generic JMAP proxy that doesn't understand (or need to understand) the actual method calls it's dispatching to JMAP servers downstream. > > (Yes, I saw later in §3.1 you say "The type-specific resolution rules defined in this specification (determining whether a resolved value should be treated as a single value, an array, or a map) are applied by the JMAP method implementation layer, not by the reference resolution layer." — that's still requiring support at multiple layers.) > > Instead, why not add an extra type property to the ResultReference object that gives the expected type? The caller should know what they expect this to resolve to, and that means the reference resolver doesn't need to know. This lets everything be done at the Syntactic Resolution Phase (per §3.2). > > §2.3 Usage in /set Methods > > I think we need to explicitly state that should you opt in to the refplus capability you cannot set a property within a Foo object that beings with a literal #. This is not a problem with any of the data types being used with JMAP so far (as far as I'm aware), but worth noting for the future. (If for some reason a client does need to do this in the future, they must not include the refplus capability in the using array of the Request object; as per RFC8620, if not explicitly opted in, the server must not apply the capability.) > > §2.3 If a result reference fails to resolve, the server MUST reject the creation or update of that specific object with a SetError of type "invalidResultReference" > > This is problematic, because it means the resolution has to happen at method execution time, rather than at method dispatch time. I don't think it's necessary: we can resolve the references before dispatch and reject the whole method with invalidResultReference if any fail. That's consistent with all the other result reference resolution, and means it can be handled in the same layer. > > Otherwise, if we really want to keep the currently specified behaviour, I think we will need to add the refplus capability to the accountCapabilities of accounts that support using ResultReferences inside /set create/update. Again, in the proxy case it may not be all of them. > >> https://datatracker.ietf.org/doc/draft-ietf-jmap-metadata/ > > > I think this is looking fairly solid. A few comments: > > §2.1.2 Servers SHOULD document whether they provide read-only or read-write access to ImapMetadata. > §2.1.3 Servers SHOULD document whether they provide read-only or read-write access to WebDavMetadata. > > Why not put this in the capabilities? > > §3.1 "alreadyExists" SetError […] MAY include an "existingId" property containing the id of the existing Metadata object. > > I'd change this MAY to a MUST — it's easy to implement, and if it's only a MAY a client can't rely on it, which is a pain. (As a general rule, > > §4.1 The response to an extended /get method includes the following additional property > > I think we probably need to include metadataState in the response as well? > > §4.2.1 Servers SHOULD NOT generate […] state changes for automatically deleted metadata. The deletion is considered an implicit consequence of destroying the related object. However, servers MAY emit push notifications or update metadata state strings to reflect that metadata has been deleted, if such notifications would otherwise occur for explicitly deleted metadata. > > I'm not quite sure what you're going for here. Surely the metadata state has to change if a metadata object is destroyed, regardless of how this happened. Otherwise, the /changes updates won't work correctly. > > Related, the document doesn't currently specify that changes purely to a Metadata object SHOULD NOT change the state string for the related type, but I think that's the idea. Although… > > Is this the right approach? > > With my client implementer hat on, I was thinking about how I would want to use metadata. Generally, I'd want to be able to say "I'm interested in metadata for this particular type" and then fetch/update it with the instances of that type themselves. I can't think of a circumstance where I'd want metadata without the related object, but I could definitely just have a small subset of the dataset for a particular object (e.g. I have loaded 100 emails for a user with 1,000,000 messages). The current approach is a bit painful: > • I can fetch the metadata with the Email objects by using the fetchMetadata argument. Fine. > • The Metadata state changes. I call Metadata/changes with filterRelatedType set to "Email". I can ignore any updated metadata objects I don't have, but I have to always fetch the created metadata objects, as I have no way of knowing if they're related to the Email objects I currently have in memory or not. > • I can't search for a Foo object that has some particular metadata AND a regular property (e.g. if I used metadata to store a memo on an Email, and wanted to search for all emails that are in the inbox and have a memo with the text "foo"). > A very different approach would be: > • Data types with metadata support (as per the capabilities) get a mutable _metadata_: String[*] property if you opt in to the capability. We could have a _private_metadata_ property too for private metadata, if supported (per the capability). > • The value of this property is a (possibly empty) object (never null so you can always patch). The keys at the top level are registered, or a domain name: > • imap: maps to IMAP metadata > • webdav: maps to WebDAV metadata > • example.com: maps to arbitrary vendor data. > • The metadata property can be specified in the properties argument to Foo/get, like any other property. If you don't specify any properties, it will be returned with the default set of properties (normally everything) for that data type. (Or maybe we'd need a way to say "give me all the default properties, but not the metadata properties for this object type"?) > • Foo/changes returns objects where the _metadata_ property has changed in the updated argument of the response. We add an updatedProperties argument to the response, like in Mailbox/changes. If only metadata has changed, the server should use this to indicate that, so you can then only fetch the metadata property. Possibly we add an extra argument to Foo/changes to ignore metadata-only changes for data types where you're not interested in the metadata. > • We define some extensions to the Foo/query FilterCondition for any data type that supports metadata: > • the presence of metadata at a particular path, e.g., {"metadataExists": "fastmail.com/memo"} — this matches any object where it has a value defined at that path. > • text match at a particular path. e.g., {"metadataText": { path: "fastmail.com/memo", value: "foo"} — looks for a string in the property at a particular path. Is false if the path doesn't exist or isn't a string type. > • That's … kind of it? You can use standard Foo/set patching to update specific metadata properties without stomping on other vendors’ metadata. You always keep your metadata in sync with the underlying objects. You don't really need to change any code in the client, and all existing sync code will just work. > Thoughts? This seems both simpler and more functional to me, and I don't see any obvious drawbacks at first glance. > > Cheers, > Neil. > _______________________________________________ > JMAP mailing list -- jmap@ietf.org > To unsubscribe send an email to jmap-leave@ietf.org
- [JMAP] Status of JMAP Metadata, RefPlus and Mail … Mauro De Gennaro
- [JMAP] Re: Status of JMAP Metadata, RefPlus and M… Neil Jenkins
- [JMAP] Re: Status of JMAP Metadata, RefPlus and M… Mauro De Gennaro