fix(agent-core-v2): tower mode mistaking newly agents for previous name - #3752
tpoisonooo wants to merge 5 commits into
Conversation
…istration Agent ids restart from agent-0 in each session, so a freshly spawned worker collided with the previous session's roster entry and every find-first lookup (caller identity, write guard, death bookkeeping) resolved to the stale entry: workers read the wrong inbox, sent under the wrong name, and were denied their own writes, mission updates, and reviews. - resolveAgent picks the latest roster entry for an agent id; all callers (resolveCallerName, write guard, resume veto, died/revived) go through it - registerAgent retires same-agent-id entries before appending - enter() (/tower on) now adopts the workspace roster itself instead of relying on a manual TowerInit
🦋 Changeset detectedLatest commit: 9cf7e83 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7eaa7ef5f2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
… finds a dead foreign owner A forked or restored session replays the durable TowerModeEnter into an active tower mode without ever calling enter(), so the roster adoption added there never ran on the restore path: with the previous owner session gone, the fork kept the mode (and the stale roster) until a manual TowerInit. The dead-owner branch of the restore-time reconciliation now adopts the workspace, mirroring enter()'s takeover of an idle owner; a live foreign owner still causes an exit.
…dopting its roster Taking tower mode over from a live but idle owner called the owner's synchronous exit(), whose ownership release ran fire-and-forget, and immediately adopted the roster — two concurrent load-modify-save cycles on .tower/comms/state.json that could lose the new owner or resurrect the stale roster. exit() now awaits the ownership release and the takeover awaits the owner's exit(); the remaining callers either await (RPC/HTTP tower-mode-off) or explicitly ignore the promise (mode mutex, restore-time self-exit).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0124c53925
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…nnot complete Adoption failures (unreadable or unpersistable state.json) were swallowed into a log warning, so enter() and the stale-owner restore both activated tower mode with the foreign owner and stale roster still in place — the exact identity mismatch the adoption is meant to prevent, now with a false success report. adoptTowerRoster() now throws a TowerProtocolError with the underlying cause: enter() propagates it before any tool is activated, and the restore path drops the replayed tower mode instead (it must not throw inside the restore hook chain).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a89b66fd98
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…option adopt() treated any state.json read failure as an uninitialized workspace via isInitialized()'s catch-all, so an existing but unreadable state file (EACCES, EISDIR, transient I/O) reported a successful no-op adoption and enter() activated tower mode against the foreign state — bypassing the activation guard added in the previous commit. Only ENOENT now means uninitialized; every other read error propagates into the fail-activation / deactivate-on-restore paths.
Related Issue
Resolve #(issue_number)
Problem
跨 session 重启 tower mode 导致 agent id 撞号。
tower 给 worker 发消息,inbox 用 id 解析命中了旧名字,最终 worker 收不到。
What changed
Checklist
/approve).gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.