I Run Coding Agents in Parallel. A Markdown File Is Their Manager.
On October 11, I opened GitHub and counted four pull requests. I was expecting two. 453 and #456 fixed the same thing. So did #454 and #452. Different branches, different code, same task. Two of my coding agent
On October 11, I opened GitHub and counted four pull requests. I was expecting two.
453 and #456 fixed the same thing. So did #454 and #452. Different branches, different code, same task. Two of my coding agents had each done the work perfectly, in two separate sessions, without knowing the other one existed.
Nobody had made a mistake. That's what bothered me.
Agent A had picked the tasks and started coding. Agent B, in another terminal, had looked at the list, seen two tasks nobody had claimed, and done the reasonable thing. If two human developers did this, you'd say "they should talk to each other". Agents don't talk to each other. They don't even remember yesterday.
So I did what you do with a team that doesn't communicate: I gave them a manager. It's a Markdown file.
An employee with amnesia
Picture a brilliant developer who joins your team every morning with no memory of the day before. Doesn't know what was decided. Doesn't know what was tried and abandoned. Doesn't know who's working on what.
That's a coding agent. With one of them, you compensate: you explain again. With four in parallel, each in its own git worktree, you become a full-time switchboard operator, and the agents still step on each other.
I build i18n Support Plus, an open source JetBrains plugin, this way. As I write this, the repository is past pull request #950, and more than 500 task entries have gone through two files at its root:
-
TODO.md: what's left to do -
TODO-DONE.md: what's finished
No ticketing tool. Nothing to install. Nothing tied to one agent: anything that can read a file can join the team.
It works because of five rules. I didn't design them. I collected them, one accident at a time.
Rule 1: write the task for someone who knows nothing
Here's a real one, archived on November 8 (translated from French, shortened):
#### [TASK-CADRAGE-CONFIG-KEYSTROKE-REBUILD] Every letter typed in an open
`i18n-check.json` setting rebuilds the whole usage index
- **Added:** 2026-11-08
- **Exclusive scope:**
- `.../settings/Settings.kt`
- `.../usages/CodeUsageIndexService.kt`
- `.../usages/CodeUsageIndexServiceTest.kt`
- `CHANGELOG.md`
- **Context:** measured by #926. Typing `node_modules` in the excluded
directories field triggers twelve full rebuilds, about 18 s each on
300 files, with the CPU spinning.
- **Expected:** unsaved content is only read after a typing pause;
a rebuild in progress is cancelled when the state changes again.
- **Expected tests:** a burst of ten keystrokes = one rebuild.
Look at the title: it's the defect, in one sentence. Look at the context: a measurement, not an impression. An agent can pick this up cold and never ask me a question.
It's also, I realized later, just a well-written ticket. Agents didn't need anything exotic. They needed what my human colleagues had been asking for all along.
Rule 2: one task, one territory
This is the rule that makes everything else possible.
Two tasks of the same priority never touch the same files. That's the "exclusive scope" line above. If two file lists overlap, one task moves to another priority level.
Once that's true, parallel work stops being a coordination problem. I say "work through priority 2", the agents leave in a wave, each on its own files, and there is nothing to arbitrate because there is nothing to collide on.
The parallelism isn't decided when the agents start. It's decided when the tasks are written.
Rule 3: say "mine" before you touch anything
An agent that takes a task writes IN PROGRESS in front of its title. The others skip it.
You already know how I learned that the timing matters. The mark is worthless if it goes on after the first line of code. It has to be the very first thing the agent does, the way you say "I'll take it" in a meeting before opening your laptop.
Since October 11, there's a second check before any wave: look at the open branches and pull requests. Trust, but verify.
Rule 4: finished means gone
The natural reflex is to leave a completed task in the file with a nice green check mark. It feels good. Look at all that progress.
Now look at what that feeling costs. Every agent reads TODO.md at the start of every session. Every finished task still sitting there gets reread, by every agent, every time, forever. You end up spending tokens so that machines can admire your check marks.
Now a finished task leaves. Its whole section moves to the end of TODO-DONE.md, and it keeps one line in a table at the top of TODO.md: what changed, which PR, what date. The archive is append-only. Agents write at the end of it and never read it.
Today TODO.md weighs 24 KB. The archive weighs 1.28 MB. Every session starts by reading 52 times less than the project's real history, and nothing was thrown away.
Rule 5: you see a bug, you write it down, you walk away
Agents are helpful to a fault. Ask one to fix a typo, and if it notices a questionable function on the way, it will "also fix" it. That's how a ten-line task becomes a four-hundred-line pull request that conflicts with three others.
So the rule is the one you'd give an eager intern. An out-of-scope problem doesn't get fixed. It gets an entry in a "to be framed" section: what you saw, which files, a possible approach, a rough cost. Then you go back to your task.
I decide what happens next. Anything marked "awaiting decision" stays untouched. That section has turned into a bug tracker of its own, with one advantage: every entry comes from someone who was looking at the code when they wrote it.
The days it failed anyway
The day my own rule blocked me. At one point, 10 tasks out of 13 needed to touch plugin.xml or the label files. Strict exclusive scopes spread them over 10 priority levels. One task at a time: I had built a very sophisticated queue. But two tasks that each add a line to the same file only create a trivial conflict. So on October 6 the rule got an exception, written at the top of the file: those files can be shared, as long as every task only adds lines.
A rule that's too strict fails as surely as no rule. It just fails slowly.
The day the agents fought over the machine. Scopes protect files. They don't protect the computer. Two worktrees share one Gradle cache, so their builds collide. And one agent's ./gradlew --stop kills the other agent's daemon in the middle of its tests.
The second agent then sees a failure that looks exactly like a regression, while its code is fine. And an agent that believes it broke something will try to fix it. Now test runs are serialized, or each agent gets its own GRADLE_USER_HOME.
The day of the four pull requests. You were there.
What I can and can't tell you
What I can tell you: more than 500 task entries, 24 KB to read at startup against 1.28 MB of history, waves of agents that don't need me to referee.
What I can't tell you: how much faster this is than no file at all. I never ran the comparison. These numbers describe how the project runs. They don't prove a gain, and I'd be suspicious of anyone who gave you one.
Here's what I believe after all this:
- An agent's memory should live in the repository, not in its session.
- Parallel work is prepared when the tasks are written. The number of agents matters less than the shape of the backlog.
- What gets read at every startup must stay small. Keep everything else, but out of sight.
- Most of what makes agents effective is what makes a team effective. We just never had to write it down this precisely.
One question before you go. If two of your agents started right now, on the same repo, with the same instruction, what would stop them from doing the same task twice?
If the answer is "me", you're the manager. Consider delegating to a text file.
This article was first published as a case study on my site, where I write about frontend architecture and coding agents in practice.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.
