summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md48
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md3
2 files changed, 50 insertions, 1 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 1704a28..d5f58dd 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
@@ -5290,3 +5290,51 @@ defect when `QT_TRANSLATE_NOOP` is reverted to `QT_TR_NOOP`.
**Not done:** no language-selection UI, and no second language. `QLocale()`
reading the environment is how a Linux desktop already chooses; add a selector
when there is something to choose between.
+
+## 96. A query returning the thread already on display opens onto the placeholder
+
+**Observed (user, 2026-08-15, with two screenshots):** an `id:` query produces
+exactly one card, the status bar reports "1 thread selected (1 message)", the
+card paints as selected, and the message pane stays on the placeholder. Two
+different messages from two different providers, with and without an account
+selected.
+
+**Filed originally as the unverified half of item 66** and assumed to be the
+same empty-`MessageIdRole` failure. It is not, and that assumption is what kept
+it open: 66's fix was correct and this reproduced against it.
+
+**Cause (verified in code and by instrumented run):** `runQuery()` blanks the
+message pane but leaves `m_currentThreadId`, `m_currentMessageId` and
+`m_currentMessageThreadId` naming the thread that was showing. Both selection
+handlers compare a newly selected row against those to decide whether it is
+already displayed, so a result containing that same thread is recognised as
+"already showing" and `onThreadSelected()` is never called. An instrumented run
+printed `currentThreadId after runQuery: "0000000000000001"` against an
+identical row thread id with the pane on the placeholder.
+
+**Why an `id:` query and nothing else.** The id is copied out of the details
+dialog of the message being read, so that thread is current at the exact moment
+the query replaces the view. Any query returning a different thread hides the
+fault completely, which is why it survived from 2026-08-04 to 2026-08-15 and
+why the first version of the regression test passed against it.
+
+**Four hypotheses eliminated by measurement before the cause was found**, each
+of which looked likely from reading:
+
+- `MessageIdRole` empty on a fresh single-message row. The row carries the id.
+- Account scoping mangling the query. `path:"acct/**" and (id:...)` returns the
+ row, and the user reproduced it with no account selected.
+- `MimeParser` failing on the real file. A probe against it reported `ok true`,
+ 9614 bytes of plain text and 40701 of HTML.
+- The id needing quoting. Both real ids resolve bare and quoted, one of them
+ carrying a `=` before the `@`.
+
+**Fix.** Clear the three ids where the pane is blanked, in `runQuery()`. They
+describe what the pane is showing, so they cannot outlive it.
+
+**The regression test's first query must open the SAME thread the second one
+returns.** With two different threads it passes against the defect, which is
+how the first version of it was green. It asserts the ids are cleared, because
+that is the fix's contract, and then that the pane leaves the placeholder,
+which is what the user sees. Mutation check: reverting the fix fails it with
+"runQuery blanked the pane but still names a current thread".
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 e921e89..c376f6e 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
@@ -130,7 +130,7 @@ taking that too literally.
| 63 | No way to see sent mail, and no filter for it | workflow | M | **done** 2026-08-11; see `specs/2026-08-11-sent-mail-design.md` |
| 64 | The Sync button carries a mailbox icon, not a refresh one | presentation | XS | **done** 2026-08-11 |
| 65 | No full code review and optimization pass | correctness | ? | open, unspecified |
-| 66 | Selecting a thread root leaves the message pane blank until a reply has been selected | defect | S | **done** 2026-08-14, unreleased. Not the blank pane it was filed as: the root rendered the CONVERSATION until the thread had been expanded once, then one message. Now always one message, and the conversation view is removed at the user's request. **One case unverified by hand:** the notes also report a single-message `id:` query whose card would not open, which is the same empty-`MessageIdRole` failure and should be gone; confirm against an `id:` query before treating it as closed |
+| 66 | Selecting a thread root leaves the message pane blank until a reply has been selected | defect | S | **done** 2026-08-14, unreleased. Not the blank pane it was filed as: the root rendered the CONVERSATION until the thread had been expanded once, then one message. Now always one message, and the conversation view is removed at the user's request. **One case unverified by hand:** the notes also report a single-message `id:` query whose card would not open, which is the same empty-`MessageIdRole` failure and should be gone; confirmed 2026-08-15 as a SEPARATE defect with a different cause, see item 96 |
| 87 | Auto mark-read marks a whole thread, including replies never displayed | defect | S | open; measured 2026-08-14. Reachable only after 66 removed the conversation view. Blocked on 88 |
| 88 | `threadAt(current.row())` answers about the wrong thread for a reply row | defect | S | open; found 2026-08-14 by shipping a fix that marked an unrelated message read. Row numbers are per parent in a tree |
| 67 | The placeholder pane counts unread, flagged and inbox, but not sent or drafts | information | XS | **done** 2026-08-11, shipped in 0.15.0 |
@@ -160,6 +160,7 @@ taking that too literally.
| 93 | The query buttons are whatever the user pinned, not a designed set of filters | workflow | M | **done** 2026-08-15, unreleased; see `specs/2026-08-15-builtin-filters-design.md`. Absorbs item 90. Four built-in filters composing with the account dropdown; the user's own queries unpinned, never deleted |
| 95 | A query in the overflow menu cannot be run | defect | XS | **done** 2026-08-15, unreleased. Pre-existing and not caused by 93: the entry's action owned a submenu, and Qt emits no `triggered` for those, so the connection had never fired. Surfaced because 93 moved every query into the menu |
| 94 | `pinned` has nothing left to decide once the buttons are built-in | maintenance | S | open; **blocked on 93**, and deliberately not part of it. A user-visible removal: the row becomes built-ins only and every saved query lives in the menu |
+| 96 | A query returning the thread already on display opens onto the placeholder | defect | S | **done** 2026-08-15, unreleased. Split from 66's unverified half, which had a different cause. Reproduced from two screenshots after four measured eliminations |
Sizes are rough: XS under an hour, S a sitting, M a session.