Files
redsen-lean-harness/docs/adr/0003-worktree-lane-isolation.md
T
mozempkandCopilot 383129f571 feat: scaffold redsen-lean-harness v0.1.0
Recovered from crashed session (Node OOM). Repo contains full P0-P6
scaffold: plugin.json/marketplace.json, AGENTS.md, ADRs 0001-0006,
lh CLI (init/index/graph/lane/run/memory/host/report/doctor), 10
.github/agents, 12 CLI skills, instructions, context7 mcp.json, and
unit/e2e test suite.

Fixed: run.mjs read --in-tokens/--out-tokens but tests and CLI docs
use --input-tokens/--output-tokens, so telemetry totals were always 0.
Now accepts both forms.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 22:44:15 +02:00

2.6 KiB

ADR 0003 — git worktree per write-lane; pluggable isolation backend

  • Status: Accepted
  • Date: 2026-09-09

Context

The harness drives parallel dynamic workflows on its own: the conductor re-plans and re-fans-out at every checkpoint. Multiple builder agents therefore write code concurrently.

Concurrent writes to a single checkout corrupt work — two agents editing the same file, or one agent's partial state being read by another, produces failures that are extremely hard to diagnose and that waste far more tokens than they save.

Decision

  1. Read-only lanes share the main checkout. Recon and review never write, so they are safe to fan out N-wide with no isolation.
  2. Every write lane gets its own git worktree + branch (lh/<runId>/<laneId>).
  3. File-scope leases. Every lane declares scope globs up front. lh lane create performs a glob-intersection check against all live write lanes and rejects overlapping scopes. The check is deliberately conservative: when intersection is ambiguous, it rejects.
  4. Sequential integration. A dedicated integrator agent merges lane branches one at a time and runs one full verify. On conflict, lh lane merge does not auto-resolve — it marks the lane blocked and returns the conflicted paths for escalation.
  5. The isolation backend is pluggable — worktree (default), inplace, and a stubbed devcontainer, selected by config.isolation.backend.

Scope compliance is also a Ralph exit criterion: lh lane status reports files changed outside the declared scope, and a lane with out-of-scope changes cannot pass.

Consequences

  • Parallel writes are safe by construction rather than by convention.
  • Lanes are cheap (a branch and a worktree), so the fully dynamic re-planning model can spawn and drop them freely.
  • Merge conflicts surface as an explicit, escalatable state instead of silent corruption.
  • Worktrees require git ≥ 2.5 and a real repository. lh doctor and lh host check for this and degrade to inplace + sequential execution when unavailable.
  • Moving to per-lane devcontainers in v2 is a backend swap, not a rewrite.

Alternatives considered

  • Shared checkout with file locks — rejected: locks are advisory, agents forget them, and a crashed agent leaves stale locks.
  • Devcontainer per lane now — deferred to v2. Strongest isolation but a heavy dependency and a slow inner loop; the pluggable backend keeps the door open.
  • Read-only parallelism only — rejected: it caps the speedup at exactly the phase that is already cheap.