diff options
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 46 |
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 |
