[JMAP] Re: JMAP for Calendars comments

Neil Jenkins <neilj@fastmailteam.com> Fri, 10 October 2025 01:27 UTC

Return-Path: <neilj@fastmailteam.com>
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 58BDA7064E11 for <jmap@mail2.ietf.org>; Thu, 9 Oct 2025 18:27:17 -0700 (PDT)
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -2.798
X-Spam-Level:
X-Spam-Status: No, score=-2.798 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, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b="UiIc2v//"; dkim=pass (2048-bit key) header.d=messagingengine.com header.b="FMp0Rst7"
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 DCF95r6OFNTu for <jmap@mail2.ietf.org>; Thu, 9 Oct 2025 18:27:16 -0700 (PDT)
Received: from fhigh-b6-smtp.messagingengine.com (fhigh-b6-smtp.messagingengine.com [202.12.124.157]) (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 3AFB47064E05 for <jmap@ietf.org>; Thu, 9 Oct 2025 18:27:16 -0700 (PDT)
Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id AAAE67A012C for <jmap@ietf.org>; Thu, 9 Oct 2025 21:27:09 -0400 (EDT)
Received: from phl-imap-15 ([10.202.2.104]) by phl-compute-02.internal (MEProxy); Thu, 09 Oct 2025 21:27:09 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=cc:content-type:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm3; t=1760059629; x= 1760146029; bh=+qRRnun3A2Tm8UFgpnuxA/bECY1qizkjYDkRwt7wVNk=; b=U iIc2v//z7HOVwWH2Vn/AV/dzmh5gGRM2XnlkOzZ4VAdSNN0GIaBA/8K2QuxHSwb+ Mtpiy+D2bWrExU994UgukTA8tMx2uHKGa+VuCzB7BDwrA1YFfF6BTWNlUchUZANI r5FlZqd/l/eesmh0fAdx7fnKmO3OuaKZJEEzAurvcm0SW4y9vRwbIK7fbr4wV7jm QFVE8TV/D7qU5eeVS3XBTztvCKmCY4o8T/dbLQ/dUyZyPDc9pnmXx+DnlKRRZxsg 4bVtAZG9uEEbuBTbUvOnx7uGwEut/HkAOZCfPkJ55xlJ34WW/f37h+SK60bVQn3B OYmv0f1HCfrmzYc55Q4LQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1760059629; x=1760146029; bh=+qRRnun3A2Tm8UFgpnuxA/bECY1qizkjYDk Rwt7wVNk=; b=FMp0Rst7kp2VDwUYq+qvsOdwB4GeZjXomxnNuZHIiaaIWw7UbPs OmXcGlHZVWDntSFbdNkZ2Ow4Zk6IQ8MRPL5l+HRK/vEjeWYoqD5p76gKJNGvZlor HGztOGwY4isiugDUiIRLg6pmLuzbmHHyD3hQAaw9GAPgpUceIZKxl87vMYawnBYa v3bylmU1lwRGId7ig/UV0Mo8YZvOrve2WzgUS1DmbNlgyndtgMk2AwXwNJvYvG8P mGLdxTNREg1R8rQgEnlWnwlG1/+oDDU+GoiRuQqZsgFnRVnDUrXPhXJSktZm/7is SRbbAJf7PsxlY7SAIlSGcAQf30l2hjfHMRg==
X-ME-Sender: <xms:7WDoaBD4cSLnHbNFKNKmAlgYc3CZ8rDeSRGSRxATZqzGRMKG_unHYA> <xme:7WDoaKXSs3kLEqYdEnw08SKoenRrSWke51AtP9x_8Jp-IDQlZxZGdhOut3pCmA4BT 2F2PGRTQvF5HOUMCE6wvcfJoOCVyW9sTgT8sdbwQoMaCy-AJQ>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddutdejjeegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvffkjghfufgtsegrtderreertdejnecuhfhrohhmpedfpfgvihhlucfl vghnkhhinhhsfdcuoehnvghilhhjsehfrghsthhmrghilhhtvggrmhdrtghomheqnecugg ftrfgrthhtvghrnhepleegteeihfdugeduheejvdevudehjeejteeijeeufeduveetieej keevvefgtedvnecuffhomhgrihhnpehivghtfhdrohhrghenucevlhhushhtvghrufhiii gvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehnvghilhhjsehfrghsthhmrghilhht vggrmhdrtghomhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtg hpthhtohepjhhmrghpsehivghtfhdrohhrgh
X-ME-Proxy: <xmx:7WDoaCm1cPChvZJM3aIgkNOx0i9oxB_xRONGwRAFFoTa9DPLVigZ-g> <xmx:7WDoaAwNLNm4s-fp2NbOQFQ4qObz9g5tv5FG9t5vlnoW4AC2p7ybYg> <xmx:7WDoaGTBrPb4813aNVv07oLyQ552lZHbc643N-dYgD3mqsFa7MvlRg> <xmx:7WDoaLuw86U69wiVjvbEKgZlM40FZG9-0m_x-SdqHjHYQlKZE1rmNw> <xmx:7WDoaOcofkUqMMjDJRtruEDSUIBBaaBe0SpInByY5HTst9uQOWRx1_IO>
Feedback-ID: ibc614277:Fastmail
Received: by mailuser.phl.internal (Postfix, from userid 501) id 47B7B78012B; Thu, 9 Oct 2025 21:27:09 -0400 (EDT)
X-Mailer: MessagingEngine.com Webmail Interface
MIME-Version: 1.0
X-ThreadId: An5MunO63raJ
Date: Fri, 10 Oct 2025 12:26:48 +1100
From: Neil Jenkins <neilj@fastmailteam.com>
To: IETF JMAP Mailing List <jmap@ietf.org>
Message-Id: <4561708e-c41a-4ef5-a644-0444eabbc083@dogfoodapp.fastmail.com>
In-Reply-To: <34E1318A-C0D3-495F-9076-6B914C60D59F@stalw.art>
References: <101DEC25-A12F-4063-90FB-446C6E5190BF@stalw.art> <4aa2017d-5ef4-486f-a264-2c8e2bec6094@dogfoodapp.fastmail.com> <34E1318A-C0D3-495F-9076-6B914C60D59F@stalw.art>
Content-Type: multipart/alternative; boundary="bbe3a877ff7b4dbf9768f5a706071082"
Message-ID-Hash: Y3GIXWOJWWLJ52CBCFE3NG3IRCTEMXM6
X-Message-ID-Hash: Y3GIXWOJWWLJ52CBCFE3NG3IRCTEMXM6
X-MailFrom: neilj@fastmailteam.com
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: JMAP for Calendars comments
List-Id: JSON Meta Access Protocol <jmap.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/w8KV_NJSvB2KBabTb4COuCMOEXw>
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 Mauro,

>  • *Finding the principal for a calendar address: *As mentioned before, it’s currently not possible to obtain the principal ID for a given calendar address. Allowing `Principal/query` to search by `calendarAddress` would solve this and avoid the need to add a new property to the `Participant` object.
> 

I'm still not quite clear on the use case you have here. The only one I can see (using your scenario) is that you are Wile E. Coyote and want to check the availability of Road Runner so you can invite them to an event, but you only know their alias `runner@acme.net and not ``road_runner@acme.net? That … doesn't seem very likely?`

>  • *Discovering a principal’s calendar addresses:*
> 

This is already in the spec <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#section-2.1>:

A "urn:ietf:params:jmap:calendars" property is added to the Principal 
"capabilities" object, the value of which is an object with the 
following properties:
[…]

*calendarAddress*: `String
`
If this Principal may be added as a participant to an event, this is the calendarAddress to use to receive iTIP scheduling messages.

>  • *Identifying the main account ID of a principal: *Suppose Road Runner wants to share his personal calendar (or a mailbox) with Wile. He queries for Wile’s `Principal` and sees account IDs “A1” and “A3” listed under the `accounts` property. But how can his client tell which one is Wile’s main account?
> 

Also in the same bit of the spec <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#section-2.1>:

A "urn:ietf:params:jmap:calendars" property is added to the Principal 
"capabilities" object, the value of which is an object with the 
following properties:

*accountId*: Id|null

Id of Account with the urn:ietf:params:jmap:calendars capability that contains the calendar   data for this Principal, or null if either (a) there is none (e.g. the Principal is a group just used for permissions management), or (b) the user does not have access to any data in the account (with the exception of free/busy, which is governed by the "mayGetAvailability" property).

>  • Both have the `urn:ietf:params:jmap:principals:owner` capability since he’s a member of both.
> 

This doesn't make sense — A3 is not owned by either Wile E Coyote or Road Runner, it is just shared with both of them. It should either have no owner, or be owned by a Principal representing the team.

> I also have a few additional comments and questions unrelated to the above:
> 
>  • *CalendarEvent/set:* The line *“If 'utcStart' is set, this is translated into a 'start' property using the server's current time zone information”* isn’t entirely clear. I assume it means the event is converted to the calendar’s default time zone?
> 

If the "timeZone" property of the event is null, then yes. If not-null, it should be translated into local time using whatever time zone was set by that property. By "The server's current time zone information" I just meant the current version of the IANA DB it has at the time. I agree this could be clearer.

>  • *Conflicting calendar defaults:* When an event is added to multiple calendars with different default alerts, time zones, etc., how should these preferences be applied?
> 

For alerts, it's the union of all alerts:
*6.1 Default alerts <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#section-6.1>*
If the "useDefaultAlerts" property of an event is true, the alerts are 
taken from the "defaultAlertsWithTime" or "defaultAlertsWithoutTime" 
property of all Calendars (see Section 4 <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#calendars>) the event is in,

The time zone one is trickier, and is not currently defined in the spec I think. So if you have an event without a time zone, and it's in multiple calendars with different default time zone properties … err, I have no idea what you should do. I think all you can do is pick one, and try to make it stable? Any other suggestions?

>  • *Principal/getAvailability:*
> 
>    • The method requires both a `principalId` and an `accountId`. Could the `accountId` be made optional so the server returns combined availability for all calendars the principal can access?
> 

The accountId here is the account id in which to find the Principal object (just like every other JMAP method — when you're supplying record ids, you need to know the account id in which to look for them). It's *not* the account id in which to look for calendars/events for that principal: you should indeed look at all calendars/accounts the Principal has access to (subject to the includeInAvailability property etc. set on the calendar for that principal).

>  • The rules for relevant events cover shared calendars, but it would help to clarify how to handle personal calendars containing events without participants.

I think this is already covered by:
If the "includeInAvailability" property of the calendar is "attending", 
then the Principal is a participant of the event, and has a 
"participationStatus" of "accepted" or "tentative".

I would expect (by default at least), the user's personal calendars to have includeInAvailability set to "all" (i.e. all events, including those without participants, are considered), while shared/team calendars might have includeInAvailability set to "attending".

>  • It’s unclear what `busyStatus` should be used when `participationStatus` is `needsAction`, `tentative` (and maybe also that `delegated should not be included`).

`"tentative"` — The event status is "tentative" or the Principal's "participationStatus" is "tentative".

That's an "or", so if the event status is tentative, the busyStatus here would be tentative, according to the spec. (Or have I misunderstood your question?)

>  • *Recurrence range matching:* CalDAV treats time ranges differently for `VEVENT` and `VTODO` (RFC 4791 §9.9). Should JMAP for Calendars follow the same behavior for consistency?
> 

I'm not sure I quite follow here. JMAP Calendars does not return todos, only events, so I'm not sure how VTODO is relevant?

>  • *CalendarEvent/query:* The `cannotCalculateOccurrences` error seems to cover general recurrence failures. Would it be useful to define a specific error when a recurrence range expansion is too large?
> 

You mean if it exceeds the *maxExpandedQueryDuration* duration (found in the capabilities)? Yeah, that should maybe have a different error type.

>  • *CalendarEventNotification:* The `changedBy/name` property should probably be nullable, since this information might not be available in iMIP messages from external systems.
> 

Yeah, ok.

>  • *Shared personal calendars:* The specification currently focuses on shared group calendars, which is great, but it might also need to clarify the rules for shared *personal* calendars (for example, how `Principal/getAvailability` should behave in that context).
> 

I'm not quite sure what you're looking for here; if it's not cleared up by the comments above, could you please clarify what's unclear?

Cheers,
Neil.