Failure screens, reconnect toast, and the WAITING state #15
Labels
No labels
needs-info
needs-triage
ready-for-agent
ready-for-human
v2
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wayfinder:ticket
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
aiko/denpa#15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What to build
Every fault gets the same six-part structure (card 5a), varying only in whose problem it is: degraded station bar with a status word, a texture block, a headline in her voice about what she cannot do — never an error code, the two-hop chain with a one-line reason per hop, a folded 詳細 reveal holding the real error and the likely causes, and one primary action right for this fault plus a secondary that is never a dead end.
Five faults:
6d matters most — it is the only fault where she still works. It must degrade to text, explicitly confirming that 文字入力 · TTS · 自発送信 stay live while 常時受信 · 押して送信 stop.
Also in this slice: 7c reconnect toast — cyan, three seconds, no button, and it names the gap length because that is the only useful fact. No "reconnected successfully", no checkmark. If cron fired while dark it turns acid and offers 読む — she does not replay them out loud. And 7d WAITING: the meter holds the idle floor, the PTT key goes dark reading 受け取った, 割り込み dims because there is nothing yet to interrupt.
Design reference:
docs/design/denpa-receiver/README.md(card ids1a,4a… index intoDenpa Receiver.dc.html, openable in a browser).Acceptance criteria
Blocked by
Reality audit
Governing rule: build to reality, Hermes leads. Not doing something is acceptable if it does not break core functionality. Breaking the design is acceptable. Building UI that does nothing is not.
Audited against the actual wire surface:
hermes-agent 0.19.0, verified running):/health,/v1/models,/v1/runs,/v1/runs/{id},/v1/runs/{id}/events,/v1/runs/{id}/stop,/v1/runs/{id}/approvalmessage.delta,tool.started,tool.completed,run.completed,run.cancelled,run.failed/run.errored,reasoning.available,approval.request(carries a per-requestchoicesarray and sets run statuswaiting_for_approval; the go-between discards it today — see #19)full-text,audio,control,error,set-model-and-conf,config-switched,config-files,background-files,history-list,history-data,new-history-created,history-deleted,user-input-transcription,backend-synth-complete,force-new-message,tool_call_status,interrupt-signal,heartbeat-ack,group-updatetext-input,mic-audio-data,mic-audio-end,raw-audio-data,ai-speak-signal,interrupt-signal,fetch-history-list,fetch-and-set-history,create-new-history,delete-history,fetch-configs,switch-config,fetch-backgrounds,audio-play-start,request-init-config,heartbeatOne of five faults degrades; the rest are real
set-model-and-conf/config-files.errormessage. Its headline and structure survive; what changes is that it can only appear after she tries and cannot answer.Consequence to honour: the 詳細 reveal shows the real error text the go-between sent. Do not invent likely-cause lists the client cannot substantiate — if the error says only that the run failed, say that.
The reconnect toast (7c) is real: socket-derived, and the gap length is genuinely knowable. Its acid variant (missed unprompted turns) depends on #22 and should not ship before it.
7d WAITING is real and unaffected.
The acid reconnect toast's dependency changed shape
This issue notes the acid variant (missed unprompted turns) depends on #22. Still true, but what it depends on has changed twice and has now settled.
ollvt-hermes-bridge#16chose a Hermes Platform adapter pushing to the go-between, not the go-between polling cron output. So missed-broadcast recovery is not "read the unread output files" — Hermes owns the queue, coalesces per job id (a cron that fired twelve times while the client was dark surfaces once, marked12x), applies a staleness bound, and drains on reconnect.For this slice that means the toast announces what is about to drain, rather than reconstructing history from a log. Which is the lighter build, and it keeps the existing criterion — "Missed unprompted turns are offered to read, never replayed as audio" — intact.
Also relevant to 6d, the fault where she still works: the claim that 自発送信 stays live is only true once the adapter lands. Until then there is no unprompted path at all, so 6d's copy should not promise one.
Unrelated correction: this issue's endpoint audit lists
POST /v1/runs/{id}/approval, and it was right — 承認 has a complete data path and was wrongly filed as deferred. Now tracked as #26. Nothing in this slice changes, but the 5a/6x screens should not treat a suspended run as a failure;waiting_for_approvalis alive.Ruled out of scope for v1 on the wayfinder map, the conversation works (v1). Labelled
v2; staying open rather than closed, because the scope call lives on the map and this is still real work.v1 is: a real voice conversation — you speak, she answers in her own voice, Live2D renders, the log records it — on the Windows desktop, the OnePlus Pad and an Android phone, for one operator on hardware they already own.
The text path is split out into #53 and pulled into v1. This issue keeps the rest and stays
v2.Why the split: walking onboarding on the desktop app on 2026-07-30 hit exactly the dead end this issue's own text forbids —
Both mic keys raise a VAD permission dialog, the desktop push-to-talk hotkey never registers (
#51), and there is no text input anywhere in the receiver chrome. So the only way into the product is a microphone that does not work, and the escape hatch this issue specifies was never built.The escape hatch is separable from the taxonomy, and far cheaper:
websocket_handler.py:72already handlestext-input,pairing.ts:75already sends it, and a real turn crossed on it today. Only the compose surface is missing.What stays here: 6d itself —
耳を塞がれてる, the flatlined無音 — 権限なしmeter,設定を開く— and every other failure screen, including the WAITING treatment.Two more pieces split out, on the operator's call, 2026-07-30. This issue keeps the five fault screens and the reconnect toast.
error.websocketNotOpenuntil it was relaunched, and it happens on every restart.Previously split: #53, the compose surface — 6d's
文字で話す, which turned out to be the only way to reach her without a microphone.Two of the remaining faults have gone stale, and should not be built as written
鍵が合わない/鍵を入れ直すdescribes a key the operator types. ADR-0011 removes that model: devices enrol with the go-between and present a long-lived per-device token, so an auth failure means this device is no longer enrolled, and the action is to re-enrol, not to re-enter a key. Build it with#26/#40, or it will be a screen for a mechanism that no longer exists.姿を選ぶassumes a model picker.#52establishes that 姿 currently offers character-config bundles whose personas are dead, and that the picker needs rebuilding againstmodel_dict.json. This screen's primary action does not exist yet in the form it assumes.Both are recorded here rather than split, because they are still fault screens — they just cannot be written correctly until the mechanisms they act on are settled.
What remains genuinely ready in this issue: 6a socket won't open, 5a upstream down (already downgraded by the reality audit to a post-failure state built from the
errormessage), and the reconnect toast itself once #57 gives it a gap length to name.Split into a v1 slice and this remainder, on the operator's call, 2026-07-30. This issue stays
v2.#59 takes 6a (socket will not open) and 5a (she could not answer) — the two faults that are buildable today and that you hit simply trying to use her. It takes them at the fidelity v1 needs: which hop broke, her words not an error code, the real error text under
詳細, one action that is not a dead end.What stays here, and why each cannot be built correctly yet:
鍵を入れ直すdescribes typing a key ADR-0011 removes. Build with#26/#40.姿を選ぶassumes a picker#52establishes needs rebuilding.#57, which is the behaviour underneath it.Everything split from this issue so far: #53 compose surface, #57 reconnect, #58 WAITING, and now #59.