(Spine Ch. 26.)
“The bearing of a child takes nine months, no matter how many women are assigned.” Fred Brooks, The Mythical Man-Month: Essays on Software Engineering (1975), Page 17
Ticket 4 gets two patches. One for a race condition that does not exist, one for an API limit that does. Both agents are mine, both are “working,” both are billed, and neither knows the other is awake. That is a whiteboard drawing, not a war story: I have never paid that exact double bill, and the only reason is that I serialize the parts that would collide.
Bottom line: Running ten copies of the same agent in parallel is not collaboration. It’s paying ten times for the same job. Multiagent systems work when roles are hard stops: one agent researches, another codes, a third verifies. Without differentiation, you get merge chaos and no reason to parallelize in the first place.
Collaboration is division of labor with hard role boundaries. Not a wig on the same brain. Three parts:
1. Each agent has a checkable constraint that forces a different path.
Researcher can only read and retrieve. Cannot write files, cannot decide. Coder can only write, refactor, and run its own dev tests. Cannot call eval tools, cannot approve, cannot deploy. Verifier calls eval tools, approves, rejects, escalates, and cannot write code. These are not suggestions. They are architecture, and they force different work. The first time I wrote this down I gave all three agents the same tool list and then wondered why they kept producing the same answer.
A constraint that sounds like “research more carefully” is decoration. “Your tool set is {search, retrieve, summarize}” is hard. When the researcher hits “I need to write the spec,” it stops, because that is the coder’s lane. You get the handoff.
2. Each agent owns exactly one decision type or output type.
Researcher owns: “Here are the facts, sorted by confidence.” Coder owns: “Here’s the implementation. It’s correct because {dev test results, types, reasoning}.” Verifier owns: “Approved” or “Rejected, here’s why.” Deploy happens only after that approval, and never from inside the Coder.
One. Not “researcher and skeptic.” One clean output per role. The merge is structured because the outputs are role-shaped, not because someone spent three days aligning them.
3. There is always a tie-breaker and everyone knows it.
When Researcher says “fact X is true” and Coder says “I can’t implement based on that fact,” someone makes the call: Researcher owns factual validity, Coder owns feasibility, Verifier owns acceptance, and a human owns escalation. The tie-breaker must be named. Not voted on. Named. Mine for months was “Jeremy notices at 11pm,” which is not a tie-breaker, it is a hobby. What I tell people to write instead is one line in the system prompt: “you can escalate, or you can resolve this, but you cannot ignore it.” I’m not going to pretend I have a clean one to quote off a live agent yet. Everything I have running today still resolves ties by me, and migrating those is the work, not the credential.
August 8, 2026, airank. One scaling question: how do we get 1,000 ChatGPT captures a day.
Setup (the wrong way): three planners, differentiated by temperament. Fable on architecture, Opus on fidelity-first, Ponytail on the laziest thing that works. One shared tool list. One shared context. No named owner for any decision. On paper that is a council. In practice it is one brain wearing three hats and billing for all of them.
What it cost: six hours. Four rounds of reconvening. Three competing theories for the throttling, a message quota, a fingerprint verdict, and a reputation slope we had supposedly earned by behaving like a bot. All three wrong. Three separate times I had to walk in and break a tie nobody had assigned an owner to. Opus withdrew its own account-count recommendation three times, 10 to 12, then 3 to 5, then 2, and scored itself “I was wrong three times.” Good agent. Terrible architecture, and I built it.
The answer was sitting in the archive in English on every failed
page: “Too many requests. You’re making requests too quickly.”
Nobody had opened one. Two of the three kept writing cleverer
aggregations over the reason column, which is a polite way
of saying they spent an afternoon reasoning about a string our own code
had written. Fable finally pulled the stored HTML and read the
modal.
The corrected version: differentiate by tool list,
not by personality. One agent that can only fetch and read
stored capture HTML. One that can only aggregate the
reason column. One that can only reject a theory
as unsupported and say what evidence would settle it. Now the
reason-column agent physically cannot inspect a page, so its aggregation
arrives labeled as what it is, and the HTML agent physically cannot
theorize, so it comes back with the modal text or with nothing. The
rejecter has no stake in either. The cost is handoff latency and one
more round trip. The win is that the six hours become one pass, because
the blind spot is no longer shared.
The loud failure is the collision: two agents write the same file and one gets stomped. Whoever commits last wins, which is the Slashdot “first post” race run backwards with your production branch as the prize. I design against that one on principle, not from a stomped file I can name. The only conflict files I have ever swept out of those repos were Syncthing’s, not an agent’s. The quiet failure is the one that actually got me:
Same role in a wig, running in parallel, then hand-waving the merge.
You define roles as “Researcher,” “Coder,” “Verifier.” You implement them as three instances of the same system prompt with a different sentence in the preamble. Same tools. Same context. Same freedom to re-think and second-guess. When they finish you merge by consensus or majority vote. You called it collaboration. You got three monologues in a room with no one in charge. Each agent hedged because it could not see the other two. Each re-thought the problem. The “merge” is a rewrite.
That is August 8 in one sentence: temperament is not a role, and same tools means same blind spot. Evidence for the fix is in the archive itself. 22 captures got opened by hand out of 1,788 archived, selected as the failed logged-in pages and the older-era ones. 12 of 12 timestamped logged-in captures carried the modal. 10 of 10 older ones. 0 of 10 from the logged-out era, which is what made it a rate limit on the session and not a mystery. Different personalities on one tool list do not buy you three views. They buy you one view in three accents, plus the bill.
The second failure is my worry rather than my scar, and it is really one failure wearing two coats: hard roles with no written contract. You nail the constraints, then Researcher outputs prose and Coder interprets prose, and where the prose is ambiguous the guess becomes load-bearing. Same shape when the tie-breaker is assumed instead of stated: Researcher says architecture A, Coder says B is faster, and the winner is whoever finished last or talked loudest. August 8 does not prove either one; there the handoffs were fine and the tool lists were the problem. Every ambiguity I have left in a prose handoff so far has been read the way I meant it, and that is luck wearing a design’s clothes.
Do
[search, retrieve, summarize]. Coder
[write, refactor, run_dev_tests]. Verifier
[eval, approve, reject, escalate]. Deploy is gated on
Verifier approval and lives in nobody’s default list.{ticket_id, root_cause, evidence_uri, confidence, severity}.
Coder to Verifier:
{ticket_id, root_cause, diff_uri, dev_tests_passed, assumptions[]}.
Rejection path back:
{ticket_id, verdict: "rejected", failing_check, what_would_settle_it},
which goes to whoever owns that fact, not to whoever is idle.evidence_uri beats a prose summary of the evidence, because
the next agent can open it and August 8 is exactly what happens when
nobody does.Don’t
Ch. 25 (Do It at the Same Time) made the case for parallelization: independent work, same clock, cheaper wall-clock time. This chapter constrains it: parallelization only wins if you have roles. Ch. 20 gives each role a measurable stop condition so “I hand off when” is checkable, and Ch. 44 argues for an eval per role rather than one end-to-end score, which is what makes a Verifier’s rejection mean something. Ch. 27 (The Merge From Hell) assumes role-shaped outputs and takes the other half: combining them when they’re done. Spread the work (25), give it roles so it doesn’t collide (26), then merge (27), which turns out to be most of the job.
Thesis is Jeremy’s operational pattern (roles are tool sets and output ownership, not prompt variance): argument, not citation.
Verified:
~/Projects/airank/blog/2026-08-08-the-council-and-the-unread-modal.md.
Three planners (Fable, Opus, Ponytail) differentiated by temperament
rather than tool access, six hours on one scaling question, four rounds
of reconvening, three competing wrong theories (message quota,
fingerprint verdict, reputation slope). Ground truth sat in 1,788
archived captures as a plain-English “Too many requests” modal; 22
captures inspected by hand, confirmed in 12 of 12 timestamped logged-in
captures and 10 of 10 older ones, 0 of 10 from the logged-out era. Three
owner interventions to break unassigned ties. Opus withdrew its
account-count recommendation three times, 10 to 12, then 3 to 5, then 2,
and scored itself “I was wrong three times.” The follow-up verification
of Fable’s config-key finding used a regex that mishandled escaping,
returned absent on all eight keys, and nearly got the
correct finding filed as unsupported.Where I do not have the receipt: