You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ao stop correctly kills sessions across all projects in the global config and writes them to last-stop.json. But ao start (any variant) only registers and polls a single project (the one resolved from cwd), and consequently any restore code that runs — whether reached via the interactive prompt on plain ao start, the auto-confirm ao start --restore, or via the skip-prompt ao start --no-restore (which skips both) — drops every session whose projectId doesn't match the registered one. A user who runs ao stop && ao start <anything> from one project's directory loses every active session in every other project, with no warning.
The fix has two layers: (1) the single-project registration scope at start time, and (2) the restore loop's project filter downstream of registration.
This is distinct from #1743 (which is the ao stop → ao update → ao start path losing last-stop.json entirely). Here last-stop.jsonis written and is consumed for the cwd project — but cross-project entries are silently filtered out.
Source: Live AO session, in-chat triage with Claude orchestrator | Reported by:@Itrytoohard Analyzed against:5897b4e8 (AgentWrapper/agent-orchestrator origin/main as of 2026-06-08) Environment: macOS 14.6 arm64, Node v22.11.0, tmux runtime; two real projects (agent-orchestrator_5dce9e3fe8, agent-orchestrator_649ba24578) registered in global config Confidence:High — captured the full stop+start log; saw 8/8 stopped vs 1/1 restored; verified resulting on-disk state matches.
Affected invocations
Invocation
What happens to cross-project sessions
ao start → answer "yes" to restore prompt
Dropped (same single-project filter applies)
ao start → answer "no"
Not restored (expected — user opted out)
ao start --restore
Dropped (auto-runs the same filtered restore)
ao start --no-restore
Not restored (expected — user opted out)
The bug is scope-level, not flag-level. Every variant of ao start registers only the cwd's project.
Reproduction
Have ≥1 active session in project A and ≥1 active session in project B, both registered in ~/.agent-orchestrator/config.yaml.
From a shell whose cwd resolves to project A, run any of: ao stop && ao start --restore / ao stop && ao start (answer "yes" at prompt) / ao stop && ao start --no-restore (won't even prompt).
Expected: all sessions from project A and project B come back (per CLAUDE.md: "Offers to restore sessions from last-stop.json — includes cross-project sessions via otherProjects field").
Actual: only project A's sessions restore. Project B's sessions stay terminated / manually_killed with their runtimes gone. Daemon's lifecycle worker only polls project A — even sessions you manually ao session restore after the fact don't get lifecycle events for project B.
Concrete log from this user (ao stop && ao start --restore from project _649ba24578's directory):
$ ao stop && ao start --restore
[...]
Stop AO and 8 active session(s)? Yes
✔ Stopped 8 session(s)
agent-orchestrator: ao-10, ao-11, ao-12, ao-13, ao-14, ao-2, ao-orchestrator ← 7 in project _5dce9e3fe8
agent-orchestrator_649ba24578: ao-2-orchestrator ← 1 in project _649ba24578
[...]
Starting orchestrator for Agent Orchestrator
[...]
✔ Restored orchestrator session: ao-2-orchestrator
✔ Lifecycle project supervisor started
1 session(s) from other projects were also stopped: ← misleading: says "1", actually 7
agent-orchestrator_649ba24578: ao-2-orchestrator ← wrong project listed (cwd, not "other")
✔ Restored 1/1 session(s)
Lifecycle: supervised (polling 1 project(s): agent-orchestrator_649ba24578) ← only 1 project polled
Stopped 8, restored 1. The "1 session(s) from other projects were also stopped: agent-orchestrator_649ba24578: ao-2-orchestrator" line is itself bugged — _649ba24578 was the cwd project, not "other"; and the count says 1 when there were 7 cross-project sessions. The reader has no way to discover that 7 sessions were lost.
Root Cause Hypotheses
I haven't traced the code path, but the symptoms point at:
ao start registers only the cwd-resolved project with the lifecycle supervisor (polling 1 project(s): agent-orchestrator_649ba24578). The single-project registration is independent of which flag is passed and happens before the restore code runs.
The restore code path (whether reached via --restore, the default prompt, or anywhere else) iterates last-stop.json's sessions and filters out anything whose projectId doesn't match the registered set — so cross-project entries get dropped.
The misleading log line ("1 session(s) from other projects … ao-2-orchestrator") is a downstream bug in the same code path — the message-rendering treats the cwd-project session as the "other project" entry, suggesting an off-by-one or wrong-source-variable.
Per-session manual restore works because ao session restore <id> resolves the project from findSessionRecord(sessionId) across the entire global config:
This rebuilds each worktree from its branch, relaunches the agent, and adds the session back. But the daemon's lifecycle worker still only polls the cwd project, so those restored sessions don't receive PR/CI/runtime updates until the next full restart from a directory that registers the right project — which itself has the same single-project scope. There is no in-place "tell the running daemon to also start polling project X" command.
Suggested Fix
Small to large:
Make ao start register every project that has restorable sessions in last-stop.json (and/or every project in the global config — the right scope is a design call, but at minimum: union of cwd-project + every projectId appearing in last-stop.json.sessions[] and otherProjects[].sessions[]). The existing running.json.projects: [] is already an array — the wiring just needs to populate it from the right source on start.
Make the restore loop cross-project-aware. Once registration is fixed, iterate the union of sessions[] and otherProjects[].sessions[], dispatching each session restore against its own project's session manager.
Fix the log line. The "N session(s) from other projects were also stopped" message should (a) count the actual cross-project rows, not 1, and (b) list the other projects' sessions, not the cwd-project's. The wrong rendering is independently misleading even after the underlying restore is fixed.
Add a dry-run / non-default behavior guard. If last-stop.json contains sessions whose projectId isn't being registered by this ao start, either (a) register them, or (b) print a loud warning enumerating exactly which sessions will be left terminated and ask for confirmation. Silent loss is the worst outcome.
Impact
ao stop && ao start <anything> is not a safe round-trip in any multi-project setup. Users who run this expecting "stop everything, start everything back" lose work silently. The flag matrix above shows this is independent of --restore.
The user's case here: 7 sessions across a different project went dark with no recourse other than per-session manual restore (which itself loses the lifecycle polling).
Restored sessions don't get lifecycle events anyway because the daemon only polls one project — restore is incomplete on a deeper axis.
Related
#1743 — adjacent restore-bug. ao update between stop and start destroys last-stop.json. Same family, different failure mode. Fixes likely live in nearby code.
#2110 — sidebar lists all terminated sessions. The 7 sessions this bug strands appear there indefinitely.
#1128 — RFC: multi-base-branch orchestrators (one orchestrator per branch). The single-project polling assumption that drives this bug also constrains that RFC.
#1522 (CLOSED) — "Dynamic project supervisor: auto-poll active globally-registered projects". Closed; whatever shipped clearly didn't cover the start-time registration path. Worth re-reading that fix's scope.
#1590 (CLOSED) — "kill+restore session starts fresh chat instead of resuming (multi-project)". Different bug but in the multi-project restore neighborhood.
Edited: Retitled and rewritten from the original "ao start --restore drops cross-project sessions" to reflect that the bug is scope-level (single-project registration), not flag-level. The flag matrix in §"Affected invocations" makes the broader effect explicit. Body updated end-to-end. — 2026-06-08
Bug
ao stopcorrectly kills sessions across all projects in the global config and writes them tolast-stop.json. Butao start(any variant) only registers and polls a single project (the one resolved from cwd), and consequently any restore code that runs — whether reached via the interactive prompt on plainao start, the auto-confirmao start --restore, or via the skip-promptao start --no-restore(which skips both) — drops every session whoseprojectIddoesn't match the registered one. A user who runsao stop && ao start <anything>from one project's directory loses every active session in every other project, with no warning.The fix has two layers: (1) the single-project registration scope at start time, and (2) the restore loop's project filter downstream of registration.
This is distinct from #1743 (which is the
ao stop → ao update → ao startpath losinglast-stop.jsonentirely). Herelast-stop.jsonis written and is consumed for the cwd project — but cross-project entries are silently filtered out.Source: Live AO session, in-chat triage with Claude orchestrator | Reported by: @Itrytoohard
Analyzed against:
5897b4e8(AgentWrapper/agent-orchestrator origin/main as of 2026-06-08)Environment: macOS 14.6 arm64, Node v22.11.0, tmux runtime; two real projects (
agent-orchestrator_5dce9e3fe8,agent-orchestrator_649ba24578) registered in global configConfidence: High — captured the full stop+start log; saw 8/8 stopped vs 1/1 restored; verified resulting on-disk state matches.
Affected invocations
ao start→ answer "yes" to restore promptao start→ answer "no"ao start --restoreao start --no-restoreThe bug is scope-level, not flag-level. Every variant of
ao startregisters only the cwd's project.Reproduction
~/.agent-orchestrator/config.yaml.ao stop && ao start --restore/ao stop && ao start(answer "yes" at prompt) /ao stop && ao start --no-restore(won't even prompt).CLAUDE.md: "Offers to restore sessions fromlast-stop.json— includes cross-project sessions viaotherProjectsfield").terminated / manually_killedwith their runtimes gone. Daemon's lifecycle worker only polls project A — even sessions you manuallyao session restoreafter the fact don't get lifecycle events for project B.Concrete log from this user (
ao stop && ao start --restorefrom project_649ba24578's directory):Stopped 8, restored 1. The "1 session(s) from other projects were also stopped: agent-orchestrator_649ba24578: ao-2-orchestrator" line is itself bugged —
_649ba24578was the cwd project, not "other"; and the count says 1 when there were 7 cross-project sessions. The reader has no way to discover that 7 sessions were lost.Root Cause Hypotheses
I haven't traced the code path, but the symptoms point at:
ao startregisters only the cwd-resolved project with the lifecycle supervisor (polling 1 project(s): agent-orchestrator_649ba24578). The single-project registration is independent of which flag is passed and happens before the restore code runs.The restore code path (whether reached via
--restore, the default prompt, or anywhere else) iterateslast-stop.json's sessions and filters out anything whoseprojectIddoesn't match the registered set — so cross-project entries get dropped.The misleading log line ("1 session(s) from other projects … ao-2-orchestrator") is a downstream bug in the same code path — the message-rendering treats the cwd-project session as the "other project" entry, suggesting an off-by-one or wrong-source-variable.
Pointer files (per
CLAUDE.md's "Key Files" table):packages/cli/src/commands/start.ts+packages/cli/src/lib/running-state.ts.Workaround
Per-session manual restore works because
ao session restore <id>resolves the project fromfindSessionRecord(sessionId)across the entire global config:This rebuilds each worktree from its branch, relaunches the agent, and adds the session back. But the daemon's lifecycle worker still only polls the cwd project, so those restored sessions don't receive PR/CI/runtime updates until the next full restart from a directory that registers the right project — which itself has the same single-project scope. There is no in-place "tell the running daemon to also start polling project X" command.
Suggested Fix
Small to large:
Make
ao startregister every project that has restorable sessions inlast-stop.json(and/or every project in the global config — the right scope is a design call, but at minimum: union ofcwd-project+ everyprojectIdappearing inlast-stop.json.sessions[]andotherProjects[].sessions[]). The existingrunning.json.projects: []is already an array — the wiring just needs to populate it from the right source on start.Make the restore loop cross-project-aware. Once registration is fixed, iterate the union of
sessions[]andotherProjects[].sessions[], dispatching each session restore against its own project's session manager.Fix the log line. The "N session(s) from other projects were also stopped" message should (a) count the actual cross-project rows, not 1, and (b) list the other projects' sessions, not the cwd-project's. The wrong rendering is independently misleading even after the underlying restore is fixed.
Add a dry-run / non-default behavior guard. If
last-stop.jsoncontains sessions whoseprojectIdisn't being registered by thisao start, either (a) register them, or (b) print a loud warning enumerating exactly which sessions will be left terminated and ask for confirmation. Silent loss is the worst outcome.Impact
ao stop && ao start <anything>is not a safe round-trip in any multi-project setup. Users who run this expecting "stop everything, start everything back" lose work silently. The flag matrix above shows this is independent of--restore.ao updateflow (#1743's neighbor problem) doubly fragile — even after bug(cli): ao stop → ao update → ao start leaves sessions terminated, no restore prompt #1743 is fixed, the multi-project loss case still bites.Related
ao updatebetween stop and start destroyslast-stop.json. Same family, different failure mode. Fixes likely live in nearby code.Edited: Retitled and rewritten from the original "ao start --restore drops cross-project sessions" to reflect that the bug is scope-level (single-project registration), not flag-level. The flag matrix in §"Affected invocations" makes the broader effect explicit. Body updated end-to-end. — 2026-06-08