aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md44
1 files changed, 44 insertions, 0 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
index 133a761..0f7181b 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
@@ -7348,3 +7348,47 @@ what a drafts folder is; they are separate readers and neither should start
importing the other.
---
+
+## 153. A draft cannot be opened for editing, so it is write-only
+
+**Observed (user, 2026-08-24).** Found the moment item 138 gave drafts a
+button: "Double clicking on a draft should open the message in the editor
+window", and "there's no edit action anywhere, a draft is useless as is".
+
+**Cause (verified in code).** `DraftStore` had a `write()` and no reader, and
+nothing anywhere opened a composer from an existing message. A draft therefore
+rendered in the message pane like ordinary mail and could never be finished.
+
+**Outcome.** `ComposeContextBuilder::forDraft()`, a `Kind::Draft` that seeds
+every field verbatim, `edit_draft` in the Message menu, and double-click.
+
+**Three things worth keeping.**
+
+**A resumed draft must own its file.** Maildir has no in-place edit, so an
+autosave writes a new file and unlinks the old; a composer that did not know
+its own path would leave the original behind and one message would become two.
+`ComposeContext::draftPath` carries it into `m_draftPath`, which the autosave
+already knew how to replace.
+
+**`MimeParser` had no `bcc` and nothing had ever needed one.**
+`MessageBuilder` writes Bcc into the draft file deliberately and says why, so a
+resumed draft that ignored it would drop every blind recipient from the message
+the user then finishes and sends, silently. That is the failure this item was
+most likely to ship.
+
+**The gate is not cosmetic.** `edit_draft` is offered only on a file inside a
+configured drafts folder, matched on the PATH: a `draft` tag is not enough,
+since notmuch surfaces the Maildir D flag as one and a message flagged by
+another client sits in the inbox. Offered on ordinary mail, the composer would
+own a file it did not write and the first autosave would DELETE a received
+message.
+
+**And a live defect found on the way, which is the reason this took as long as
+it did.** `updateComposeActions()` ran only from `onSelectionChanged`. Both
+signals fire for an ordinary click, so nothing had ever noticed; but running a
+query and setting the current index emits `currentRowChanged` ALONE, so the
+enablement was computed against the previously selected row. Measured: Edit
+draft stayed disabled on a draft selected that way, and the reply family had
+the same blind spot without a test that could see it. It is now connected to
+both signals. Reading `currentRowChanged` is safe here for the reason
+`CLAUDE.md` gives: it answers "which row is current", and no count is read.