fix(drafts): guard immutable draft replacement and preserve originals #45
No reviewers
Labels
No labels
waiting-on-julian
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jlxq0/jmap-mcp!45
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/safe-draft-replacement-20261029"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
update_draftpreviously patched immutable JMAP content and accepted Email IDs without draft ownership or concurrency guards. It now requires the saved account state and draft revision, creates and verifies a replacement, then conditionally moves the verified original to Trash and reads both back. It never permanently deletes or submits email. Partial/unknown outcomes carry recovery IDs and permanently consume the workflow generation; clients must serialize updates and reconcile manually before accepting a new generation.save_draftreturns verified ID/state/revision; read-onlyget_draft_versionsupports safe conflict checks. The server accepts any account-owned plain draft, so autonomous clients must separately track their own created IDs and unchanged generation revisions. Blank/foreign From fields, sent/moved mail and unsupported rich/MIME content are refused. RFC line endings, empty subject text and bracketed reply IDs are normalized before writing; the same plain part in both text/HTML display lists is supported. Existing update clients must migrate to required preconditions and the newly returned Email ID.Rebased onto separately reviewed/green/merged dependency PR46. Exact current head
2e19f3e03b8489835b105c767bfd6fad6fa81add: pinned Rust1.93.0 fmt, clippy(all targets/features, locked, -Dwarnings),274tests pass. Nine deliberate guard-removal mutations each fail named handler tests; restored source hash matches current module. Cargo audit0vulnerabilities (existing allowed chacha20 yankedwarning), deny bans/licenses/sources and checksum-pinned OSV2.5.1 pass. Native read-only Stalwart metadata corrected fixture shape; it does not prove live writes.Fresh independent Claude Code print review (claude-opus-5-5) APPROVE exact
2e19f3e03b8489835b105c767bfd6fad6fa81add; CI158 all required and Docker jobs success. The reviewer read source independently and did not run tests; exact-headCI supplies execution evidence. Source-only: no release/tag, credential/scope/profile changes, production mailbox writes or deployment. Release remains gated on Lucy caller/allowlist migration with a serialized durable created-ID/generation ledger and the disposable live Stalwart acceptance matrix, including normalization, race/unknown outcomes and Trash retention. Existing Lucy-own sends are outside this draft workflow and unchanged.86e2a8c9842e19f3e03b