docs: add ADR for per-login JMAP sessions
Assisted-by: Claude Opus 5.5 via Claude Code
change rymxxkttkppqstzqoyypzpnpqnoqtlyq
commit 8df871d14c30545284e139c5683003a856dfc6b1
author Alpha Chen <alpha@kejadlen.dev>
date
parent vqvozlkn
diff --git a/docs/DESIGN.md b/docs/DESIGN.md
index e63263e..45dfdee 100644
--- a/docs/DESIGN.md
+++ b/docs/DESIGN.md
@@ -31,7 +31,7 @@ Backed by Fastmail. Credentials and accounts are separate:
 - A **credential** is a Fastmail API token (JMAP type) for one Fastmail login. It opens a JMAP session.
 - An **account** is a JMAP `accountId` from that session.
 
-Chosen setup: **one credential per login, no JMAP sharing.** The household login gets a token with mail + submission scopes; our son's login gets its own token with a read-only mail scope. (Alternative considered: sharing his account into the household login so Docket never holds a credential for his login. Rejected for now in favor of simplicity and no dependency on how Fastmail exposes shares. To be recorded in an ADR — see below.)
+Chosen setup: **one credential per login, no JMAP sharing.** The household login gets a token with mail + submission scopes; our son's login gets its own token with a read-only mail scope. Sharing his account into the household login was considered and rejected for now; see [ADR 1](adr/0001-per-login-jmap-sessions.md).
 
 **Policy is derived from what the server permits, not config.** The app reads token capabilities, `isReadOnly` on the session account, and `myRights` on each mailbox and only offers actions that are allowed.
 
@@ -154,7 +154,3 @@ The primary other client is **Mail.app over IMAP**; Fastmail web stays in folder
 - Whether Fastmail web URLs are stable enough to deep-link to a thread.
 - Mail.app behavior test (throwaway message): label it `Docket/Do`, then file, archive, and delete it from Mail.app, checking `mailboxIds` via JMAP after each step. Confirms that moves keep other mailbox memberships and shows what Trash/Archive do to the `Docket/` label.
 - Confirm Fastmail offers a read-only mail scope for API tokens, and how it shows up in the session.
-
-## When development starts
-
-- Write an ADR recording the choice of separate per-login sessions over JMAP sharing for our son's account, including the trade-offs: simplicity and no sharing unknowns vs. Docket holding a credential for his login.
diff --git a/docs/adr/0001-per-login-jmap-sessions.md b/docs/adr/0001-per-login-jmap-sessions.md
new file mode 100644
index 0000000..08d3a96
--- /dev/null
+++ b/docs/adr/0001-per-login-jmap-sessions.md
@@ -0,0 +1,47 @@
+# 1. Per-login JMAP sessions over sharing
+
+Date: 2026-10-03
+
+Status: Accepted
+
+## Context
+
+Docket manages two Fastmail logins: the household login, which we
+read and write, and our son's login, which we monitor read-only. Docket
+can reach his mail in either of two ways:
+
+- Separate sessions: his login gets its own API token, and Docket opens
+  a second JMAP session with it.
+- Sharing: he shares his mail into the household login, and his account
+  appears as another `accountId` in the household session. Docket holds
+  one token.
+
+Sharing keeps his credential out of Docket, but it depends on how
+Fastmail exposes shared accounts over JMAP: whether they show up in the
+session, which rights they carry, and whether push covers them. We
+haven't tested any of that.
+
+## Decision
+
+Docket uses one credential per Fastmail login and no JMAP sharing. The
+household token has the mail and submission scopes. His token has a
+read-only mail scope.
+
+## Consequences
+
+- Docket treats every credential the same way: one session and one push
+  connection each, with accounts read from that session. No code path
+  handles shared accounts.
+- Docket holds a token for his login. If it leaks, it exposes his mail
+  directly rather than through a share we could revoke from the
+  household side. The token lives in its own file like any other
+  credential (see [Storage](../DESIGN.md#storage)), and a separate file
+  is one more secret to provision and rotate.
+- Docket derives what it offers from what the server permits, so the
+  read-only guarantee rests on the token's scope, not on Docket's
+  config. This assumes Fastmail offers a read-only mail scope, which is
+  still unconfirmed. If it doesn't, his token would permit writes and
+  Docket would offer them, so revisit this decision.
+- Revisit sharing if separate sessions become a burden, such as more
+  monitored logins or token rotation becoming a chore, and test how
+  Fastmail exposes shares before switching.