Skip to content

fix(agent-core-v2): resolve reopened agents to their roster branch - #3726

Merged
sailist merged 1 commit into
MoonshotAI:devfrom
sailist:bug-182-09-10-session-reopen-roster
Sep 11, 2026
Merged

fix(agent-core-v2): resolve reopened agents to their roster branch#3726
sailist merged 1 commit into
MoonshotAI:devfrom
sailist:bug-182-09-10-session-reopen-roster

Conversation

@sailist

@sailist sailist commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

Internal bug report (no public issue): reopening an agent after undo + process restart resurrects the undone turns.

Problem

SessionStores manages one branch per agent plus a _session branch whose agent.opened / agent.switched / agent.closed events fold into a roster mapping each agent to its current branch. This roster must exist because undo is non-destructive: undo('main', 1) forks a new branch main~2 and switches to it, while the old main branch keeps its full pre-undo history.

The read side had a gap: open() resolved branches purely by agent name (tree.has(agentId) → open the same-named branch) and never consulted the roster. Within the same process this went unnoticed (the in-memory store was already reset), but after a process restart open('main') opened the stale pre-undo branch and every undone turn came back. The migrate-v2 end-to-end test asserted only the roster contents after a restart, never the history the reopened agent actually sees — exactly the gap.

What changed

  • SessionStores.open() now treats the roster as authoritative: it reads the folded roster first and opens the registered branch when an entry exists (a roster entry pointing at a missing branch fails loudly via openBranch — corrupted data, no silent fallback). Without an entry it keeps the existing fallback — open the same-named branch (covers the crash window between createBranch and the persisted agent.opened) or create one from opts.from — and dispatches agent.opened to backfill the registration whenever it opens a branch with no roster entry, so first open and crash-window repair share one registration path.
  • Tests extended with zero net test-count change: the stores reopen case now undoes before reopening and asserts the restored agent follows the roster (main~2, post-undo history) while the fork branch keeps its own full history; the migrate-v2 end-to-end case now also opens the agent after the simulated restart and asserts ref.branch and the folded history, not just the roster contents.
  • No changeset: SessionStores is only consumed by human/ tests and persist/open.ts so far — production DI wiring lands in a follow-up task, so the fix is not user-perceivable yet.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: fd54591

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@sailist
sailist merged commit 0d48c45 into MoonshotAI:dev Sep 11, 2026
12 of 13 checks passed
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