Two-hop connection model — socket state vs upstream health #11
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#11
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
Decided: the go-between pushes a dedicated
upstream_statusmessage on connect and on every change, carrying the/healthresult, the agent name it saw, last-checked time, and a failure reason. Not piggybacked on an existing status message, and not polled over HTTP. Client never polls; the socket is the only transport.Every failure screen, the onboarding gate and the 局 settings tab depend on the client knowing which of two hops is broken:
client ──WebSocket──▶ go-between ──HTTP/SSE──▶ HermesToday "connected" means "the socket opened", which is why the current app can sit silently with a live socket and a dead upstream.
WebSocketContextmust carry both hops independently: local socket state, and the go-between's reported view of Hermes (/healthresult, agent name, last check, failure reason).The client never talks to Hermes directly and must never hold the Hermes bearer key — upstream status is reported by the go-between and shown read-only.
Deliver the LOADING (同調中) treatment against this: tuning static with a sweeping bar, not a spinner over an empty stage.
aiko/ollvt-hermes-bridge#17 tracks the go-between side.
Design reference:
docs/design/denpa-receiver/README.md(card ids1a,4a… index intoDenpa Receiver.dc.html, openable in a browser).Acceptance criteria
WebSocketContextexposes both hops separately, each with a status and a one-line reasonBlocked 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,heartbeatRescoped: no upstream health message exists
There is no
upstream_statusmessage and no path by which the go-between reports Hermes'' health. The earlier decision to add one stands as a request (aiko/ollvt-hermes-bridge#17 item 1), but this issue must not ship a hop indicator that is permanently "unknown".What is real today:
errormessage.HermesRunFailedErrorcarries the run''s failure reason. So the client learns the upstream is broken when a turn fails, not before.Build that, and nothing more. Two states, honestly labelled: the socket hop is live-monitored; the upstream hop is last known, stamped with when it was last proven, and unknown until the first turn.
Do not draw a live upstream indicator, a health poll, or a
/health 200readout. The client never talks to Hermes directly and has no data for any of them.LOADING(同調中) is unaffected and still ships.When the go-between grows the reporting message, the upstream hop upgrades from last-known to live with no UI change — the two-state model already accommodates it.
Closing in favour of #27, rewritten against the ADRs.
This issue's premise changed with ADR-0001: Denpa is a Hermes gateway Platform adapter and the
api_serverHTTP surface is abandoned entirely. Patching the body would have left a trail of corrections on top of a stale audit block - the same pattern that got 承認 wrongly cut once already.Decisions now live in
docs/adr/in the go-between repo (branchdocs/hermes-platform-adrs). The replacement issue references them rather than restating them.