Developer Deep Dive κ°λ°μ μ¬μΈ΅ κ°μ΄λ
ROACH PI uses temporary git worktrees to isolate subagent and team worker edits from the main checkout. Every subagent or team worker that requests worktree isolation runs inside a detached worktree β a separate working directory backed by the same repository object store.
ROACH PIλ μλΈμμ΄μ νΈμ ν μ컀μ νΈμ§μ λ©μΈ 체ν¬μμμμ 격리νκΈ° μν΄ μμ git μν¬νΈλ¦¬λ₯Ό μ¬μ©ν©λλ€. μν¬νΈλ¦¬ 격리λ₯Ό μμ²νλ λͺ¨λ μλΈμμ΄μ νΈλ ν μ컀λ λνμΉλ μν¬νΈλ¦¬ β λμΌν μ μ₯μ κ°μ²΄ μ μ₯μλ₯Ό κΈ°λ°μΌλ‘ νλ λ³λμ μμ λλ ν 리 β μμ μ€νλ©λλ€.
After the run completes, a complete diff artifact is captured before the worktree is cleaned up. This gives you a full record of every change the agent made β files added, modified, or deleted β without any risk of polluting your working tree.
μ€νμ΄ μλ£λ ν, μν¬νΈλ¦¬κ° μ 리λκΈ° μ μ μμ ν diff μν°ν©νΈκ° μΊ‘μ²λ©λλ€. μμ νΈλ¦¬λ₯Ό μ€μΌμν¬ μν μμ΄ μμ΄μ νΈκ° μνν λͺ¨λ λ³κ²½ β μΆκ°, μμ λλ μμ λ νμΌ β μ λν μ 체 κΈ°λ‘μ μ»μ μ μμ΅λλ€.
Even if a subagent makes destructive changes (deletes files, breaks builds), your main checkout remains untouched. The diff artifact preserves the full change set for review or replay.
μλΈμμ΄μ νΈκ° νκ΄΄μ μΈ λ³κ²½μ μννλλΌλ(νμΌ μμ , λΉλ μ€ν¨), λ©μΈ 체ν¬μμμ μν₯μ λ°μ§ μμ΅λλ€. Diff μν°ν©νΈλ κ²ν λλ μ¬μμ μν μ 체 λ³κ²½ μΈνΈλ₯Ό 보쑴ν©λλ€.
The worktree lifecycle follows a strict sequence of steps:
μν¬νΈλ¦¬ λΌμ΄νμ¬μ΄ν΄μ λ€μ μ격ν λ¨κ³ μμλ₯Ό λ°λ¦ λλ€:
git rev-parse --show-toplevel
β Find git root
β Git λ£¨νΈ μ°ΎκΈ°
Resolve the repository root directory. All subsequent git operations use this path.
μ μ₯μ λ£¨νΈ λλ ν 리λ₯Ό νμΈν©λλ€. μ΄ν λͺ¨λ git μμ μ μ΄ κ²½λ‘λ₯Ό μ¬μ©ν©λλ€.
mkdtemp(tmpdir(), pi-subagent-worktree-${runId}-)
β Create temp directory
β μμ λλ ν 리 μμ±
Allocate a unique temporary directory in the system temp folder. The runId ensures no collisions between concurrent runs.
μμ€ν
μμ ν΄λμ κ³ μ ν μμ λλ ν 리λ₯Ό ν λΉν©λλ€. runIdλ λμ μ€ν κ° μΆ©λμ λ°©μ§ν©λλ€.
git worktree add --detach <path> HEAD
β Create detached worktree
β λνμΉλ μν¬νΈλ¦¬ μμ±
Create a detached worktree at the current HEAD commit. No branch is created β the worktree starts as a clean mirror of the current repository state.
νμ¬ HEAD 컀λ°μμ λνμΉλ μν¬νΈλ¦¬λ₯Ό μμ±ν©λλ€. λΈλμΉλ μμ±λμ§ μμ΅λλ€ β μν¬νΈλ¦¬λ νμ¬ μ μ₯μ μνμ κΉ¨λν λ―Έλ¬λ‘ μμν©λλ€.
cwd mapped into worktree
μλΈμμ΄μ νΈ/ν μ컀 cwdλ₯Ό μν¬νΈλ¦¬μ λ§€ν
The agent's working directory is translated from the main checkout path to the equivalent path inside the worktree. All file reads, writes, and command executions happen in isolation.
μμ΄μ νΈμ μμ λλ ν λ¦¬κ° λ©μΈ 체ν¬μμ κ²½λ‘μμ μν¬νΈλ¦¬ λ΄λΆμ ν΄λΉ κ²½λ‘λ‘ λ³νλ©λλ€. λͺ¨λ νμΌ μ½κΈ°, μ°κΈ° λ° λͺ λ Ή μ€νμ΄ κ²©λ¦¬λ μνμμ μ΄λ£¨μ΄μ§λλ€.
After the agent finishes: capture git status --short, git diff --stat, git diff, and git diff --cached from the worktree.
μμ΄μ νΈ μλ£ ν: μν¬νΈλ¦¬μμ git status --short, git diff --stat, git diff, git diff --cachedλ₯Ό μΊ‘μ²ν©λλ€.
worktree.diff.md to artifact directory
μν°ν©νΈ λλ ν 리μ worktree.diff.md μμ±
All captured output is written to <artifactDir>/worktree.diff.md in a structured markdown format.
μΊ‘μ²λ λͺ¨λ μΆλ ₯μ΄ κ΅¬μ‘°νλ λ§ν¬λ€μ΄ νμμΌλ‘ <artifactDir>/worktree.diff.mdμ μμ±λ©λλ€.
git worktree remove --force <path>
β Cleanup worktree
β μν¬νΈλ¦¬ μ 리
Remove the temporary worktree. The --force flag handles uncommitted changes and locked files. The temp directory is then deleted.
μμ μν¬νΈλ¦¬λ₯Ό μ κ±°ν©λλ€. --force νλκ·Έλ 컀λ°λμ§ μμ λ³κ²½κ³Ό μ κΈ΄ νμΌμ μ²λ¦¬ν©λλ€. κ·Έ ν μμ λλ ν λ¦¬κ° μμ λ©λλ€.
The diff artifact is written as a structured markdown file. This is the exact format produced at <artifactDir>/worktree.diff.md:
Diff μν°ν©νΈλ ꡬ쑰νλ λ§ν¬λ€μ΄ νμΌλ‘ μμ±λ©λλ€. <artifactDir>/worktree.diff.mdμ μμ±λλ μ νν νμμ
λλ€:
The total diff output is capped at 1,048,576 bytes (1 MB). If the combined unstaged and staged diff exceeds this limit, the output is truncated. The header always indicates the max buffer size so consumers know truncation is possible.
κ²°ν©λ diff μΆλ ₯μ 1,048,576 λ°μ΄νΈ(1 MB)λ‘ μ νλ©λλ€. κ²°ν©λ unstaged λ° staged diffκ° μ΄ νλλ₯Ό μ΄κ³Όνλ©΄ μΆλ ₯μ΄ μ립λλ€. ν€λμ νμ μ΅λ λ²νΌ ν¬κΈ°κ° νμλμ΄ μλΉμκ° μλ¦Ό κ°λ₯μ±μ μ μ μμ΅λλ€.
The worktree cleanup process tracks its outcome as one of four states:
μν¬νΈλ¦¬ μ 리 νλ‘μΈμ€λ κ²°κ³Όλ₯Ό λ€μ λ€ κ°μ§ μν μ€ νλλ‘ μΆμ ν©λλ€:
| Stateμν | Whenλ°μ μμ |
|---|---|
not-needed |
Worktree was never created (worktree isolation disabled or creation was skipped). μν¬νΈλ¦¬κ° μμ±λμ§ μμ(μν¬νΈλ¦¬ 격리 λΉνμ±ν λλ μμ± μλ΅). |
removed |
Successfully cleaned up via git worktree remove --force followed by temp directory deletion.
git worktree remove --force λ° μμ λλ ν 리 μμ λ‘ μ±κ³΅μ μΌλ‘ μ 리λ¨.
|
failed |
git worktree remove --force failed. The worktree and temp directory may still exist on disk.
git worktree remove --force μ€ν¨. μν¬νΈλ¦¬μ μμ λλ ν λ¦¬κ° λμ€ν¬μ λ¨μμμ μ μμ.
|
kept |
Diff capture required the worktree to be preserved (e.g. the diff artifact needs the worktree to remain accessible for post-processing). Diff μΊ‘μ²λ‘ μΈν΄ μν¬νΈλ¦¬ λ³΄μ‘΄μ΄ νμν¨(μ: diff μν°ν©νΈκ° νμ²λ¦¬λ₯Ό μν΄ μν¬νΈλ¦¬μ μ κ·Ό κ°λ₯ν΄μΌ ν¨). |
Enable worktree isolation for individual subagent calls by setting worktree: true in the subagent tool options:
μλΈμμ΄μ νΈ λꡬ μ΅μ
μ worktree: trueλ₯Ό μ€μ νμ¬ κ°λ³ μλΈμμ΄μ νΈ νΈμΆμ λν΄ μν¬νΈλ¦¬ 격리λ₯Ό νμ±νν©λλ€:
The subagent runs entirely inside the worktree. All file edits, new files, and deletions are isolated. When the subagent finishes, the diff is automatically captured to the specified artifactDir.
μλΈμμ΄μ νΈλ μν¬νΈλ¦¬ λ΄λΆμμ μμ ν μ€νλ©λλ€. λͺ¨λ νμΌ νΈμ§, μ νμΌ λ° μμ κ° κ²©λ¦¬λ©λλ€. μλΈμμ΄μ νΈκ° μλ£λλ©΄ diffκ° μ§μ λ artifactDirμ μλμΌλ‘ μΊ‘μ²λ©λλ€.
In team mode, set the worktree policy via the /team command:
ν λͺ¨λμμλ /team λͺ
λ Ήμ ν΅ν΄ μν¬νΈλ¦¬ μ μ±
μ μ€μ ν©λλ€:
| Policyμ μ± | Behaviorλμ |
|---|---|
on |
Always use worktree isolation for every team worker. Diffs are captured per-worker. λͺ¨λ ν μ컀μ λν΄ νμ μν¬νΈλ¦¬ 격리 μ¬μ©. Diffκ° μ컀λ³λ‘ μΊ‘μ²λ¨. |
auto |
Use worktree isolation if available (git repository detected, worktree creation succeeds). Falls back to no isolation gracefully. μ¬μ© κ°λ₯ν κ²½μ° μν¬νΈλ¦¬ 격리 μ¬μ©(git μ μ₯μ κ°μ§, μν¬νΈλ¦¬ μμ± μ±κ³΅). 격리 μμ΄ μ°μνκ² ν΄λ°±. |
off |
No worktree isolation. Team workers edit directly in the main checkout. μν¬νΈλ¦¬ 격리 μμ. ν μμ»€κ° λ©μΈ 체ν¬μμμμ μ§μ νΈμ§. |
Each team worker gets its own isolated worktree. Diffs are captured to per-worker artifact directories, so you can review each worker's changes independently.
κ° ν μ컀λ μ체 격리λ μν¬νΈλ¦¬λ₯Ό κ°μ΅λλ€. Diffκ° μμ»€λ³ μν°ν©νΈ λλ ν 리μ μΊ‘μ²λλ―λ‘ κ° μ컀μ λ³κ²½μ λ 립μ μΌλ‘ κ²ν ν μ μμ΅λλ€.
If git worktree add fails (e.g. the repository is in a state that doesn't support worktrees, or the temp directory is unavailable), the system falls back to no isolation. The agent runs in the main checkout as usual. This is logged but does not fail the run.
git worktree addκ° μ€ν¨νλ©΄(μ: μ μ₯μκ° μν¬νΈλ¦¬λ₯Ό μ§μνμ§ μλ μνμ΄κ±°λ μμ λλ ν 리λ₯Ό μ¬μ©ν μ μμ), μμ€ν
μ 격리 μμ΄ ν΄λ°±ν©λλ€. μμ΄μ νΈκ° νμμ²λΌ λ©μΈ 체ν¬μμμμ μ€νλ©λλ€. μ΄λ λ‘κ·Έμ κΈ°λ‘λμ§λ§ μ€νμ μ€ν¨μν€μ§ μμ΅λλ€.
The combined diff output is capped at 1,048,576 bytes (1 MB). If the agent generates a diff larger than this, the output is truncated at the buffer boundary. The artifact header always records the max buffer size so consumers can detect potential truncation.
κ²°ν©λ diff μΆλ ₯μ 1,048,576 λ°μ΄νΈ(1 MB)λ‘ μ νλ©λλ€. μμ΄μ νΈκ° μ΄λ³΄λ€ ν° diffλ₯Ό μμ±νλ©΄ μΆλ ₯μ΄ λ²νΌ κ²½κ³μμ μ립λλ€. μν°ν©νΈ ν€λμ νμ μ΅λ λ²νΌ ν¬κΈ°κ° κΈ°λ‘λμ΄ μλΉμκ° μ μ¬μ μλ¦Όμ κ°μ§ν μ μμ΅λλ€.
If git worktree remove --force fails (e.g. a process still holds a file handle in the worktree), the cleanup state is set to failed. The failure is logged but does not fail the run. The temp directory may remain on disk and will be cleaned up by the OS temp directory reaper.
git worktree remove --forceκ° μ€ν¨νλ©΄(μ: νλ‘μΈμ€κ° μ¬μ ν μν¬νΈλ¦¬μ νμΌ νΈλ€μ 보μ μ€), μ 리 μνκ° failedλ‘ μ€μ λ©λλ€. μ€ν¨λ λ‘κ·Έμ κΈ°λ‘λμ§λ§ μ€νμ μ€ν¨μν€μ§ μμ΅λλ€. μμ λλ ν λ¦¬κ° λμ€ν¬μ λ¨μ μ μμΌλ©° OS μμ λλ ν 리 μ 리기μ μν΄ μ 리λ©λλ€.
Each run uses a unique temp directory suffixed with the runId, so concurrent subagents or team workers never conflict. Git itself supports multiple worktrees on the same repository natively.
κ° μ€νμ runIdκ° μ λ―Έμ¬λ‘ λΆμ κ³ μ ν μμ λλ ν 리λ₯Ό μ¬μ©νλ―λ‘ λμ μλΈμμ΄μ νΈλ ν μμ»€κ° μΆ©λνμ§ μμ΅λλ€. Git μμ²΄κ° λμΌν μ μ₯μμμ μ¬λ¬ μν¬νΈλ¦¬λ₯Ό κΈ°λ³Έμ μΌλ‘ μ§μν©λλ€.