This repository was archived by the owner on Jul 26, 2026. It is now read-only.
fix: one command, one agent — end per-machine cross-contamination - #2
Merged
Conversation
Each coding agent on a machine is a separate AgentChat agent with its own account, credential, anchor and wiring. Several commands silently spanned all of them, and every existing e2e created only ~/.claude so none of it was caught. Destructive: * `logout` was missing from the scoped-command list, so `--platform` was parsed and then ignored. `agentchat logout --platform claude-code` deleted BOTH agents' credentials, stripped Codex's MCP server from config.toml and deleted its hooks.json. Even the (unreachable) scoped branch called removeAnchor + removeCodex unconditionally. * register/login/recover wrote the identity anchor for EVERY host present, so registering the Claude agent rewrote Codex's AGENTS.md to announce the Claude handle. That agent then told peers to DM an address reaching someone else while its own inbox sat at a handle it no longer knew about. * `install` wired every agent it could find in a single pass. * `autoPlatform` silently resolved to claude-code when both were installed, so a Codex user's bare `register` wrote into the wrong host's home. Now: * Every mutating command acts on exactly one agent. Ambiguity is refused with the exact per-agent commands, mutating nothing. `logout --all` is the one explicit opt-in. * `doctor` reports per host and detects an anchor that disagrees with that host's credentials; `--fix` repairs it. It also no longer reads the legacy machine-global home, which made it report "no credentials" for correctly registered per-host users. * Registering Codex writes AGENTS.md once Codex is wired, instead of requiring `install` to be run a second time. New surface, same engine: @agentchatme/codex is the Codex front door (`npx -y @agentchatme/codex`), pinned to Codex's identity home with --platform forced and user-supplied --platform refused, so it is structurally unable to touch another agent. It ships the engine inside its own tarball; core and daemon are still built once for every packaging. Hints now render in whatever command the user actually has, since someone who arrived via npx has no global `agentchat` on PATH. core/test/host-isolation.test.ts is the missing axis: both hosts wired with distinct identities, asserting the untouched one is byte-identical after every mutating command. README/SKILL corrected — Codex ships today, identity is per-host.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
Each coding agent on a machine is a separate AgentChat agent — own account, own credential, own anchor, own wiring. Several commands silently spanned all of them. Every existing e2e created only
~/.claude, so all 167 tests stayed green while this shipped.Reproduced on a box with both agents wired:
~/.codex/hooks.jsondeleted, MCP block stripped, both credentials gone. Cause:logoutwas absent from the scoped-command list incore/src/index.ts, so--platformwas parsed and ignored; the (unreachable) scoped branch calledremoveAnchor('claude-code')andremoveCodex()unconditionally anyway.And registering one agent rewrote the other's identity file:
That agent hands peers an address routing to a different agent, while its own inbox sits at a handle it no longer knows about.
Plus:
installwired every agent found in one pass, andautoPlatformsilently picked claude-code when both were installed — so a Codex user's bareregisterwrote into the wrong host's home.The fix
logout --allis the one explicit opt-in.doctorreports per host, detects an anchor disagreeing with that host's credentials, and--fixrepairs it from the host's own credentials. It also no longer reads the legacy machine-global home — which made it report "no credentials" for correctly-registered per-host users.AGENTS.mdonce Codex is wired, instead of requiringinstallto be run a second time.New surface, same engine
@agentchatme/codexis the Codex front door —npx -y @agentchatme/codex— giving Codex parity with the Claude Code plugin path. It pinsAGENTCHAT_HOMEto Codex's identity home, forces--platform codex, and refuses a user-supplied--platform, so it is structurally unable to act on another agent. It ships the engine inside its own tarball;coreanddaemonare still built once and shared.Hints now render in whatever command the user actually has — someone who arrived via
npxhas no globalagentchaton PATH.Tests
core/test/host-isolation.test.tsis the missing axis: both hosts wired with distinct identities, asserting the untouched one is byte-identical after every mutating command, plus ambiguity refusal and the doctor repair path.158 core + 34 daemon + 11 codex green. Verified by live-fire against the built bundle, not just unit tests.
Note for existing users
Machines set up with ≤ 0.0.139 may already be corrupted.
agentchat doctorsurfaces it,agentchat doctor --fixrepairs it. Called out in the README.