summaryrefslogtreecommitdiffstats
path: root/docs/superpowers/plans
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers/plans')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md95
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md41
2 files changed, 97 insertions, 39 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 ba8b99e..e6c7840 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
@@ -5101,3 +5101,98 @@ keep resetting the account.
Kept in full because the cause, the comment defending the reset, and the rules
preview that motivated it are all still true of the code.
+
+## 93. The query buttons are whatever the user pinned, not a designed set of filters
+
+**Observed (user, 2026-08-15),** reached by explaining item 90 rather than from
+the notes:
+
+> The queries that show as buttons shouldn't be in the same league as the ones I
+> write and store in the "more queries" menu. If I see "Unread" as a button, I
+> read it as "filter all my mails and show me only what is not yet read", but
+> being a button, in my head it should cooperate with other UI elements. So if a
+> dropdown offers to select an account, that same button should work with that
+> selection transparently, not fight it.
+
+**Cause.** Nothing ships as a default. `Config::startupSavedQuery()` falls back
+to `m_savedQueries.first()` and a fresh install has an empty query row, so every
+button the user has is one they wrote into `[queries]` and that the queries.json
+migration pinned (`src/config.cpp:455`). The buttons became "whatever is pinned"
+by migration, never by design. The user's own words: "that's the direction I
+wanted from the start, we drifted to what is today".
+
+**Approach.** Four built-in filters, Unread, Inbox, Flagged and Sent, as
+generated entries in the closed set `kQueryGenerators` that already exists for
+Sent. They compose with the account dropdown; saved queries keep setting the
+account from what they stored. The user's own pinned queries are UNPINNED once
+the buttons are confirmed working, never deleted, so they fold into the menu and
+stay recoverable.
+
+**Absorbs item 90.** The button that clears the account selection stops being a
+saved query at all, so there is nothing left to fix in `runSavedQuery()`.
+
+**Specified in `specs/2026-08-15-builtin-filters-design.md`.** Three constraints
+worth knowing before opening it: a generator must answer PER ACCOUNT rather than
+having its all-accounts query wrapped in a scope, or Sent double-scopes and works
+only by accident of `path:` being hierarchical; Sent stays `flat` and the other
+three do not, so the four match in scope and not in view mode; and changing the
+account deliberately runs nothing, since the button is the verb.
+
+**Size: M.**
+
+**Closed 2026-08-15, unreleased.** Four built-in filters ship as generated
+entries in `kQueryGenerators`, resolved through a new
+`Config::resolvedQuery(query, accountKey)` that asks a generator for the
+ACCOUNT'S OWN query rather than wrapping its all-accounts one. `runFilter()`
+reads the account box and never writes it, which is the whole of item 90;
+`runSavedQuery()` still sets the account from what the entry stored, because a
+saved query is a destination.
+
+Three things worth keeping.
+
+The Sent trap the spec predicted is real and the tests assert on the query
+STRING because of it: wrapping gives `path:"a/**" and (path:"a/Sent/**" or
+path:"b/Sent/**")`, which returns the right rows because `path:` is
+hierarchical, so a row-count assertion passes against the wrong query. The
+mutation putting the wrap back fails two tests.
+
+Migration unpins and never deletes, in both directions: Sent is no longer
+migrated out of the INI at all, and a stored entry naming a known generator is
+unpinned on load, which is what every install upgraded through 0.19.0 carries.
+The user unpinned their own queries by hand, as they had asked to.
+
+A rendering probe had to be fixed rather than adapted, and it is the documented
+failure mode. `replyRowsKeepTheirTextUnderTheThreadLine` sized the window to
+300px; four more buttons pushed the reply row below the viewport, the pixel loop
+ran zero times, and it reported "0 pixels, the row was painted over", which is a
+different defect from the one it exists to catch. It has 600px and a guard
+asserting the row is inside the viewport, verified by putting 300 back: it now
+names the row at 83..165 in an 82px viewport.
+
+## 95. A query in the overflow menu cannot be run
+
+**Observed (user, 2026-08-15),** hand testing item 93:
+
+> now no entry in that menu is runnable, they all look like submenus and offer
+> all options to edit, show as buttons, etc.
+
+**Cause, and it is NOT item 93's.** `buildSavedQueryRow` gave each menu entry
+both a `triggered` connection and a submenu of edit actions. **Qt emits no
+`triggered` for an action that owns a menu**: clicking the entry opens the
+submenu and does nothing else, so that connection had never fired, in any
+release that had an overflow menu.
+
+It went unnoticed because the menu was the rarely-used half while the user's
+queries were pinned buttons. Item 93 moved every query into the menu, which is
+how it surfaced, and item 94 makes the menu their only home, so this is now the
+path that has to work.
+
+**Closed 2026-08-15, unreleased.** Running is an item INSIDE the submenu, first
+and above a separator, with Edit, the pin toggle and Delete below it. The entry
+keeps its submenu, because an unpinned query must not become the one thing that
+cannot be edited or deleted.
+
+The test asserts the Run item exists, that it is first, that triggering it
+reaches the query, and that the edit actions survived beside it. Restoring the
+old wiring fails it on the first of those and names the Qt behaviour rather than
+reporting a wrong query string.
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 884c56b..c02de31 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
@@ -157,7 +157,8 @@ taking that too literally.
| 90 | A saved-query button clears the account selection | workflow | S | **folded into 93** 2026-08-15. Not fixed in place: the button that misbehaves stops being a saved query at all. See `specs/2026-08-15-builtin-filters-design.md` |
| 91 | Double-clicking a thread could open it in its own window | workflow | ? | open, unspecified; the user marked it "(?) UX not sure" |
| 92 | Nothing distinguishes a tag written by a rule from one the user applied | information | ? | open, unspecified; the user asked it as a question, and the answer decides whether it is a display item or a format change across two repos |
-| 93 | The query buttons are whatever the user pinned, not a designed set of filters | workflow | M | open, specified 2026-08-15; see `specs/2026-08-15-builtin-filters-design.md`. Absorbs item 90. Four built-in filters that compose with the account dropdown |
+| 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 |
Sizes are rough: XS under an hour, S a sitting, M a session.
@@ -547,44 +548,6 @@ work.
- Do not restore the pre-0.16.0 behaviour by making the delay negative for the
user. `auto_sync_delay_ms` is theirs to set.
-## 93. The query buttons are whatever the user pinned, not a designed set of filters
-
-**Observed (user, 2026-08-15),** reached by explaining item 90 rather than from
-the notes:
-
-> The queries that show as buttons shouldn't be in the same league as the ones I
-> write and store in the "more queries" menu. If I see "Unread" as a button, I
-> read it as "filter all my mails and show me only what is not yet read", but
-> being a button, in my head it should cooperate with other UI elements. So if a
-> dropdown offers to select an account, that same button should work with that
-> selection transparently, not fight it.
-
-**Cause.** Nothing ships as a default. `Config::startupSavedQuery()` falls back
-to `m_savedQueries.first()` and a fresh install has an empty query row, so every
-button the user has is one they wrote into `[queries]` and that the queries.json
-migration pinned (`src/config.cpp:455`). The buttons became "whatever is pinned"
-by migration, never by design. The user's own words: "that's the direction I
-wanted from the start, we drifted to what is today".
-
-**Approach.** Four built-in filters, Unread, Inbox, Flagged and Sent, as
-generated entries in the closed set `kQueryGenerators` that already exists for
-Sent. They compose with the account dropdown; saved queries keep setting the
-account from what they stored. The user's own pinned queries are UNPINNED once
-the buttons are confirmed working, never deleted, so they fold into the menu and
-stay recoverable.
-
-**Absorbs item 90.** The button that clears the account selection stops being a
-saved query at all, so there is nothing left to fix in `runSavedQuery()`.
-
-**Specified in `specs/2026-08-15-builtin-filters-design.md`.** Three constraints
-worth knowing before opening it: a generator must answer PER ACCOUNT rather than
-having its all-accounts query wrapped in a scope, or Sent double-scopes and works
-only by accident of `path:` being hierarchical; Sent stays `flat` and the other
-three do not, so the four match in scope and not in view mode; and changing the
-account deliberately runs nothing, since the button is the verb.
-
-**Size: M.**
-
## 94. `pinned` has nothing left to decide once the buttons are built-in
**Observed (user, 2026-08-15),** thinking past item 93 rather than from the