The Problem
Run agents across many repos for a few weeks and then run one honest audit. Here is what ours found, on a workspace where every individual session had done its job well: 87 repositories, 63 with findings, and 551 modified files sitting uncommitted — some touched that morning, some untouched for 97 days. Almost nothing was on main. Most repos sat parked on a long-lived agent branch from weeks ago, one commit ahead of a remote nobody had looked at since.
None of that came from a bad session. It came from many good ones. Each agent branched, worked, and finished correctly in isolation — and nothing ever reconciled what the fleet left behind. That is the shape of the problem: many projects, many agents, each correct alone, none responsible for the whole.
This matters because agents orient by reading git state. The branch name, the diff, the distance from origin — that is how a cold session decides what is safe to touch. A workspace where git lies feeds misinformation straight into every session that starts there, and the failures it produces are expensive and hard to trace:
- Work nothing can revert. Directories with a manifest and no repository at all — or worse, a husk
.gita tool left behind, directory present, repository absent. Our audit found ten. - The wrong-repo commit. An automated cleanup ran
git add -Ain a tree that also held 500 lines of a concurrent agent's in-flight work, and committed all of it to the wrong repo. Recovering took longer than the original work. - Prod and main disagreeing. A package's main said 0.2.1 while the registry served 0.2.0 — the security fixes existed, were not live, and nothing surfaced the gap.
The instinct that makes this worse: writing "always branch, keep trees clean" into your agent instructions and considering it handled. You cannot enforce procedure with an instruction file. The agent either reads it or doesn't — and the session most likely to break the rule is exactly the one that never loaded it. Enforcement lives where the wrong action fails, or it doesn't live anywhere.
The Core Insight
A clean tree is not housekeeping. It is operating environment for a fleet: when trees are clean by default, anything dirty means something — a live session, or an abandoned one, and the age of the newest touched file tells you which. When everything is dirty, nothing means anything, and every session inherits ambiguity the last one left.
The fix is norms installed into the environment rather than instructions issued to agents, in three layers, cheapest first:
- The wall — deterministic git hooks that refuse direct commits to main, installed once at the workspace level so every repo, current and future, enforces the same rule with zero per-repo setup. Costs nothing to run, forever. Any agent — and any human — meets the same refusal, and the refusal message itself teaches the fix.
- The witness — a scheduled loop that reports drift and reconciles committed work: it pushes branches that have sat quiet and opens one pull request per branch. Deterministic, token-free, and deliberately weak.
- The record — one line written at every session close: repo, branch, dirty count. The trail that turns "who left this?" from archaeology into a lookup.
The one rule that makes the whole system safe: automation never mutates a working tree it didn't make. The loop's verbs are report, push a committed branch, and open a PR — never commit, never stage, never stash, never clean. Uncommitted work is someone's desk, not litter: with concurrent sessions, no tool can know which dirty files belong to whom, so the only safe move on uncommitted work is to leave it alone. The 500-line wrong-repo commit above happened because a tool broke exactly this rule.
Prevention outranks janitorial work: the wall stops the mess forming, so the witness only ever handles finished work. And an agent's own session is the one actor allowed to commit its work — at its own boundary, when it still knows which files are its. The loop is the safety net for sessions that died, not the primary mechanism.