Skip to content

feat(serve): opt-in etcd-lease presence for the daemon's live sessions#487

Merged
sahuagin merged 1 commit into
mainfrom
cc/serve-session-lease-presence
Jul 13, 2026
Merged

feat(serve): opt-in etcd-lease presence for the daemon's live sessions#487
sahuagin merged 1 commit into
mainfrom
cc/serve-session-lease-presence

Conversation

@tcovert-c137

@tcovert-c137 tcovert-c137 Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What

The mu-daemon slice of lease-backed dialogue presence — completes the trio (mu#482 server read side, agent_tools#48 cc watch holder): mu serve registers its live sessions (mu:<daemon_id>:<session_id>) plus a daemon key under one etcd lease, so mu peers show up presence:"lease" on the dialogue channel and are addressable by broadcast without ever saying/polling. Crash → the single lease expires → all the daemon's keys vanish. The lease IS the liveness proof.

Design: a reconciliation task (every TTL/3: keepalive + diff the keyspace against Sessions::live_session_ids(), a new accessor covering inner + workers and deliberately excluding rehydrated read-only ghosts) — no per-lifecycle hooks, so every create/remove path including spawned workers is covered on the next tick.

Adoption barrier (operator requirement)

Strictly opt-in, no cargo feature needed:

  • Runs only when events_dir is set (production; same hermeticity posture as the supervisor mailbox — tests spawn nothing) and [dialogue.presence] enabled = true is in the config (carried opaquely by mu-core since fix(mu-core): tolerate the [dialogue] config section owned by mu-dialogue #485).
  • Absent/disabled → nothing spawned, no network. A bare mu install needs no etcd.
  • No new compile cost: reqwest was already in the dep tree via rmcp's reqwest transport; base64 is a workspace dep — hence config-gating instead of a feature flag ("behind a feature if necessary" — it wasn't).
  • Fail-open: etcd trouble degrades to activity-derived presence and retries on the tick; sessions are never affected.

Testing

  • Unit: config gating shapes (absent/disabled/no-endpoints → off; defaults; TTL floor), desired-set computation, gateway int64 tolerance. just ci green.
  • Live against etcd 3.6.5 + the production dialogue server: mu serve start → daemon peer visible as presence:"lease" via agent dialogue peers; kill → liveness claim dropped at lease expiry.

🤖 Generated with Claude Code

https://claude.ai/code/session_019YY9xpjK6mWLJDMaYnvC6T

The mu-daemon slice of lease-backed dialogue presence (push-mailbox spec
§1; completes the trio: mu#482 server read side, agent_tools#48 cc watch
holder). One lease per daemon + one reconciliation task: every TTL/3 it
keepalives and syncs /mu/dialogue/v1/peers/ against the LIVE session
registry (mu:<daemon_id>:<session_id> per session + a daemon key) — no
lifecycle hooks, so every create/remove path (workers included) is
covered on the next tick, and a crashed daemon's keys vanish with its
single lease. Rehydrated read-only ghosts are excluded via a new
Sessions::live_session_ids() (inner + workers only).

Strictly opt-in per operator requirement (adopting mu must not require
etcd): spawned only when events_dir is set (production; same hermeticity
posture as the supervisor mailbox) AND [dialogue.presence] enabled=true
is present in the config mu-core carries opaquely (mu#485). No cargo
feature: reqwest is already in the dep tree via rmcp's reqwest transport
and base64 is a workspace dep, so the compile-cost delta is nil —
config-gating alone keeps the adoption barrier flat. Fail-open: etcd
trouble degrades to activity-derived presence and retries; sessions are
never affected.

Verified live against etcd 3.6.5 + the production dialogue server: mu
serve start -> daemon peer visible as presence=lease on the channel;
kill -> liveness claim dropped at lease expiry.
@sahuagin sahuagin merged commit 949fed7 into main Jul 13, 2026
5 checks passed
@sahuagin sahuagin deleted the cc/serve-session-lease-presence branch July 13, 2026 17:00
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.

1 participant