{ "description": "Agents vectors: shared remote Claude Code sessions fronted by an Eleven group (docs/superpowers/specs/2026-08-05-eleven-claude-agents-design.md). The workstation bridge posts durable session.* events; every member's fold converges on the same fleet board. Payloads aren't sender-signed, so the fold re-validates everything regardless of what the bridge checked. Source of truth: web/static/apps/agents.js.", "app": "agents", "source": "web/static/apps/agents.js", "state_shape": { "sessions": [{ "id": "string (^[A-Za-z0-9_-]{1,64}$)", "name": "string (≤80, from the wire field `session` — `name` is transport-injected)", "flavor": "\"scoped\" | \"plain\" (anything else folds to scoped)", "root": "string (≤300)", "worktree": "string (≤300)", "by": "string (≤80, who asked)", "ts": "number (epoch ms)", "state": "running | idle | waiting | dead | ended", "activity": "string (≤200)", "statusTs": "number", "prompts": "number", "turns": "number", "result": "string (≤500)", "approvals": [{ "rid": "string", "tool": "string (≤120)", "digest": "string (≤200)", "state": "pending | allowed | denied", "by": "string (decider, from transport name)" }], "endedAt": "number", "reason": "string (≤120)" }] }, "notes": [ "The session's human name rides the wire as `session`, never `name` — `name`/`ts`/`uid` are transport-injected (emitter identity), so the bridge cannot use them for payload.", "session.spawn is idempotent by id and never replaces: an existing id is a no-op (a re-spawn is a new id). Max 50 sessions per thread, oldest ended evicted first.", "session.status on an unknown session, with an unknown state, or after session.end is a no-op — ended is terminal; a late status frame can't resurrect a session.", "session.approval: the bridge posts the pending request; a member's decision folds onto it. First decision wins — a decided approval never flips, and a decision for an unposted rid is a no-op.", "session.end drops pending approvals (they die with the session) and is the bridge's cue to remove a scoped session's worktree (close-session-closes-worktree, decided 2026-08-28; committed branches survive).", "session.tool / session.stream are ephemeral (relay-only) types claimed with no-op folds — a hostile stored copy folds harmlessly.", "Per the accepted design, session.prompt IS the member's chat message (one event, two projections); board state keeps only a count." ], "vectors": [ { "name": "spawn", "description": "The bridge announces a new scoped session; every canonical field materialises.", "initial_state": { "sessions": [] }, "event": { "type": "session.spawn", "id": "s1", "session": "fix-login", "flavor": "scoped", "root": "~/github.com/elevenmessenger/messenger", "worktree": "wt-fix-login", "by": "Paul", "name": "Claude", "ts": 1700000000000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "~/github.com/elevenmessenger/messenger", "worktree": "wt-fix-login", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "expected_group_chat_projection": { "text": "started session “fix-login” on ~/github.com/elevenmessenger/messenger", "action": true } }, { "name": "spawn_duplicate_id_noop", "description": "A second spawn with an existing id never replaces — history can't be rewritten by a later event.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.spawn", "id": "s1", "session": "impostor", "flavor": "plain", "name": "Mallory", "ts": 1700000009000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] } }, { "name": "spawn_bad_flavor_folds_scoped", "description": "A hostile or future flavor value folds to the safe reading: scoped.", "initial_state": { "sessions": [] }, "event": { "type": "session.spawn", "id": "s2", "session": "ops", "flavor": "root-of-everything", "name": "Claude", "ts": 1700000001000 }, "expected_state_update": { "sessions": [ { "id": "s2", "name": "ops", "flavor": "scoped", "root": "", "worktree": "", "by": "", "ts": 1700000001000, "state": "running", "activity": "", "statusTs": 1700000001000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] } }, { "name": "spawn_missing_id_noop", "description": "An event without a usable id is hopeless and folds to a no-op.", "initial_state": { "sessions": [] }, "event": { "type": "session.spawn", "session": "ghost", "name": "Mallory", "ts": 1700000002000 }, "expected_state_update": { "sessions": [] } }, { "name": "status_updates_board", "description": "session.status is board truth: state + the one-line activity + its timestamp.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.status", "id": "s1", "state": "waiting", "activity": "go test ./internal/bot", "name": "Claude", "ts": 1700000003000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "waiting", "activity": "go test ./internal/bot", "statusTs": 1700000003000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "expected_group_chat_projection": null }, { "name": "status_unknown_session_or_state_noop", "description": "A status for an unknown session id folds to a no-op (and an unknown state value would too).", "initial_state": { "sessions": [] }, "event": { "type": "session.status", "id": "s9", "state": "running", "activity": "x", "name": "Claude", "ts": 1700000003000 }, "expected_state_update": { "sessions": [] } }, { "name": "prompt_counts_and_projects", "description": "A member steers the session: the prompt IS their chat message (action-line projection for now); the board counts it.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.prompt", "id": "s1", "session": "fix-login", "text": "fix the flaky reminder test", "name": "Paul", "uid": "u_paul", "ts": 1700000004000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 1, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "expected_group_chat_projection": { "text": "asked fix-login: “fix the flaky reminder test”", "action": true } }, { "name": "turn_counts_and_projects", "description": "The assistant's completed turn: a bubble in the app's voice, tagged with the session; the board counts it.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 1, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.turn", "id": "s1", "session": "fix-login", "text": "Found it — the ticker fires before the store hydrates.", "name": "Claude", "ts": 1700000005000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 1, "turns": 1, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "expected_group_chat_projection": { "text": "[fix-login] Found it — the ticker fires before the store hydrates.", "action": false } }, { "name": "approval_first_decision_wins", "description": "The bridge posts a pending approval; Ana allows it; Bob's later deny is a no-op — first decision wins, attributed by the transport name.", "event_sequence": [ { "type": "session.spawn", "id": "s1", "session": "fix-login", "flavor": "scoped", "root": "r", "by": "Paul", "name": "Claude", "ts": 1700000000000 }, { "type": "session.approval", "id": "s1", "rid": "a1", "session": "fix-login", "tool": "git push", "digest": "origin main", "state": "pending", "name": "Claude", "ts": 1700000006000 }, { "type": "session.approval", "id": "s1", "rid": "a1", "session": "fix-login", "tool": "git push", "state": "allowed", "name": "Ana", "uid": "u_ana", "ts": 1700000007000 }, { "type": "session.approval", "id": "s1", "rid": "a1", "session": "fix-login", "tool": "git push", "state": "denied", "name": "Bob", "uid": "u_bob", "ts": 1700000008000 } ], "expected_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [{ "rid": "a1", "tool": "git push", "digest": "origin main", "state": "allowed", "by": "Ana" }], "endedAt": 0, "reason": "" } ] } }, { "name": "approval_decision_without_pending_noop", "description": "A decision for a request the log never saw folds to a no-op — approvals exist only once the bridge posts them.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.approval", "id": "s1", "rid": "a9", "state": "allowed", "name": "Mallory", "ts": 1700000008000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] } }, { "name": "end_is_terminal", "description": "Closing a session: pending approvals die with it, and a late status frame can't resurrect it.", "event_sequence": [ { "type": "session.spawn", "id": "s1", "session": "fix-login", "flavor": "scoped", "root": "r", "by": "Paul", "name": "Claude", "ts": 1700000000000 }, { "type": "session.approval", "id": "s1", "rid": "a1", "session": "fix-login", "tool": "git push", "state": "pending", "name": "Claude", "ts": 1700000006000 }, { "type": "session.end", "id": "s1", "session": "fix-login", "reason": "closed", "name": "Paul", "uid": "u_paul", "ts": 1700000009000 }, { "type": "session.status", "id": "s1", "state": "running", "activity": "zombie", "name": "Claude", "ts": 1700000010000 } ], "expected_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "ended", "activity": "", "statusTs": 1700000000000, "prompts": 0, "turns": 0, "result": "", "approvals": [], "endedAt": 1700000009000, "reason": "closed" } ] }, "expected_group_chat_projection_of": { "type": "session.end", "id": "s1", "session": "fix-login", "reason": "closed", "name": "Paul", "uid": "u_paul", "ts": 1700000009000 }, "expected_group_chat_projection": { "text": "closed session “fix-login”", "action": true } }, { "name": "result_keeps_latest_summary", "description": "A milestone summary lands on the board (latest wins) and speaks as a bubble.", "initial_state": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 1, "turns": 2, "result": "", "approvals": [], "endedAt": 0, "reason": "" } ] }, "event": { "type": "session.result", "id": "s1", "session": "fix-login", "summary": "2 files changed, go test green", "name": "Claude", "ts": 1700000011000 }, "expected_state_update": { "sessions": [ { "id": "s1", "name": "fix-login", "flavor": "scoped", "root": "r", "worktree": "", "by": "Paul", "ts": 1700000000000, "state": "running", "activity": "", "statusTs": 1700000000000, "prompts": 1, "turns": 2, "result": "2 files changed, go test green", "approvals": [], "endedAt": 0, "reason": "" } ] }, "expected_group_chat_projection": { "text": "[fix-login] ✅ 2 files changed, go test green", "action": false } }, { "name": "ephemeral_types_fold_to_noop", "description": "A hostile client storing a session.stream frame as a real message folds harmlessly — the type is claimed with a no-op fold.", "initial_state": { "sessions": [] }, "event": { "type": "session.stream", "id": "s1", "text": "partial…", "name": "Mallory", "ts": 1700000012000 }, "expected_state_update": { "sessions": [] } } ] }