diff --git a/apps/cli/CHANGELOG.md b/apps/cli/CHANGELOG.md index 454dab4..f95d91c 100644 --- a/apps/cli/CHANGELOG.md +++ b/apps/cli/CHANGELOG.md @@ -31,9 +31,12 @@ access shape). `parent_attestation`). Older payloads continue to work. - **`claudemesh launch`** — generates an ed25519 session keypair and a 12 h parent attestation per launch (mesh secret key signs it), - forwards both to the daemon under `body.presence`. The flag - `CLAUDEMESH_SESSION_PRESENCE` defaults to ON; set `=0` to roll back - if a broker on a given mesh is misbehaving. + forwards both to the daemon under `body.presence`. Per-session + presence is always on; older brokers that don't recognize + `session_hello` reply `unknown_message_type` and the daemon quietly + drops the per-session WS for that mesh — the regular member-keyed + WS still covers all functionality, the only loss is sibling-session + visibility on that mesh. - **latent 1.29.0 bug fix** — `claudemesh launch` referenced `claudeSessionId` before its `const` declaration further down the file, hitting the temporal dead zone → `ReferenceError` silently @@ -44,10 +47,9 @@ access shape). ### Sequencing -The broker side ships first and bakes for ~24 h. Only then does the -flag default flip on the CLI side. Older CLIs continue working -unchanged (no per-session WS), and the protocol is purely additive on -the wire. +The broker side ships first and bakes for ~24 h. Older CLIs continue +working unchanged (no per-session WS), and the protocol is purely +additive on the wire. ### Verification (smoke) diff --git a/apps/cli/src/commands/launch.ts b/apps/cli/src/commands/launch.ts index 1d7c3be..8a48775 100644 --- a/apps/cli/src/commands/launch.ts +++ b/apps/cli/src/commands/launch.ts @@ -680,9 +680,8 @@ export async function runLaunch(flags: LaunchFlags, rawArgs: string[]): Promise< sessionTokenForCleanup = minted.token; // Per-session ephemeral keypair + parent attestation (1.30.0+). - // Behind CLAUDEMESH_SESSION_PRESENCE: the daemon ignores the - // presence material when the flag is off, so sending it always is - // forward-compatible. + // Older daemons ignore unknown body fields, so sending presence + // material always is forward-compatible. let presencePayload: { session_pubkey: string; session_secret_key: string; diff --git a/apps/cli/src/daemon/run.ts b/apps/cli/src/daemon/run.ts index d7f1c4e..352cb28 100644 --- a/apps/cli/src/daemon/run.ts +++ b/apps/cli/src/daemon/run.ts @@ -28,18 +28,6 @@ export interface RunDaemonOptions { clonePolicy?: ClonePolicy; } -/** - * 1.30.0 feature flag. Default ON — the daemon opens a long-lived WS per - * registered session so siblings see each other in `peer list`. Set - * CLAUDEMESH_SESSION_PRESENCE=0 (or "false"/"off") to disable for - * rollback if the broker side is misbehaving on a given mesh. - */ -function isSessionPresenceEnabled(): boolean { - const v = process.env.CLAUDEMESH_SESSION_PRESENCE; - if (v === undefined || v === "") return true; - return v !== "0" && v.toLowerCase() !== "false" && v.toLowerCase() !== "off"; -} - /** Detect a few common container environments to pick UDS-only by default. */ function detectContainer(): boolean { if (process.env.KUBERNETES_SERVICE_HOST) return true; @@ -167,14 +155,13 @@ export async function runDaemon(opts: RunDaemonOptions = {}): Promise { let drain: DrainHandle | null = null; drain = startDrainWorker({ db: outboxDb, brokers }); - // 1.30.0 — per-session broker presence. Default OFF for one release - // cycle so the broker side bakes before the flag flips. Opt-in via - // CLAUDEMESH_SESSION_PRESENCE=1; flips to default-on in 1.30.0 GA. - const sessionPresenceEnabled = isSessionPresenceEnabled(); + // 1.30.0 — per-session broker presence. Always on. Older CLIs that + // don't include `presence` material in the register body just won't + // get a session WS; the daemon's own member-keyed broker still + // covers them. const sessionBrokers = new Map(); setRegistryHooks({ onRegister: (info) => { - if (!sessionPresenceEnabled) return; if (!info.presence) return; const meshConfig = meshConfigs.get(info.mesh); if (!meshConfig) { diff --git a/docs/roadmap.md b/docs/roadmap.md index 736e5fd..e573815 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -277,8 +277,7 @@ identity (deferred for security review). signature checks; daemon adds a slim `SessionBrokerClient` and registry lifecycle hooks. Also fixes a latent 1.29.0 TDZ bug where `claudemesh launch`'s IPC session-token registration was silently - failing every run. Flag-gated for one cycle, default ON in this - release; set `CLAUDEMESH_SESSION_PRESENCE=0` for rollback. Spec at + failing every run. Spec at `.artifacts/specs/2026-05-04-per-session-presence.md`. What's left for true v2.0.0 (next sessions):