Skip to content

feat(coding-agent): event-driven supervisor agent roster serving list from one ledger - #1897

Merged
xeophon merged 48 commits into
mainfrom
feat/agent-roster-ledger
Sep 1, 2026
Merged

feat(coding-agent): event-driven supervisor agent roster serving list from one ledger#1897
xeophon merged 48 commits into
mainfrom
feat/agent-roster-ledger

Conversation

@snimu

@snimu snimu commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Part 2 of 3 for ENG-5794 (https://linear.app/primeintellect/issue/ENG-5794). Stacked on #1895; base is feat/agent-roster-classifier, so this diff is PR2-only. Part 3 (subscription push + TUI consumption) follows.

Summary

  • workers now push their agent roster to the supervisor as events (roster_delta/roster_heartbeat private worker frames): send-only-if-changed deltas from every session/child lifecycle point, queued RLM children included before any session exists, plus a complete replacing snapshot on every (re)auth that carries pending removals — deletions survive supervisor disconnects
  • the supervisor owns one AgentRosterLedger: status classified once at write via the shared classifier (feat(coding-agent): shared agent-status classifier, honest worker visibility, subagents bar rename #1895), seeded at startup from the catalog and the RLM spawn ledger (artifact-dir subagents included, tombstones excluded), then kept current purely by events
  • list is served synchronously from the ledger with zero worker round-trips; the per-worker fan-out with its 5s timeout, the silent stale-summaries path, and mergeSessionLists are deleted; the public list population is byte-compatible with pre-PR2 behavior (pinned by the restored process test)
  • worker death marks family rows recovering natively via socket close; recovery exhaustion marks failed; one 15s unref'd watchdog stamps lastHeardFromAt after 45s of silence (honest staleness instead of silently stale data)
  • legacy workers without the roster capability keep the old refresh path via a capability-gated shim
  • worker.summaries remains only for adoption/recovery/eviction; wake fallback, create readiness, and reuse lookups read the ledger; sessionDir filtering matches artifact-dir subagents by owning-root topology (no sibling-dir cross-contamination)

Validation

  • three adversarial review rounds; final verdict APPROVE with all mutants killed: write-time classification skip, legacy-shim widening, removal-handling drop, worker-close marking skip, queued-supersession lifecycle delete, late-queued-update guard — each by named tests; composition insertion-order reversal proven semantics-free (21/21 green)
  • disconnect semantics pinned: delete-while-disconnected cannot resurrect (removals ride the snapshot, applied after replacement); queue+bind+close while disconnected survives as its durable passivated row
  • sandbox: 19-suite battery 526 passed / 9 skipped; full coding-agent suite zero regressions vs base (identical environmental failure set); root npm run check green

Note

High Risk
Core daemon supervision and session listing now depend on a new worker–supervisor roster protocol and ledger consistency; legacy workers are rejected until restarted, and delete/list/ownership paths were rewired around tombstones and roster state.

Overview
Moves daemon list off per-worker pulls onto a supervisor-owned AgentRoster ledger: workers advertise agent_roster on auth and push roster_delta (diff or full snapshot on reconnect) plus roster_heartbeat over private worker frames; the supervisor applies frames with epoch/chaining, seeds offline rows from the session catalog and RLM spawn ledger, and serves list synchronously from that store.

Workers compose and flush roster rows from session lifecycle (including queued subagents before a session exists, passivated/evicted rows, and explicit removals on archive/delete/swap). Worker disconnect marks rows recovering; prolonged silence sets lastHeardFromAt via a watchdog. Client-owned workers drop roster rows when unregistered; shared tombstoneSavedSessionDelete runs before saved-session deletes. pendingRlmSpawnAppends keys are scoped by parentActiveSessionId#childId. Legacy workers without the capability are rejected (PreRosterWorkerError) and non–client-owned ones may be restarted on adoption.

Reviewed by Cursor Bugbot for commit 385f566. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add event-driven AgentRoster to daemon supervisor and worker protocol

  • Introduces AgentRoster in agent-roster.ts as the single source of truth for session listing, root selection, and ownership checks in the supervisor, replacing direct reads of worker.summaries
  • Workers now compose roster entries from session state and publish roster_delta (snapshot or diff) and roster_heartbeat frames to authenticated supervisors; the protocol is extended in daemon-worker-protocol.ts with DAEMON_WORKER_ROSTER_CAPABILITY and DaemonWorkerRosterOutbound
  • On connect, the supervisor registers a frame listener before auth, requires the agent_roster capability, and throws PreRosterWorkerError for legacy workers; non-client-owned legacy workers are auto-restarted during recovery
  • Session deletion now writes a spawn-ledger tombstone via tombstoneSavedSessionDelete before file removal; roster entries for deleted/closed sessions are removed in the next delta
  • UI label in subagent-summary-line.ts changes from "agents" to "subagents", and agents-view-state.ts now shows live sessions even when worker state is not ready, displaying the worker state as the status label
  • Risk: legacy workers without agent_roster capability will be rejected and restarted; pendingRlmSpawnAppends keys change from childId to ${parentActiveSessionId}#${childId} in daemon-mode.ts — any out-of-tree consumers of that map will break

Changes since #1897 opened

  • Modified DaemonSupervisor roster reseed logic to filter spawn-ledger edges by session family root [385f566]
  • Refactored RlmSpawnLedger.familyUnlocked method to emit orphaned children as root rows and modified delete-session tombstoning to cover all duplicate edges [385f566]
  • Added test coverage for session family filtering during reseed, duplicate edge tombstoning, and orphaned child behavior [385f566]
  • Updated changelog to clarify event-driven agent roster freshness semantics [385f566]

Macroscope summarized 1639737.

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.

3 participants