Skip to content
← Back

Lesson 3 of 6

Isolate worktrees, ports and secrets

Give every parallel worker its own Git worktree, branch, Vite port, and gitignored placeholder secret so two workers cannot overwrite files or verify the wrong app.

A subagent is a child session, not a separate checkout

Isolation is manual Git, not an OpenCode multi-agent API. A subagent runs as a child session of the same project and shares the working directory unless you point it at another one. OpenCode documents no worktree manager and no parallel-agent scheduler. OPENCODE_EXPERIMENTAL_WORKSPACES is labelled experimental on the CLI page — do not use it as the isolation mechanism here. OPENCODE_ENABLE_PARALLEL enables Parallel web search tools, not extra agents.

What is built-in: start OpenCode on a directory (opencode /path/to/project in the TUI; opencode run --dir <path> non-interactively) and permission.external_directory (default ask) to gate paths outside that directory. Those flags point and gate. Git creates the isolation. One worktree, one branch, one port, one secret file per worker — if any cell repeats, isolation is broken.

Create one worktree and branch per worker

A worktree cannot share a branch with another worktree. From a clean, committed baseline (official option order: -b then path):

cd ~/agent-lab/task-tracker
git status --short && git log --oneline -1
git worktree add -b feat/due-dates ../tt-due
git worktree add -b feat/tags ../tt-tags
git worktree add -b feat/search ../tt-search
git worktree list

If Git says a branch is already checked out, you reused a branch — make a new one. Each worktree needs its own npm install; node_modules is not shared. The committed opencode.json and AGENTS.md appear in each worktree. Copy and adapt TASK.md.example to TASK.md there before starting a worker. Open OpenCode inside the worktree after its task brief is ready:

cd ~/agent-lab/tt-due
opencode --agent Agent-DUE

or opencode ~/agent-lab/tt-due --agent Agent-DUE. The TUI takes a project path as an argument. --dir is the flag on opencode run / attach, not a substitute for a missing worktree. When a branch is merged and finished: git worktree remove ../tt-due then git branch -d feat/due-dates.

Give each running app a port that fails if taken

Vite’s default port is 5173. If that port is busy, Vite tries the next one unless strictPort is set — then it exits. That exit is what you want. Two workers on one port can “verify” each other’s app. Assign ports in the plan and start with a hard fail:

cd ~/agent-lab/tt-due
npm run dev -- --port 5174 --strictPort

Use 5175 for tags, 5176 for search, 5173 for the integration checkout. Confirm each URL loads independently. Then start a second server on 5174 and record that it exits instead of hopping. Kill stray servers before you trust a browser check. --strictPort is a Vite server option, not an OpenCode feature.

Keep secrets untracked, per worktree, and fake

The tracker needs no real key. Practise the habit with a placeholder only:

printf 'VITE_LAB_FLAG=ll_lab_placeholder_not_a_real_key\n' > .env.local
git check-ignore -v .env.local
git status --short

.env.local must not appear in git status. Vite exposes VITE_* to client code and warns that those values must not hold secrets — they are compiled into the bundle. OpenCode’s default read permission denies .env and .env.* (.env.example allowed). Treat that as a safety net. Never paste a real key into a prompt. /share publishes a public transcript to anyone with the link; leave sharing on manual or disabled. If a real key is committed, rotate it first, then remove it from history — deleting the file is not enough.

Sources

How did this lesson go? Give feedback →