3.4 KiB
Stable Assistant Turn Anchors Phase 0 Inventory
This inventory implements the first non-visual slice of
stable-assistant-turn-anchors.md.
It documents the current per-turn state layers and the event-shape contract that
future anchor phases must consume. It does not claim that anchors are wired into
streaming or rendering yet.
State Layers
| Layer | Current surface | Phase 0 anchor policy |
|---|---|---|
| RuntimeAdapter / run-journal Event Envelope | event_id, run_id, seq, Last-Event-ID / after_seq |
Preferred identity and replay dedupe source. |
| Run journal replay events | read_run_events(), _replay_run_journal, runtime_journal_snapshot |
Durable replay hydration source before browser caches. |
| Server settled transcript | /api/session messages and metadata |
Settlement updates final answer and terminal state on an existing turn. |
S.messages |
Browser transcript projection consumed by renderMessages() |
Projection/cache, not a second semantic owner. |
INFLIGHT |
Browser recovery cache and persisted localStorage state | Recovery fallback only; does not outrank journal or settled transcript. |
| Stream closure state | attachLiveStream() local assistant text, reasoning text, parser target, tool state |
Hot-path write buffer; future phases normalize this into anchor events. |
| Live DOM | #liveAssistantTurn, Worklog rows, tool cards, Thinking cards |
Renderer output only; DOM survival is not semantic truth. |
The same inventory is encoded in static/assistant_turn_anchors.js as
HermesAssistantTurnAnchors.stateLayers so tests can pin the current authority
order.
Slice 2 Normalizer Helper
HermesAssistantTurnAnchors.normalizeAssistantTurnAnchorSourceEvent() converts a
single current source event into a normalized anchor event envelope without
registering it, rendering it, or mutating browser state. It accepts live SSE-like
events (type, data, lastEventId), replay/journal-like events (event,
payload, event_id, seq), and settled/session payload events such as
settled_message.
HermesAssistantTurnAnchors.normalizeAssistantTurnAnchorSourceEvents() applies
the same helper to a list and dedupes repeated live + replay observations by the
same event-envelope key. This is still inert: send(), attachLiveStream(),
renderMessages(), settlement restore, S.messages, INFLIGHT, and the DOM do
not consume the helper yet.
Source Event Classification
Phase 0 classifies current sources before changing render behavior:
- activity:
token,interim_assistant,reasoning,tool,tool_complete,tool_update,compressing,compressed,approval,clarify,pending_steer_leftover,goal_continue,done,cancel,error,apperror - artifact:
artifact_reference - side effect:
state_saved - metadata:
usage,title,settled_message,runtime_journal_snapshot,inflight_snapshot - transport:
stream_end
Future phases may add sources, but every source must choose one of these classes
or explicitly mark itself excluded.
Dedupe Invariant
Anchor event dedupe is intentionally independent of visible text and timestamps. The Phase 0 helper uses this order:
event_idrun_id + seqsession_id + local_idas a browser fallback
This mirrors the RuntimeAdapter Event Envelope and keeps the browser aligned with run-journal replay while the anchor registry is still unwired.