---
title: "The Git Rules That Survive Parallel Agents"
canonical: https://dxdev.com/blog/2026-09-07_git-commit-discipline-parallel-agents/
datePublished: 2026-09-07
---
The uncommitted diff had already been sitting for eleven minutes when the second agent's edit landed on top of it and the first one just disappeared. No error, no conflict marker, nothing in the log. `git status` came back clean because there was nothing left to be dirty about.

That was the first time I ran two agents against the same working tree at once. One was mid-refactor on the script that scores drafts for leftover identifying details, hadn't committed yet, still iterating. I kicked off a second agent on an unrelated file in the same repo to save time. It touched something that triggered a checkout on its way to a clean state, and the first agent's uncommitted work went with it. No crash, no diff to recover, just a file that quietly matched HEAD again. I only noticed because the change count in my session notes didn't match what was on disk.

The fix is not clever. Every agent commits to its target branch before it yields control to a sibling, full stop, even if the change is half-finished and the message is going to look like `wip: masking pass, not done`. An uncommitted edit is not "in progress," it's unprotected state that any other process touching the tree can erase. Once it's a commit, worst case another agent reverts it and I `git log` my way back. Before that, there's nothing to revert to.

That rule caught the second failure mode almost immediately, because it forced me to look at what agents were actually putting in those interim commits. I was running a batch of doc corrections across twelve files under one ticket, parallelized so each agent grabbed a file and committed its fix. I'd told every agent, in the same prompt, no em dashes, no double-hyphens. I diffed the batch afterward anyway and found three files with fresh em dashes sitting right next to the sentence that told the agent not to use them. Not old text, added lines. The instruction was in context and got ignored anyway.

So the second rule: never trust the hard style constraints to hold on their own, scan every agent-added line for dash violations before the commit goes in. It's a five-second grep for the em dash and en dash code points on the staged hunk, but it has to happen every time, because "I told it not to" is not a control, it's a hope.

Neither of these showed up in code review, because code review checks logic, and both failures were about coordination, not correctness. The masking pass that got wiped was fine, logically. The dash violations were fine, logically, they just weren't fine at all for the actual rule set. What broke was the assumption that "the agent finished the task" meant "the state is safe" or "the constraint held." Neither is true by default when more than one process is touching the same repo or the same style guide at the same time.

The pattern that emerged out of both incidents is the same one underneath: don't let an agent's output exist only in its own head or its own working copy. Commit before yield turns an agent's progress into something durable the moment it's done, instead of something that lives only until the next process touches the tree. The dash scan turns "the agent was told" into "the agent was checked." Both rules exist because an agent doing exactly what it was asked, correctly, is not the same thing as the repo being in a state you can trust.
