Write-Ahead Reconciliation
Clients optimistically apply their own actions locally, then reconcile when the server echoes them back alongside any concurrent actions from other clients or the server itself. This provides instant UI feedback while maintaining server-authoritative consistency.
Client-Side State
Each client maintains per-subscription:
confirmedState— Last fully server-acknowledged state.pendingActions[]— Optimistically applied but not yet echoed by server.optimisticState—confirmedStatewithpendingActionsreplayed on top (computed, not stored).
confirmedState ──► apply pending[0] ──► apply pending[1] ──► ... ──► optimisticStateThe UI always renders optimisticState. Users see their actions reflected immediately.
Reconciliation Algorithm
When the client receives an ActionEnvelope from the server:
Own action echoed (
origin.clientId === myIdand matches head ofpendingActions):- Pop from pending, apply to
confirmedState.
- Pop from pending, apply to
Foreign action (different origin or server-originated):
- Apply to
confirmedState, rebase remainingpendingActions.
- Apply to
Rejected action (server echoed with
rejectionReasonpresent):- Remove from pending (optimistic effect reverted). The
rejectionReasonMAY be surfaced to the user.
- Remove from pending (optimistic effect reverted). The
Recompute
optimisticStatefromconfirmedState+ remainingpendingActions.
Example
The homepage walks through this flow in a short, scripted demo that runs entirely in your browser: the "host" and every client mirror run through the canonical reducers, the agent and terminal output are scripted, and no network requests are made. An optimistic message renders faded until the host acknowledges it. The phone then approves a tool call and loses its connection while the host keeps going. When it reconnects, it sends one reconnect request with lastSeenServerSeq and its subscriptions, and the missed envelopes arrive in order inside the response. The client drops its pending queue and applies them to its confirmed state to converge. An opt-in detail shows the snapshot fallback for a gap too old to replay. The demo then shows automations, terminals and capability negotiation as examples of extending AHP with more channels. With reduced motion enabled, the steps are identical, but devices swap in place without sliding or zooming. The navigation's theme switch applies to the demo, device screens and the rest of the documentation; your light or dark preference persists between pages.
Time Server Client A Client B
─────────────────────────────────────────────────────────────────────────────────
t1 dispatch(turnStarted)
pending: [turnStarted]
optimistic: has activeTurn
t2 receives turnStarted from A
applies, broadcast seq=10
t3 receives seq=10 (own echo)
pop from pending
confirmed = optimistic
t4 agent produces delta
broadcasts seq=11
t5 receives seq=11 (foreign) receives seq=11
apply to confirmed apply to confirmedWhy Rebasing Is Simple
Most chat actions are append-only:
- Add turn, append delta, add tool call, append response part.
Pending actions still apply cleanly to an updated confirmed state because they operate on independent data — the turn the client created still exists; the content it appended is additive.
The rare true conflict (two clients abort the same turn) is resolved by server-wins semantics — the server's echo is the source of truth.
Reconnection
If the transport connection drops:
// Client → Server (request)
{
"jsonrpc": "2.0",
"id": 2,
"method": "reconnect",
"params": {
"channel": "ahp-root://",
"clientId": "client-1",
"lastSeenServerSeq": 42,
"subscriptions": ["ahp-root://", "ahp-session:/<uuid>"]
}
}The server MUST include all replayed data in the response. If the gap is within the replay buffer, the response contains missed action envelopes. If the gap exceeds the buffer, the response contains fresh snapshots instead. In both cases, the client resets confirmedState accordingly and clears pendingActions.
Protocol notifications (like sessionAdded/sessionRemoved) are not replayed — the client should re-fetch the session list.
Next Steps
- Actions — The action types that flow through reconciliation.
- Subscriptions — How URI-based subscriptions work.
- Lifecycle — Connection handshake and reconnection.
- Session Channel — Session creation and lifecycle.