[Bug] All project sessions terminated sequentially with no user action; worktrees removed bypassing session_cleanup_facts; sessions left unrestorable

Author: axisrowCreated Sep 5, 2026Updated Sep 18, 2026
Labelsbugcomp/daemon

Environment

  • AO daemon: ao versiondev; binary /Applications/Agent Orchestrator.app/Contents/Resources/daemon/ao (built 2026-09-05 09:54)
  • macOS (Darwin 25.6.0), desktop app installed and open, daemon up ~13h (pid 14290)
  • Harness: claude-code, 14 sessions in one project (13 workers + 1 orchestrator), TUI mode

What happened

At 2026-09-05 15:05:46–15:05:55 UTC all 14 sessions of the project were terminated sequentially with no user action — a steady mechanical cadence of ~0.68–0.70 s per session, including the orchestrator session record.

Evidence from ao.db change_log (read-only query, project scoped):

seq      created_at                 session_id   event_type        payload
3118052  2026-09-05 15:05:46.586    project-1    session_updated  {"activity":"exited","isTerminated":true,...}
3118054  2026-09-05 15:05:47.311    project-2    session_updated  {"activity":"exited","isTerminated":true,...}
...
3118138  2026-09-05 15:05:55.431    project-14   session_updated  {"activity":"exited","isTerminated":true,...}

(14 rows, seq 3118052 → 3118138, one per session in numeric order.)

Within ~2 minutes, all worker worktrees under ~/.ao/data/worktrees/<project>/ were removed as well — but session_cleanup_facts has zero rows for the project, so the documented cleanup pipeline was not the actor.

What was NOT happening

  • No ao session kill, no ao session cleanup, no ao project rm — none were executed from any terminal (orchestrator session shell history verified).
  • The owner states no terminate/cleanup action in the desktop app.
  • Preceding daemon calls from the orchestrator (≈15:01–15:04): ao session claim-pr twice (failed PR_NOT_FOUND, then PR_PROJECT_MISMATCH — project record holds a stale repo URL), ao project ls, ao project get, and one ao project add upsert on the already-registered path (rejected with PATH_ALREADY_REGISTERED). Listing them for completeness; no proven causation.

The orchestrator's CLI client survived (conversation is client-side) and re-registered as a new session id after the sweep killed the old orchestrator record — from the desktop it looked like "all workers disappeared".

Secondary: the sessions are then unrecoverable

ao session restore <id> prints restored, recreates the worktree, but the agent immediately exits (status: exited, isTerminated: false); ao sendAGENT_EXITED; a second restore → SESSION_NOT_RESTORABLE. The agent terminal shows Error: Session ID <uuid> is already in use. Same family as #4280 (closed) and #3875 (open) — on a 2026-09-05 dev build. Net effect: a no-user-action sweep + broken restore = permanent loss of 13 sessions mid-flight.

Prior art for probe-failure → bulk-terminate: #1838 (closed), #1735 (closed).

Impact

13 workers lost mid-task; recovery only via fresh sessions (externalized state — pushed branches, PRs, files outside worktrees — saved us from actual work loss).

Asks

  1. Attribution: persist who/what ordered a termination (API caller vs panel vs internal sweep/reaper). Today nothing in the DB can answer "who terminated these sessions", which makes incidents like this undiagnosable.
  2. Guard rails on bulk termination paths: log the trigger, respect is_pinned, and consider requiring explicit intent for sweeps that include the orchestrator.
  3. Fix/verify the restore path (#4280 regression, #3875) — it turns any sweep into permanent loss.

Source: Untrivial-ai/agent-orchestrator