Parent
Part of #25 (Screen Solver v1: implementation spec), itself under the map #1.
What to build
What the app does, specifically, for each way things can go wrong beyond the plain happy path — so a user always gets an honest answer about app health, not silence or a stuck spinner. This layers the full failure taxonomy from the spec on top of the basic solve loop:
| Condition |
Spends a call? |
Surface |
| Window gone/unresolvable, minimized/off-desktop, black/zero-size frame |
No |
Silent — button flash only, no SSE event |
Bail (# No exercise on screen) |
Yes |
Normal done stream, low-emphasis in the client |
| Auth rejection (key revoked after startup) |
Yes |
error{kind: 'auth'}; flips the standing status pill sticky |
| Transient error, retries exhausted |
Yes |
error{kind: 'transient'} |
| Stream dies mid-answer |
Partially |
Partial pane text stays with an appended error marker |
| Mid-run target loss |
N/A |
Deliberate pause → ignored; unexpected loss → one silent re-resolution, then fallback to the picker; renderer crash → auto-restart, escalating on repeat |
| Port-bind failure |
N/A |
Refuse to start (already covered by ticket 1) |
A standing status pill escalates silent → auto-recovering → sticky. Sticky states also print one line to the host's console. There is no push/toast/notification for anyone not currently looking at an open client — the pill only speaks to whichever client is currently open, over the existing SSE channel.
Acceptance criteria
Blocked by
#29 (Solve loop over HTTP + SSE) — this ticket layers failure handling onto that baseline.
Parent
Part of #25 (Screen Solver v1: implementation spec), itself under the map #1.
What to build
What the app does, specifically, for each way things can go wrong beyond the plain happy path — so a user always gets an honest answer about app health, not silence or a stuck spinner. This layers the full failure taxonomy from the spec on top of the basic solve loop:
# No exercise on screen)donestream, low-emphasis in the clienterror{kind: 'auth'}; flips the standing status pill stickyerror{kind: 'transient'}A standing status pill escalates silent → auto-recovering → sticky. Sticky states also print one line to the host's console. There is no push/toast/notification for anyone not currently looking at an open client — the pill only speaks to whichever client is currently open, over the existing SSE channel.
Acceptance criteria
error{kind: 'auth'}on the wire and the status pill goes sticky, staying sticky across subsequent unrelated solves until explicitly resolved.error{kind: 'transient'}and does not flip the pill sticky (auto-recovering, not sticky).Blocked by
#29 (Solve loop over HTTP + SSE) — this ticket layers failure handling onto that baseline.