Summary
- What broke:
archon workflow run reuses a worktree created from a different local checkout of the same remote repository. Two separate local clones (e.g., /Sources/bugfix and /Sources/codespace) that share the same origin remote resolve to the same codebase_id, so findActiveByWorkflow returns isolation environments from the wrong local clone.
- When it started: Present in current
dev branch
- Severity:
major
Steps to Reproduce
-
Clone the same repo to two different local directories:
git clone git@example.com:org/repo.git ~/project-a
git clone git@example.com:org/repo.git ~/project-b
-
Run a workflow with --branch from the first directory:
cd ~/project-a
archon workflow run my-workflow --branch fix/issue-123 "issue 123"
This creates a worktree under ~/.archon/worktrees/.../project-a/...
-
Run the same workflow with the same --branch from the second directory:
cd ~/project-b
archon workflow run my-workflow --branch fix/issue-123 "issue 123"
-
Actual: Archon reuses the worktree from step 2 (project-a), even though the user is working in project-b. The log shows worktree_reused pointing to project-a's worktree path.
-
Expected: Archon creates a new worktree rooted under project-b, since the user invoked the workflow from a different local checkout.
Expected vs Actual
- Expected: Each local clone is treated as a separate workspace. Worktrees are scoped to the local checkout they were created from.
- Actual: Two local clones of the same remote share one
codebase_id (derived from the remote URL). findActiveByWorkflow returns the first matching active environment regardless of which local checkout it belongs to.
User Flow
User (in ~/project-b) CLI (workflow.ts) DB (isolation_environments)
───────────────────── ───────────────── ────────────────────────────
runs workflow ──────────────▶ findRepoRoot(project-b)
→ project-b
registerRepository(project-b)
→ remote: git@...:org/repo
→ codebase name: "org/repo"
→ finds existing codebase_id ◀── (registered by project-a)
findActiveByWorkflow(codebase_id, 'task', 'fix/issue-123')
[X] → returns project-a's worktree ◀── matches codebase_id + branch
worktree_reused (wrong path!)
workflow runs in project-a ◀─ uses wrong working directory
Environment
- Platform: CLI
- Database: SQLite
- Running in worktree? Yes (Archon-managed worktrees)
- OS: macOS Darwin 25.2.0
Logs
{"level":30,"module":"clone","owner":"git@ccsgitlab:corvexconnected","repo":"bugfix","path":"...bugfix/source","msg":"project_structure_created"}
{"level":30,"module":"cli.workflow","path":"/Users/.../worktrees/Sources/codespace/archon/task-fix-cvx-5921","msg":"worktree_reused"}
{"level":40,"module":"workflow.executor","codebaseName":"git@ccsgitlab:corvexconnected/corvex-workspace","msg":"codebase_name_not_owner_repo_format"}
Note: The user ran from /Sources/bugfix but the reused worktree is under /Sources/codespace.
Impact
- Affected workflows/commands: Any
archon workflow run --branch <name> when multiple local clones of the same remote exist
- Reproduction rate: Always (deterministic when conditions are met)
- Workaround available? Yes — omit
--branch to force a fresh worktree with a timestamp-based name, or manually mark stale isolation environments as completed in the SQLite DB
- Data loss risk? Yes — the workflow operates in the wrong directory. Code changes, commits, and MRs target the wrong checkout. In our case it created an MR in the wrong GitLab project with 88 unrelated files.
Scope
- Package(s) likely involved:
cli|core|isolation
- Module (if known):
cli:commands/workflow.ts (lines 422-464) — worktree reuse lookup
core:db/isolation-environments.ts (findActiveByWorkflow) — query lacks local-path scoping
core:handlers/clone.ts (registerRepository) — two local clones get the same codebase_id
Root Cause Analysis
The remote_agent_codebases table uses the remote URL to derive the codebase identity. When two local directories point to the same remote, registerRepository returns the same codebase_id for both. The findActiveByWorkflow query then matches isolation environments across both local checkouts since it only filters on codebase_id + workflow_type + workflow_id.
Suggested Fix
The worktree reuse check in workflow.ts (line 426) should validate that existingEnv.working_path is rooted under the current cwd's worktree namespace before reusing it. For example:
if (existingEnv && (await provider.healthCheck(existingEnv.working_path))) {
// Verify the worktree belongs to THIS local checkout, not a sibling clone
const expectedPathPrefix = cwd; // or derive from the worktree naming convention
if (!existingEnv.working_path.includes(basename(cwd))) {
getLog().warn(
{ path: existingEnv.working_path, cwd },
'worktree.reuse_different_checkout'
);
// Fall through to create a new worktree
} else {
// existing reuse logic
}
}
Alternatively, registerRepository could incorporate the local path into the codebase identity (e.g., use default_cwd as part of the uniqueness constraint instead of just the remote URL), but this is a larger change with broader implications for the codebase registry.
Summary
archon workflow runreuses a worktree created from a different local checkout of the same remote repository. Two separate local clones (e.g.,/Sources/bugfixand/Sources/codespace) that share the sameoriginremote resolve to the samecodebase_id, sofindActiveByWorkflowreturns isolation environments from the wrong local clone.devbranchmajorSteps to Reproduce
Clone the same repo to two different local directories:
Run a workflow with
--branchfrom the first directory:This creates a worktree under
~/.archon/worktrees/.../project-a/...Run the same workflow with the same
--branchfrom the second directory:Actual: Archon reuses the worktree from step 2 (
project-a), even though the user is working inproject-b. The log showsworktree_reusedpointing toproject-a's worktree path.Expected: Archon creates a new worktree rooted under
project-b, since the user invoked the workflow from a different local checkout.Expected vs Actual
codebase_id(derived from the remote URL).findActiveByWorkflowreturns the first matching active environment regardless of which local checkout it belongs to.User Flow
Environment
Logs
{"level":30,"module":"clone","owner":"git@ccsgitlab:corvexconnected","repo":"bugfix","path":"...bugfix/source","msg":"project_structure_created"} {"level":30,"module":"cli.workflow","path":"/Users/.../worktrees/Sources/codespace/archon/task-fix-cvx-5921","msg":"worktree_reused"} {"level":40,"module":"workflow.executor","codebaseName":"git@ccsgitlab:corvexconnected/corvex-workspace","msg":"codebase_name_not_owner_repo_format"}Note: The user ran from
/Sources/bugfixbut the reused worktree is under/Sources/codespace.Impact
archon workflow run --branch <name>when multiple local clones of the same remote exist--branchto force a fresh worktree with a timestamp-based name, or manually mark stale isolation environments ascompletedin the SQLite DBScope
cli|core|isolationcli:commands/workflow.ts(lines 422-464) — worktree reuse lookupcore:db/isolation-environments.ts(findActiveByWorkflow) — query lacks local-path scopingcore:handlers/clone.ts(registerRepository) — two local clones get the samecodebase_idRoot Cause Analysis
The
remote_agent_codebasestable uses the remote URL to derive the codebase identity. When two local directories point to the same remote,registerRepositoryreturns the samecodebase_idfor both. ThefindActiveByWorkflowquery then matches isolation environments across both local checkouts since it only filters oncodebase_id + workflow_type + workflow_id.Suggested Fix
The worktree reuse check in
workflow.ts(line 426) should validate thatexistingEnv.working_pathis rooted under the currentcwd's worktree namespace before reusing it. For example:Alternatively,
registerRepositorycould incorporate the local path into the codebase identity (e.g., usedefault_cwdas part of the uniqueness constraint instead of just the remote URL), but this is a larger change with broader implications for the codebase registry.