aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md46
1 files changed, 45 insertions, 1 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
index c0c1c1e..656773b 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
@@ -100,7 +100,7 @@ taking that too literally.
| 41 | A message whose HTML body carries a `Content-Id` renders blank | correctness | S | **done** |
| 42 | "Syncing..." says nothing about what is being synced | feedback | S | **done** |
| 43 | No "Mark all read" for the current view | workflow | S | **done** |
-| 44 | No way to manage the filters applied at sync time | workflow | M | open, specified 2026-08-12; see `specs/2026-08-12-tagging-rules-design.md`. Spans this repo and `mailctl` |
+| 44 | No way to manage the filters applied at sync time | workflow | M | **done** 2026-08-13; see `specs/2026-08-12-tagging-rules-design.md`. Spans this repo and `mailctl` |
| 45 | Two Sync buttons, and only one of them works properly | correctness | S | **done** |
| 46 | `uiStateSurvivesARestart` fails under the offscreen platform | testing | XS | **done** |
| 47 | The query bar looks unfinished, and cannot be cleared by mouse | presentation | XS | **done** |
@@ -3040,6 +3040,50 @@ A filter engine that rewrites the Maildir would not violate that literally, but
it would put qtmaildir in the business of moving mail, which is a decision to
take deliberately rather than by implementing a dialog.
+### Outcome (done 2026-08-13)
+
+The rules moved from the shell `post-new` hook to
+`~/.config/mailrules/rules.json`, read by both qtmaildir and `mailctl`. The
+hook and the shared `mailrules.py` live in the mailctl repository; this repo
+has `TagRules`, `tests/test_tagrules.cpp`, a management dialog on the Message
+menu, and `NotmuchWorker::requestMessageCounts` for the dry run. Seventeen real
+rules were converted and each one's shell comment became its `note`.
+
+**Four things learned that outlive the item.**
+
+The parenthesisation of a rule's own query is load-bearing. `tag:new and a or b`
+binds as `(tag:new and a) or b`, so a rule that is a disjunction of senders
+escapes its scope and matches the whole corpus. Several real rules have exactly
+that shape. `mailrules.scoped_query` is the only place that string is built.
+
+The hook must not consume `tag:new` when the rules failed to load. Clearing the
+marker while the rules did not run orphans that mail permanently and silently,
+and the gap would surface months later as "why did this stop being tagged".
+
+**notmuch's query parser rejects almost nothing**, which invalidated two
+assertions written into the plan from memory. `from:((((` parses cleanly and
+matches nothing rather than failing, so a test expecting a non-zero exit or a
+`-1` count fails against correct code. `tests/test_notmuchworker.cpp` already
+recorded this for thread counts and the lesson had to be learned twice.
+
+`requestCounts` counts THREADS, which is right for the placeholder pane and
+wrong for a rule: a rule tags messages, so a thread count understates any rule
+matching part of a large thread. Hence `requestMessageCounts` beside it rather
+than a change to it.
+
+**Verification, since a rules file that tags the wrong mail is expensive.** All
+seventeen converted rules were counted against the real index and matched the
+shell hook exactly, tags and counts, before anything was installed. The staged
+hook was then run against real mail with a tag deliberately removed, and
+restored it. The live swap was confirmed by a real sync: `status=OK`,
+`applied 17 rule(s)`, marker consumed, and the per-rule counts moved as new mail
+arrived.
+
+**Backfill remains out of scope**, and is the piece that will force a revision
+to the "no destructive-action confirmation, undo instead" rule in `CLAUDE.md`.
+The user has said that rule is due for revision anyway. See the spec's "Out of
+scope" section.
+
## 45. Two Sync buttons on the main window
**Observed (user, 2026-08-05):** "there's currently 2 Sync buttons on the main