Skip to content

feat(recovery): durable per-project agent-session ledger in plan.db (#2405) - #2406

Merged
kevinthelago merged 4 commits into
developfrom
agent-session-ledger
Jul 6, 2026
Merged

feat(recovery): durable per-project agent-session ledger in plan.db (#2405)#2406
kevinthelago merged 4 commits into
developfrom
agent-session-ledger

Conversation

@kevinthelago

Copy link
Copy Markdown
Owner

Fool-proof fleet recovery: an authoritative, DB-backed record of the agents a project has launched, so recovery reads a fact instead of inferring from a pid-only JSON file + worktrees + the fleet plan.

Landed here (slices 1 + 3)

  • plandb fleet_sessions table (pane_id PK · stream_id · role · cwd · pid · status · launched_at · last_seen) + the sessions module (DDL + Store upsert/heartbeat/set_status/list/remove). Wired into schema.migrate + ALL_TABLES. Persists across a clean quit (unlike pty-ledger.json).
  • bsc plan fleet session {set|list|heartbeat|status|remove} — the runtime records each spawned agent (bsc-reachable golden rule).
  • Write-hook: publishFleetRoster records every launched agent (recordFleetSessions) from the roster rows — covering both the primary launch and the recovery restart.
  • Tests + cargo check/clippy --all-targets clean · frontend typecheck/lint clean.

Still to come (follow-up slices, need the app build + GUI check)

  • discover_sessions reads the ledger (+ pid liveness) as the authoritative source.
  • Recovery/Glance restart from it + status transitions (heartbeat / ended-on-close).

Design (approved): per-project plan.db · persists across clean quit · augments (doesn't replace) pty-ledger.json (the pre-boot orphan-reaper). Refs #2405.

🤖 Generated with Claude Code

)

The authoritative, per-project record of the agents a project has LAUNCHED, so
recovery reads a fact instead of inferring from a pid-only JSON file + worktrees.

- plandb `fleet_sessions` table (pane_id PK · stream_id · role · cwd · pid · status
  · launched_at · last_seen) + the `sessions` module owning its DDL + `Store`
  methods (upsert/heartbeat/set_status/list/remove). Wired into schema.migrate +
  ALL_TABLES. Persists across a clean quit (unlike pty-ledger.json).
- `bsc plan fleet session {set|list|heartbeat|status|remove}` — the runtime records
  each spawned agent here (per the bsc-reachable golden rule).
- Tests: upsert-then-refresh preserves launched_at; set-status + remove; empty
  pane_id rejected. cargo check + clippy --all-targets clean.

Slices next: discover_sessions reads the ledger · frontend write-hooks on the fleet
lifecycle · recovery/Glance restart from it. Refs #2405.
…#2405)

publishFleetRoster now also records each launched agent in the durable per-project
session ledger (`bsc plan fleet session set`), from the same roster rows — so the
ledger reflects every fleet launch (primary launch + recovery restart, the two
publishFleetRoster callers). Best-effort + fire-and-forget per agent; a failed
write never blocks the launch. cwd is re-derived from the plan on restart, so it's
left blank here.

- recordFleetSessions(projectKey, rosterRows) in fleetRoster.ts.
- Test: records director (empty streamId) + worker (real streamId) as running;
  skips a keyless row.

Next: discover_sessions reads the ledger (app crate) · recovery/Glance restart +
status transitions. Refs #2405.
@kevinthelago
kevinthelago merged commit 8759fe2 into develop Jul 6, 2026
7 checks passed
@kevinthelago
kevinthelago deleted the agent-session-ledger branch July 6, 2026 19:04
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