
Branch hygiene with agents
When worktrees beat single-branch. The merge etiquette nobody taught you.
What goes wrong
Most teams adopted git when one human worked one branch at a time. The mental model was: feature branch, pull request, review, merge. Linear, slow, careful.
Agentic work breaks that mental model in three ways. One: agents move faster than humans, so branch age compresses. Two: agents work in parallel — sometimes two agents in the same repo at the same time. Three: agents will happily run irreversible operations (force-push, history rewrite, branch delete) without the instinct that says “wait, ask first.”
Branch hygiene with agents is not the same discipline as branch hygiene with humans. The patterns I’m about to lay out come from running QC firmware (multi-agent, parallel, week-cadence) and Parley research (single-agent, serial, month-cadence) in the same operator brain. Same git, different rules.
The branch ladder — match lifetime to work
Pick the rung that matches your work. Don’t over-engineer; don’t under-engineer. Each rung has a specific failure mode it prevents.
| Rung | When | Pattern | Failure it prevents |
|---|---|---|---|
| 0. Main only | Throwaway scripts, one-off explorations, no production stakes | git commit -am “...” | None. This is the “I accept the risk” rung. |
| 1. Feature branch | Solo work, single workstream, days to a week | git switch -c feat/<scope> | Half-broken main. Bisect-blocking commits. |
| 2. Worktree | Two agents, same repo, different scope (QC firmware + sensor bench) | git worktree add ../<repo>-<scope> <branch> | Race conditions when two agents touch the same files. |
| 3. PR-gated main | Production code, any prod-bound deploy, irreversible side effects | Branch protection + required review + CI gate | Agent self-merging broken code to prod. |
| 4. Long research branch | Research cadence longer than a week (Parley monthly notebooks) | One branch per artifact, lifetime = artifact lifetime | Trying to force weekly cadence on monthly work. |
Operating rule: most code work is rung 1 or 2. Rung 3 fires when you have prod stakes (TruPath Website on Hostinger, QC live training pipelines). Rung 4 fires when the work is research and the cadence is slower than a week. Rung 0 is honest — sometimes you really are throwaway. Just say so explicitly.
Five failure patterns
Hover any card to see the diagnosis.
Everything-on-main
The forever branch
Parallel agents on one branch
The merge with no review
The detached HEAD agent
Pattern #3 (parallel agents on one branch) is the one that surprises operators new to multi-agent work. git was designed for one writer. Worktrees are the answer.
The pre-merge prompt
Before any merge to an integration branch (or main), paste the active branch into a fresh agent session with this prompt. Agent prepares the report. You read it and decide.
Walk this branch before I merge it.
1. Diff the branch against the integration target (main or feat/X).
How many files changed? Above 30 means split the merge.
2. Are all changed files in scope of the active sprint contract?
Flag any file that isn't.
3. Did any commit in this branch touch:
- Secrets / credentials / .env files
- Config files outside the sprint contract scope
- CI / CD / deploy config
- Files in folders that another agent owns
4. Run the test suite on the branch tip. Report green/red.
5. Write a one-paragraph merge note: what shipped, what's
deferred, any known limitations.
Do not run the merge. Output the report. I'll run the merge.Catches scope creep, secret leaks, and oversized merges in 60 seconds. Agent prepares; human lands.
The asymmetry — agents prepare, humans land — is the operating rule that scales. It maps directly to the cost gradient of the action: preparing a merge is cheap and reversible; landing it is irreversible. Match authority to reversibility.
QC firmware + Parley research — same git, different rules
Two real workstreams. QC firmware is a multi-track repo with parallel agent work — worktrees are the answer. Parley research is a single-track repo with monthly cadence — long branches are correct. Same operator. Different disciplines.
QC firmware vs Parley research — branch lifetime matched to work lifetime.
- operator
I want to run the QC sensor bench test (radar + ToF) in parallel with continuing v15 CV work. Same repo, two ventures of work. How do I keep them from stepping on each other?
- agent
Worktrees. The repo at
/Users/mebrenne/QuatumQaddyis onfeat/v14-harvest. Sensor bench work has nothing to do with CV work — different files, different contracts, different review cadence.Proposal:
cd /Users/mebrenne/QuatumQaddy git worktree add ../QuatumQaddy-sensor feat/sensor-bench-2026-04-25Now you have two working directories:
-/Users/mebrenne/QuatumQaddy—feat/v14-harvest, CV work continues
-/Users/mebrenne/QuatumQaddy-sensor—feat/sensor-bench-2026-04-25, radar/ToF bench workTwo agents can run, one in each, with zero risk of collision. Merge order: sensor branch closes when bench data lands; CV branch merges when Phase 0 retry passes.
- operator
Parley is different. The repo lives on
/Volumes/Code Drive/Parley/. I run one agent at a time on it, but the branches go forever — main, then weeks of notebook work, then merge. Is that wrong? - agent
Different rhythm, different rule. Parley's research cadence is one notebook per month. The branch lifecycle should match the research lifecycle:
- One branch per notebook:
feat/nb-03-tuning-study
- Branch opens when the plan ships (docs/plans/active/...)
- Branch closes when the notebook publishes to Kaggle
- Branch lifetime: ~30 daysThe fact that branches stay open for a month is fine — the cadence justifies it. What's NOT fine is running TWO notebook branches in parallel (which collapses the per-notebook discipline). One notebook at a time, branched, merged on publish.
The Parley pre-commit hook (commit
82d9f10) blocks supabase service-role + JWT patterns — that's the secret-pattern guardrail. Agents inherit it on every commit. - operator
When the QC sensor branch is done, what's the merge etiquette? Agent runs git merge?
- agent
No. Agent prepares the merge. Human runs the merge. Specifically:
1. Agent rebases the feature branch on latest
feat/v14-harvest(or whatever the integration branch is). Resolves conflicts.
2. Agent runs the test suite. Reports green/red per file.
3. Agent writes a one-paragraph merge note: what shipped, what's deferred, any known limitations.
4. Human reads the diff. Spot-checks the test output. Runs a smoke test if applicable.
5. Human runsgit merge --no-ff(or merges via PR). The non-fast-forward keeps a visible merge commit.
6. Agent updates the relevant decision log + memory entries.The split is intentional. Agents do the work; humans take the irreversible action. Force-push to main is a hook-blocked operation.
Prompt kit
Three prompts: opening a branch, pre-merge audit, weekly branch-age sweep. Save in your CLAUDE.md or personal snippets file.
I'm starting work on: <describe>
Active sprint contract: <path>
Repo: <path>
Decide:
- Is this work parallel to other in-flight work in this repo? If
yes, propose a worktree. Show me the git worktree add command.
- Is this work serial (no other agent touching this repo)? Propose
a feature branch. Show me the git switch -c command.
- Branch name: feat/<scope>-<YYYY-MM-DD> or feat/<contract-slug>.
Do not execute. Show me the commands. I'll run them.Walk this branch before I merge it.
1. Diff the branch against the integration target (main or feat/X).
How many files changed? Above 30 means split the merge.
2. Are all changed files in scope of the active sprint contract?
Flag any file that isn't.
3. Did any commit in this branch touch:
- Secrets / credentials / .env files
- Config files outside the sprint contract scope
- CI / CD / deploy config
- Files in folders that another agent owns
4. Run the test suite on the branch tip. Report green/red.
5. Write a one-paragraph merge note: what shipped, what's
deferred, any known limitations.
Do not run the merge. Output the report. I'll run the merge.List every local branch in this repo. For each, show:
- Branch name
- Days since last commit on this branch
- Days behind the integration target
- Whether the branch has an open sprint contract
Flag any branch older than 14 days without an active contract.
Those are zombie branches — propose deletion or revival.Apply this
40-minute exercise. Audit local branches, kill zombies, document merge etiquette.
Clean up branch hygiene
Each step takes 5–10 minutes. Progress saves automatically.
- 01List your local branches in your most-active repo. Identify any branch older than two weeks.Run: git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'
- 02Pick one zombie branch. Either revive it (open a contract) or delete it.Branches without contracts rot. Decide one or the other — don't leave it in limbo.
- 03If you're running parallel work — multiple agents, multiple workstreams — set up a worktree.git worktree add ../<repo>-<scope> <branch>. Each worktree gets its own CLAUDE.md if needed.
- 04Add a pre-commit hook that blocks force-push to main and blocks commits in detached-HEAD state.Both are common agent failure modes. The hook lives in .git/hooks/pre-commit or via husky.
- 05Document your merge etiquette in CLAUDE.md: agents prepare, humans land.One paragraph. Reference the pre-merge prompt above. Make sure the agent loads it on every session.