59 lines
3.5 KiB
Markdown
59 lines
3.5 KiB
Markdown
# Quality gates — TUI visual mode
|
||
|
||
Gates for the library paint-select visual mode (architecture/visual-mode.md).
|
||
Automatic tests live in `cbd-tui/src/app/bindings.rs` (table) and
|
||
`cbd-tui/src/app/mod.rs` (dispatch/paint). LLM gates are read-and-reason checks.
|
||
|
||
## Automatic tests
|
||
|
||
- **T1 `spectrum_moved_off_v_to_f`** (bindings) — `lookup(Global-ish, f)` →
|
||
`ToggleSpectrum` in both foci; `v`/`V` no longer resolve to `ToggleSpectrum`.
|
||
- **T2 `v_and_V_enter_visual_in_library_only`** (bindings) — `v` (NONE) and `V`
|
||
(SHIFT, and SHIFT-normalized) → `LibraryVisualMode` when the library is
|
||
focused; both → `None` when the queue is focused.
|
||
- **T3 `chords_are_unique_within_scope`** (existing) still passes with the new
|
||
bindings (no duplicate `(scope, code)`).
|
||
- **T4 `visual_enter_toggles_current_mark`** (dispatch) — from a clean library,
|
||
`LibraryVisualMode` marks exactly the selected (queueable) row and sets visual
|
||
active.
|
||
- **T5 `visual_move_paints_swept_range`** (dispatch) — `LibraryVisualMode` then
|
||
N× `LibraryNext` marks the starting row plus each row moved onto (N+1 marked);
|
||
a `LibraryLast`/jump marks the whole span to the end.
|
||
- **T6 `visual_back_sweep_unpaints`** (dispatch) — after painting down, a
|
||
`LibraryPrev` toggles the re-entered row off (marks shrink by one).
|
||
- **T7 `visual_exit_keeps_marks`** (dispatch) — a second `LibraryVisualMode` (and
|
||
separately `Esc`/`ClearSearch`) deactivates visual mode while the marked set is
|
||
unchanged.
|
||
- **T8 `visual_non_move_action_exits_then_runs`** (dispatch) — with visual active,
|
||
an action like `LibraryQueueAppend` deactivates visual and still performs
|
||
(marks consumed as usual).
|
||
- **T9 `visual_exits_on_node_or_focus_change`** (dispatch) — `LibraryDive`,
|
||
`LibraryAscend`, and `CycleFocus` deactivate visual mode.
|
||
- **T10 `paint_respects_is_queable`** (dispatch or library) — sweeping over a
|
||
non-queueable row leaves it unmarked (same gate as `s`).
|
||
- **T11 `esc_in_visual_only_exits_visual`** (dispatch) — with a `/` filter active
|
||
*and* visual active, `ClearSearch` (`Esc`) exits visual without clearing the
|
||
filter; with visual inactive it clears the filter as before.
|
||
|
||
## LLM quality gates (read-and-reason)
|
||
|
||
- **G1 — no new state leaks.** Visual mode is one `bool` on `Library`; no wire
|
||
type, proto, or server call is added. Movement, marks, and `select` are reused,
|
||
not duplicated.
|
||
- **G2 — `select` stays pure.** Painting is never done inside `Library::select`,
|
||
so filter re-selection and `update_selection` never toggle marks; painting only
|
||
happens on explicit movement dispatch while visual is active.
|
||
- **G3 — dispatch routing is exhaustive and safe.** Every `Action` either
|
||
participates in visual mode (the six movements + `LibraryVisualMode` +
|
||
`ClearSearch`) or deactivates it before running; no action can leave visual
|
||
mode active across a node/focus change or a mark-consuming op.
|
||
- **G4 — bindings stay the single source of truth.** The moved spectrum key and
|
||
the new `v`/`V` come only from `BINDINGS`; help text and key labels derive from
|
||
it (no hard-coded key strings in the help modal).
|
||
- **G5 — filter/view correctness.** `paint_between` sweeps *view* indices and maps
|
||
each through the active `/` filter to its real index (like `toggle_mark`), so
|
||
only visible rows are painted and no real index is toggled twice per step.
|
||
- **G6 — indicator + docs.** The library title shows `— VISUAL` while active, and
|
||
the help modal lists `v`/`V` (visual) and the moved `f` (spectrum) with clear
|
||
descriptions.
|