Skip to content

codev adopt / launchInstance: main architect hijacks an unrelated Claude Code session instead of spawning fresh #1145

Description

@amrmelsayed

Problem

When Codev is initialized in a project that already had a Claude Code session running (claude binary already alive somewhere on the machine), the main architect launched by codev adopt (or by Tower's launchInstance on first workspace touch) does not spawn a fresh session — it appears to hijack / attach to an existing, unrelated Claude Code session as its starting point.

Reproduction:

  1. Open a project directory in VS Code (or any terminal). Do NOT initialize Codev in it.
  2. In some other context (a different terminal, a different project's session), Claude Code has an active session (persisted state on disk, potentially a running process).
  3. In the target project, run codev adopt (or trigger auto-adopt via VS Code opening the folder with codev.autoStartTower).
  4. Tower's launchInstance fires, creates the main architect terminal.
  5. Observe: the main architect's opening state is not a fresh session. It picks up prior conversation context / role state from an unrelated Claude Code session, effectively hijacking it.

Impact

  • Architect boots in a context inherited from a different project — protocols, mental model, and any prior "you are the main architect for X" instructions bleed in.
  • New workspaces don't start clean. The workspace's codev/state/main.md (per-architect notebook) and porch project state are correctly scoped, but the conversation state inside the Claude terminal is contaminated.
  • Undermines the trust that "add-architect / adopt → fresh, purpose-scoped architect."

Root cause hypothesis

Two candidate sites in the launch path:

  • packages/codev/src/agent-farm/servers/tower-instances.ts:392launchInstance. Spawns the main architect PTY. Investigate whether the launch options passed to shellper / Claude include a --resume, --continue, or session-id argument that reaches for the most-recent Claude session on the machine.
  • packages/codev/src/agent-farm/utils/harness.ts — the Claude harness config. Look for buildResume / sessionId behavior that defaults to "most recent" when no explicit id is provided.

Specifically: Claude Code CLI has a --resume flag that reattaches to the most-recent conversation on the machine by default. If the launch command builds a --resume argument without validating that the session is scoped to this workspace, it'll grab whichever conversation Claude last touched globally.

Note the pattern documented at packages/codev/src/agent-farm/utils/harness.ts:87: "no stored session id yet (codex/gemini omit it → no stale-jsonl crash-loop)." Something equivalent for Claude on fresh workspaces would prevent the hijack.

Fix sketch

Two surgical changes:

  1. Detect fresh vs resume-worthy state at launch time. For a workspace that has never registered an architect terminal before, launch Claude WITHOUT --resume (or with an explicit "new session" invocation). Only resume when there's a scoped architect row in global.db.architects with a persisted session id owned by this workspace.

  2. Verify session ownership before attach. If a session id is passed, cross-check that the session file's project-scope tag matches this workspace path. Refuse to attach to a session that references a different project directory.

Scope

  • packages/codev/src/agent-farm/servers/tower-instances.ts (launchInstance, main architect spawn)
  • packages/codev/src/agent-farm/utils/harness.ts (Claude harness resume logic)
  • Coverage: fresh codev adopt in a new workspace + concurrent Claude session elsewhere → main architect boots clean

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/towerArea: Tower server / agent farm CLI

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions