TUI recovery states¶
P4 applies the empty-state and notice recipes using the generated lipgloss roles. Conditions have one bold row, explanation and the next action use body ink, and empty rail sections reserve no rows.
These are deterministic app-model driver captures, not recordings of a live
daemon. app/recovery_test.go drives the real home.Update and home.View
paths, injects rejected mutations, and checks that session and task input
survives. The SVGs faithfully convert the resulting ANSI cell grid. Matching
SVG and ANSI goldens in app/testdata/recovery are both compared byte-for-byte
by TestRecoveryDriverScenes, making geometry, copy, weight, colour and terminal
escape sequences reviewable in tests. The 14 scenes in both themes have 28
.svg/.ansi pairs. Existing surrounding TUI chrome is outside P4.
The same test also requires every gallery .svg and .ansi under
docs/assets/recovery/tui-model-driver to match its asserted golden byte-for-byte.
The zero-task and task-load-failure scenes keep the task manager's Tasks
title and a pinned n new · esc back hint containing only live actions.
| State | Light | Dark |
|---|---|---|
| Zero sessions | ||
| No project registered | ||
| Zero tasks | ||
| Zero accounts | ||
| Remote accounts; login refused | ||
| Tasks unavailable | ||
| Projects unavailable | ||
| Cannot reach the daemon | ||
| Failed session create | ||
| Failed archive | ||
| Failed kill | ||
| Failed task save | ||
| Failed existing task save | ||
| Too-small terminal |
The complementary real tmux driver runs
inside the isolated testbox with a cheap bash stand-in. It starts with no
sessions, opens the empty task manager, submits a create rejected by the real
daemon, verifies the name remains in the form, changes its backend, and reaches
a live interactive terminal with FIRST_SESSION_REACHED echoed. It then checks
the too-small-terminal screen. Its captured terminal text
is real application evidence; it does not assert agent authentication or agent
responses. No host AF home, daemon, app process or account is used.
Mutation recovery screens persist until one key returns to the retained state; the key is consumed so dismissing a failure cannot accidentally submit or delete. An async create failure while another form is open preserves that newer form and retains the failed draft for the next create in its original project. Background snapshot failures retain loaded sessions and retry automatically.
To verify, run scripts/testbox.sh test ./app -run 'TestRecovery' -count=1 and
scripts/testbox.sh scenario scripts/tui-3915-scenario.sh. To recapture, set
AF_TUI_RECOVERY_CAPTURE to an output directory inside the testbox and run
the recovery tests. Capture mode writes both <scene>-<theme>.svg and
<scene>-<theme>.ansi and skips golden comparisons. Inspect every SVG and ANSI
diff before replacing both halves together under app/testdata/recovery.
Both the SVG and ANSI gallery copies are generated from those
goldens by scripts/gen-docs.sh and gated for drift in CI, so run that script
and commit its output rather than copying either format across by hand.
The test rejects a stale or missing gallery copy in either format. Keep the
.gitattributes ANSI whitespace rule: cell padding and trailing viewport rows are
part of the asserted frame. Verify again without AF_TUI_RECOVERY_CAPTURE so the
test checks the committed pairs.