Random pipes

STATUS.md: a shared file for multi-agent work

When I work on a bigger task − a new feature, a Terraform change, a small PoC − I usually run it across multiple agents at once. Claude Code in one window for the code, a Cowork session in another for planning and content, sometimes Desktop Claude in a third.

The split works well until I switch between them and have to type some flavour of “where are we?” so the agent can guess. Each one has its own TODO list. None of them can see the others’. And so I end up as the human message bus, with the context windows filling up with status updates instead of actual work.

This post is about a small, file-based pattern that fixed that. One shared markdown file the agents read and write, with explicit rules about how. I’ve been using it on a 48-hour PoC build − one Cowork session on planning and content, two Claude Code sessions writing code − and it removed the “where are we?” overhead almost entirely 🙌

One thing up front: STATUS.md is per-feature, not per-repo. It’s scoped to whatever piece of work the agents are coordinating on right now − a POC, a feature branch, a migration. And it’s not git-tracked − add it to .gitignore. When the feature ships, the file goes with it.


What we’ll build

  • A single STATUS.md file that lives in the repo
  • A short protocol prompt every agent gets, telling it how to read and write the file
  • A workflow where any agent can drop in or out and pick up exactly where things were
Definition of done

The pattern is “working” when:

  • I can switch between agents without typing “what’s the status?”
  • Two agents never claim the same task at the same time
  • An agent that joins fresh (new session, compacted context) reconstructs state in one read
  • The file itself tells me, hours or days later, what was done and by whom

Bonus point: the agents know when to ask me to do something for the “Operator” class of tasks. A bonus point of that bonus point is that I know what I’m supposed to be doing next in a big task, instead of keeping contexts and statuses.


The pattern

1. Make the file

A single STATUS.md at the root of the working directory − scoped to the feature, not the whole project. If you’re working on three things in parallel, that’s three files (or three directories, each with their own). Add it to .gitignore; it’s a coordination scratchpad, not history.

Two things go in it: a table of tasks, and an append-only log. That’s it.

# Build Status

| #  | Task                       | Status      | Owner       |
|----|----------------------------|-------------|-------------|
| T1 | Scaffold the app           | done        | Claude Code |
| T2 | Define data schema         | done        | Operator    |
| T3 | Build API endpoint (T1,T2) | in_progress | Claude Code |
| T4 | Wire frontend (T3)         | pending     | Claude Code |
| T5 | End-to-end test (T4)       | pending     | Operator    |

## Notes / log
_Append a one-line entry here when you change a status. Newest at top._

- 2026-05-21 14:32 − Claude Code started T3.
- 2026-05-21 14:08 − Cowork completed T2 (templates.ts written).
- 2026-05-21 13:50 − File initialized.

Status values are pendingin_progressdoneblocked. The “Depends on” column references task IDs. The log is append-only, newest first.

This is small on purpose. Every agent has to read the whole thing on every state change, so brevity matters. Resist the urge to add columns for estimated effort, acceptance criteria, or links − put those in a separate build-list.md if you need them. STATUS.md is only the state tracker.


2. Make the agents follow a protocol

The file is useless on its own. The trick is giving every agent the same protocol prompt at the start of every session. Here’s the one I use:


Status protocol for this repo. Read STATUS.md at the start of every session, before doing anything else. It is the source of truth for what is done, what is in flight, and who owns what.

Before starting any task Tx: re-read STATUS.md (it may have changed). Check the “Depends on” column. If any dependency is not done, do not start Tx − flag it and stop. If Tx is already in_progress and owned by another agent, do not start it. If Tx is pending and dependencies are met, mark it in_progress, set Owner to your identity, and append a log entry.

When Tx is complete: re-read STATUS.md to catch concurrent changes, update Tx to done, append a log entry. If Tx fails or blocks, set status to blocked with a reason in the log, then stop.

Update STATUS.md with the smallest possible edit. Never edit other agents’ log entries. The Notes/log section is append-only at the top.

Acknowledge this protocol back to me before doing any work, and confirm you have read STATUS.md.


The acknowledgment line at the end is the safety hatch. If the agent doesn’t echo the protocol back, you know it didn’t internalize it. I’ve had this catch a session about once a day − usually after context compaction.


3. Make it survive context loss

This is the property that surprised me most. Agent contexts fill up. Sessions get compacted. Claude Code restarts. Cowork sessions get archived. In any of those cases, you reopen the agent, paste the protocol, and it picks up exactly where things were − because the truth lives in the file, not in the model’s head.

Compare to the alternative, which is what I used to do: paste a multi-paragraph “here’s what we built so far, here’s what’s left, here’s who’s doing what” summary into each new session.

That’s tokens you’re burning every time, and it goes stale the moment the next agent does anything.


Why it works

Four properties carry most of the weight:

Dependency blocking prevents wasted work. When an agent tries to start T4 but T3 is still in_progress, it stops and flags you. Without this rule, agents will happily start dependent tasks against stale or imagined state and produce code that doesn’t integrate.

The audit log catches problems early. I caught a real one yesterday: src/data/templates.ts disappeared between two sessions. The log showed no agent claimed to have touched it, which told me immediately it was an accidental deletion, not an intentional refactor. (Lesson learned: git init the code on minute zero in new repos − even though STATUS.md itself stays out of git. The file records intent, and git records actual file state)

One in_progress per task at a time. Two agents cannot simultaneously claim T3. If both check the file, the first to mark in_progress wins. The second stops and flags. No more “we both started the same thing in parallel” surprises.

Survives context loss. Already covered above − the file is the memory, not the model.


When not to use it

  • Single-agent workflows. The agent’s own TODO list is fine.
  • Short tasks (one session, under an hour). The file overhead doesn’t pay back.
  • Agents that don’t reliably follow file-based protocols. Some older models will skim the file and improvise. If yours does, you’ll spend more time debugging the protocol than the work. Test the acknowledgment step first – if the agent can’t echo the protocol back, it won’t follow it either.

For multi-agent, multi-hour, multi-session work − especially anything where one agent’s output is another’s input − it pays back its setup cost in the first hour 💆


Next steps and improvements

Things I’d add next time:

  • started_at timestamp column. Useful for noticing tasks that have been in_progress for unreasonably long − sign that an agent crashed mid-task and never updated the file.
  • Agents append protocol acknowledgment to the log on first read. Then you can see at a glance which agents have actually internalized the rules this session, without asking.
  • last_compacted_at line at the top. When an agent’s context just got compacted, write it down − it explains a lot of weirdness in the next few minutes.

The open question: what about teams?

The pattern above works for one operator with many agents. But here’s what I haven’t solved: what happens when multiple humans on a team are each running their own fleet of agents on the same project?

My agents know about my STATUS.md. Your agents know about yours. Neither of us knows what the other’s agents touched until we open a PR − and by then we’ve potentially produced two incompatible implementations of the same thing, each one logically coherent within its own session.

A shared STATUS.md per repo might just shift the bottleneck − now you’ve got six agents fighting for the same five rows, and the log becomes a chat room. Per-person status files don’t compose. Something git-branch-aware? A status server with locking? A sync bot in Slack?

I don’t know yet. That’s the next post, probably, once I’ve tried a few approaches in a real team setting. If you’ve solved this − or have a strong opinion about what not to try − I’d love to hear it! ☕️


👋 Get notified about future posts

No spam. You'll receive a notification whenever I publish a new blog post.

Leave a Comment