Files
hermes-webui/docs/architecture/stable-assistant-turn-anchor-phase0.md
T

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:

  1. event_id
  2. run_id + seq
  3. session_id + local_id as 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.