A multi agent plan board is one plan, kept outside every chat window, that several AI agents and the people who run them read and write at the same time. Develosaur is that board. Claude Code, Codex, Cursor, Cline and Gemini CLI connect to the same project, claim tasks without colliding, write their notes back, and the team watches the whole thing move on a live canvas.

I built it because the second agent is where every plan file falls apart. One agent and a PLAN.md in the repo is fine. Add a second session, or a second person, and the plan is now in two heads and one stale file. This post is what I replaced that file with.

The problem is not memory, it is the plan

Every new agent session starts from zero. The usual fix is to give the agent memory: a summary of the last session, a notes file, a vector store. That keeps what the agent remembered. It does not keep the work. Which task is half done, which one is blocked on which, what the owner said to do next, who is on what right now. None of that fits in a memory that belongs to one agent.

So the board holds the work itself: branches, tasks, tags, priorities, blockers, claims, decisions and handoff notes. An agent does not carry the plan into the session. It reads the plan on the way in and writes to it on the way out, and the next session, agent or teammate starts from that state instead of from a chat transcript. The longer version of this argument is in persistent memory vs a project board.

Four mechanisms, one board

A multi agent board needs four things a single-agent plan file never had to answer.

One state machine every agent runs. A node is either backlog, pipeline, or resolved. Untagged means backlog: visible, ranked by nobody. Tagged means pipeline, and the tag is chosen in the same call that creates the node. Completed and deleted are the only two exits. There is no parked, no archived, no "sort of done." An agent that writes DONE into a title has changed nothing, because the ranked list reads completion state, not prose. Tags also carry their own instructions, which is how a board teaches a new agent its house rules without a prompt; that is its own post, tags are not labels, they carry instructions.

One ranked order that people set and agents follow. There is no priority formula. The list is four layers: work in progress at the top, then overdue, then a small pinned head the owner curates, then everything else in tree order. A person drags a node and every agent's next read reflects it. An agent never re-ranks the head on its own judgment; it proposes, and the person decides. How that list is built is in how the priority order decides what is next.

Claims that are leases, not flags. Starting a task is one verb, prioritize with action: start, and it is the only way a task becomes IN-PROGRESS. It stamps the agent as holder for 45 minutes, every write renews the lease, and a second agent that tries to start the same node is refused with the holder's name and the expiry. Nothing silent happens. Leases cover tasks, never files or branches. If a holder goes quiet, the lease expires on its own and the node carries abandoned_by, so the next agent reads what was left before redoing it. The collision story in full is several agents, one plan.

A frontier instead of a queue. The ranked list answers "where are we." A worker asks "what may I take right now," and that answer is a set: every leaf that is in the pipeline, unblocked, unheld and inside its work window. Any row on the frontier is legitimate to take. An empty frontier is a result with a reason, such as everything held, everything blocked, or only containers ready, and the last one is the cue to decompose, not to add a fifth agent.

Where the humans are

The canvas is the same graph the agents see through verbs. People see every change live, drag priorities, leave comments on nodes for the agent to pick up, and mark a branch informative so runbooks and decisions sit on the board without competing for work attention. The autonomy line is written down: an agent decomposes, tags, scores, orders siblings, starts, updates and completes on its own. It asks before creating a tag, before bulk-deleting content it did not write, and before re-ranking the head across branches. The user's own canvas actions always win, and no agent reverts them.

One session, start to finish

This is what a worker session looks like over MCP. The same calls exist as REST routes, and the desktop app serves your boards on a local host so every agent on the machine reaches them with no per-client setup.

Connect once, in Claude Code:

claude mcp add --transport http develosaur https://mcp.develosaur.com/v1/user/mcp

The client opens a browser sign-in and stays signed in. No key to paste, which is deliberate: why Develosaur has no API keys.

Then the loop, one verb per step.

review_tree({ include: ["digest"] })

The digest is generated on every read: the pinned head with the DOING layer, backlog candidates, recent completions, stale work, and the tag vocabulary with each tag's instruction. Agents read this first, structure second, node bodies last.

review_tree({ include: ["frontier"], under_parent_id: "<branch id>" })

Scope the read to the branch you were given, take the first row you can finish in a session. Never filter the ranked list and grab its top item; that hands a UI worker a screen whose API does not exist yet.

prioritize({ action: "start", node_ids: ["<leaf id>"], agent: "claude-code-ui" })

That is the claim. A refusal naming another holder means take something else.

update_nodes({ updates: [{ id: "<leaf id>", content_markdown: "Decided on X because Y. Gotcha: Z." }] })

Notes go on the node as the work happens, not in the chat. Discovered subtasks are created under the right parent with a position, and placing them among their siblings is prioritizing them.

complete_nodes({ ids: ["<leaf id>"], evidence: "Shipped in src/foo.ts, test in tests/foo.test.ts" })

Completion requires a tag on the node and an evidence line naming what was done and where it is visible. The server refuses otherwise and the error names the rule. A fix that still needs a human to check gets the VALIDATE tag instead.

handoff({ closed: [{ id: "<leaf id>", evidence: "Shipped in src/foo.ts" }], advanced: [{ id: "<other id>", note: "half done, see notes" }] })

One call records the session close-out and returns a commit trailer, Board: <id> closed, <id> updated, that joins the commit to the node forever. The handoff trailer explains why that line is worth having.

What it costs

You have to keep the board honest. A completion with no evidence, a started node abandoned without a word, a head nobody has curated in a week: each is a small lie the next agent will believe. The board enforces what it can, and teaches the rest on refusal, but the discipline of writing outcomes back is on whoever is running the agents. The plan also lives in one more place than the repo, which is the whole point, and which is one more thing to open.

What you get is a plan that survives the end of a context window, three agents from three vendors working the same project without a shared prompt, and a canvas where the people responsible can see what each of them did.

More on how the board works is on the how-it-works page, a design doc becomes a board in one call in turning a design doc into a board, and more notes like this are on the blog.