Skip to content

docs(design): daemon side-channel coordination (A1/A2/A4/A5)#4511

Open
chiga0 wants to merge 2 commits into
mainfrom
docs/daemon-sidechannel-coordination-design
Open

docs(design): daemon side-channel coordination (A1/A2/A4/A5)#4511
chiga0 wants to merge 2 commits into
mainfrom
docs/daemon-sidechannel-coordination-design

Conversation

@chiga0

@chiga0 chiga0 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

What this is

A design-first, docs-only proposal for the A-series follow-ups surfaced by the cross-client real-time sync audit and the PR #4484 post-merge review. No implementation — it defines the approach so it can be reviewed before any code lands. Each item ships as its own implementation PR after this is approved.

The bugfix/cleanup follow-ups from the same review (epoch-reset resync, approval-mode serialization, cancel dedup, forward-failure signal, replay wire rename, Provider catch-up) are separate and already in review.

The four gaps

  • A1 — in-session model switch never reaches the bus. /model, plan-mode, or agent-internal switches call config.switchModel() directly and emit nothing; only the HTTP route broadcasts. Proposal: a current_model_update sessionUpdate (mirrors the existing current_mode_update), mapped by the bridge to the existing model_switched event, with HTTP + in-session converged on a single emitter to avoid double-broadcast.
  • A2 — in-session approval-mode change emits no event. setMode calls config.setApprovalMode() without notifying. Proposal: emit current_mode_update from setMode; affirm and explicitly document the session-scoped (always) vs workspace-scoped (persist-only) broadcast split with a scope discriminator.
  • A4 — permission_resolved originator/voter ambiguity. Its originatorClientId carries the voter, while permission_request's carries the prompt originator. Proposal: add a canonical voterClientId alias (non-breaking, same pattern as the accepted lastReplayedEventId rename); SDK prefers it.
  • A5 — no side-channel snapshot on attach. A reconnecting client gets transcript replay but must separately pull current mode/model/commands/pending-permissions. Proposal: an opt-in session_snapshot frame emitted before replay so a fresh attach renders correct state without extra round-trips.

Why

These are the remaining "a state change on one path is invisible to other clients" gaps. Closing them gives the daemon a single coordination invariant: every model/approval-mode/permission transition broadcasts exactly once regardless of entry path, and a fresh attach can reconstruct side-channel state without out-of-band pulls.

Contents

Per-item problem (with code anchors), proposed design, alternatives, wire-compat, and risk; cross-cutting single-emitter and additive-alias patterns; proposed sequencing (A4 → A1+A2 → A5) and a test plan.

Requesting design review before implementation.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants