Problem
Reported by: @madtank (2026-04-18 22:45)
When an agent is connected to aX via the Hermes runtime, senders get rich live feedback in the SSE stream — 'Received', 'Working…', tool counts, progress placeholders edited in place, etc. That UX is great: sender knows the message landed, knows the agent is processing, sees activity.
When an agent is connected via other harnesses (specifically Claude Code via the ax-channel MCP bridge), there is nothing. Radio silence from message send until the final response arrives. If the Claude Code session is dead, stalled, or backlogged, the sender has no way to know.
This inconsistency makes every non-Hermes harness feel broken, and breaks trust that 'the agent is listening.'
Expected
Any agent harness plugged into aX — Hermes, Claude Code MCP bridge, ax-cli local listener, future third-party harnesses — should emit a minimum set of tool-level signals back to the sender so:
- 'Received' ack fires within <500ms of message arrival. Confirms: listener is online, connected to aX, subscribed to this agent's inbox.
- 'Processing' / 'queued' state follows within seconds. If the agent is currently busy with N prior messages, surface queue depth ('10 other items ahead of this').
- AHT (average handle time) can be derived from the receive→complete pair. Surface bucketed anomalies ('this agent usually replies in ~45s; currently past 3x that').
- 'Unavailable' / 'disabled' / 'stale listener' states must also be emitted — if the listener died, senders see it immediately rather than hanging indefinitely.
Architecture layers (from the decision-tree router design)
This was sketched out earlier in the context artifact /home/ax-agent/agents/orion/drafts/cli-notification-router.svg (task 785b696d):
- Layer 1 — Transport ACK: aX platform confirms the message landed in the listener's inbox. This is backend-side.
- Layer 2 — Listener ACK: harness process confirms it pulled the message from SSE and is about to dispatch to the agent. This is the layer that's currently missing for non-Hermes harnesses.
- Layer 3 — Agent ACK: agent runtime starts processing. Hermes does this beautifully via edit-in-place 'Working…' messages.
- Layer 4 — Agent completion: final response.
Claude Code MCP bridge currently skips Layer 2 AND Layer 3 — sender sees nothing between their send and the eventual (sometimes) final reply.
Proposed fix
ax-cli channel/server.ts (the Claude Code MCP bridge) should, on receiving an SSE event that matches this agent, immediately emit a lightweight 'received' ack back into the chat (or surface via a sidebar signal, not inline text — see task 95d9eb17 runtime sidecar).
- Adopt a shared 'harness contract' across all aX-compatible runtimes: on message receipt, emit
listener.ack event; on agent dispatch, emit agent.processing event; on completion, emit agent.done event.
- Store queue depth at the harness level; expose via a public tool call so senders can query 'how backed up is @agent'.
- Expose AHT via
ax agents roster field (already designed — project_avg_response_time_feature.md).
Related / not duplicates
Why this matters
Every harness that doesn't emit these signals feels broken to users. Owner (@madtank) observed this daily with Claude Code vs Hermes sentinels. Inconsistency also discourages future third-party harness integrations — they'll look at Hermes's rich UX and wonder how to match it.
Scope
This is a protocol / contract issue, not just a Claude Code bug. Worth landing as a harness-contract spec first (or a decorator / wrapper in ax-cli core that any harness can import to get the signals for free), then porting to channel/server.ts as the first consumer.
Opening to team
Not assigned — please pick up if you have bandwidth. Anvil already owns #74 so this is adjacent, but scope is larger than just the bridge.
Problem
Reported by: @madtank (2026-04-18 22:45)
When an agent is connected to aX via the Hermes runtime, senders get rich live feedback in the SSE stream — 'Received', 'Working…', tool counts, progress placeholders edited in place, etc. That UX is great: sender knows the message landed, knows the agent is processing, sees activity.
When an agent is connected via other harnesses (specifically Claude Code via the
ax-channelMCP bridge), there is nothing. Radio silence from message send until the final response arrives. If the Claude Code session is dead, stalled, or backlogged, the sender has no way to know.This inconsistency makes every non-Hermes harness feel broken, and breaks trust that 'the agent is listening.'
Expected
Any agent harness plugged into aX — Hermes, Claude Code MCP bridge, ax-cli local listener, future third-party harnesses — should emit a minimum set of tool-level signals back to the sender so:
Architecture layers (from the decision-tree router design)
This was sketched out earlier in the context artifact
/home/ax-agent/agents/orion/drafts/cli-notification-router.svg(task785b696d):Claude Code MCP bridge currently skips Layer 2 AND Layer 3 — sender sees nothing between their send and the eventual (sometimes) final reply.
Proposed fix
ax-cli channel/server.ts(the Claude Code MCP bridge) should, on receiving an SSE event that matches this agent, immediately emit a lightweight 'received' ack back into the chat (or surface via a sidebar signal, not inline text — see task 95d9eb17 runtime sidecar).listener.ackevent; on agent dispatch, emitagent.processingevent; on completion, emitagent.doneevent.ax agentsroster field (already designed — project_avg_response_time_feature.md).Related / not duplicates
785b696d— CLI as local notification-processing layer + decision tree router (has the SVG artifact).74961638— agent messages show same status indicators as user messages (this is the UI half).95d9eb17— agent runtime sidecar (expandable per-message tool/plan/queue panel).a55c85f6— activity triage CLI.dc65c1cd— heartbeat freshness (implicit heartbeat from message sends).Why this matters
Every harness that doesn't emit these signals feels broken to users. Owner (@madtank) observed this daily with Claude Code vs Hermes sentinels. Inconsistency also discourages future third-party harness integrations — they'll look at Hermes's rich UX and wonder how to match it.
Scope
This is a protocol / contract issue, not just a Claude Code bug. Worth landing as a harness-contract spec first (or a decorator / wrapper in ax-cli core that any harness can import to get the signals for free), then porting to channel/server.ts as the first consumer.
Opening to team
Not assigned — please pick up if you have bandwidth. Anvil already owns #74 so this is adjacent, but scope is larger than just the bridge.