Aug 30, 2026 Human-AI Collaboration

Eight Lanes

Most of what gets written about working with AI is about one person and one model. I have written some of it myself: building a music app, shipping a Mac app, designing a platform without opening Figma. That work is real and I would defend all of it, but it shares an assumption that stops holding the moment the stakes go up. One person, one session, one thread of attention.

This year I have been running eight in parallel, on a client’s global production pipeline, where being wrong costs money and someone has to sign their name to the result.

The thing nobody tells you is that the agents are not the hard part.

The problem is that nothing propagates

Parallel agent sessions do not share anything. Each one knows its own context and whatever it loads at startup, and that is all. A fact established in one session does not exist in the next. Not “arrives late” or “arrives incomplete.” Does not exist.

So every cross-session fact has to pass through you by hand, restated once per session. A correction about which language the project is actually in. A decision you made an hour ago. A hold on work that must not start yet. A finding in one lane that quietly invalidates what another lane is building on.

You become the only integration point, and the cost scales with how many sessions are running. Eight sessions is not eight times the output. It is eight times the output minus however much of your day goes into being a message bus, and that term grows faster than the first one.

That is the actual problem. Not model capability. Not prompt quality. Propagation.

Two mechanisms, because each covers what the other cannot

The fix has two halves, and the reason you need both is the interesting part.

A file every session loads at startup. Put the working method, the ownership map, the house style and any live holds in one file at the root of the workspace. Every new session picks it up automatically. This turns the protocol into a standing instruction instead of something you retype eight times a day.

Its limit: it is read at session start. It does not reach a session already running.

Direct messages between sessions. A coordinating session can push a correction to its running peers right now, which is exactly what the file cannot do.

Its limit: a message lands once. A restart forgets it completely.

So the message is the stopgap and the file is the fix. Anything that has to survive a restart belongs in the file, and a direct message is only how a running session gets caught up to it. Get this backwards, which is easy, and you will spend a week wondering why the same correction keeps evaporating.

Identity has to survive the address changing

Each session has an address you use to message it. On the setup I was running, those addresses rotate. Not just across restarts, which you would expect, but within a single continuous session. One lane appeared under three different addresses in one afternoon, same conversation throughout.

If you have written down anywhere that address X is the localization lane, you now have a document that is confidently wrong, and the failure is silent.

The fix is to anchor identity to something durable. Every lane owns a declared set of files, and that is its identity. The address is just how you reach it today. Each lane declares its owned files in its first message to any peer and restates them when it reports.

The register is a plain tab-separated file. Every session appends a row on startup and whenever it reports. A script reads it and shows the newest row per lane.

Three rules make it work, and the third is the one people get wrong:

  • Append-only. Re-appending is the update.
  • Nobody ever rewrites the file or deletes another lane’s rows. It is the one file every session writes to, and that only works because nothing ever rewrites it.
  • A stale row is normal. An old address is not evidence a session ended. It is evidence the session has not checked in since.

The report, and the trigger that matters

Five fields: unit, status, verify result, demo path, blockers. A blocker has to name what it is blocked on and who can unblock it, because “blocked” without a named dependency is just “open” wearing a hat.

Reports go out on three triggers. Two are obvious: on finishing something, and on getting stuck.

The third is the one that earns the whole protocol its keep. Report whenever you learn something that changes another lane’s assumptions. That is the case that previously had no route at all except through me, and it is the one where the damage compounds silently while everyone keeps working.

One thing worth stating explicitly, because it decides whether any of this is worth doing: reporting is not asking permission. A report says what happened. It does not wait for a reply. The moment a coordinating session starts approving other sessions’ work, you have replaced one bottleneck with a slower one, and you have also stopped getting the parallelism you built the whole apparatus for.

What went wrong in the first hour

Within an hour of the protocol going in, two lanes independently put two different menus of proposed next work in front of me for the same decision.

That is precisely the confusion the coordinating lane exists to prevent. It happened immediately, and it is in the record as the founding example rather than quietly fixed, because it is the clearest demonstration available of what goes wrong without a routing rule. The resolution was the rule: proposals for what to do next go through one lane, which puts a single menu to the human. Everything inside a chosen piece of work stays with the lane that owns it.

But the detail I keep coming back to is which menu won. It was the one from the lane that had read the entire workspace first, not the one from the coordinating lane whose job it nominally was.

The routing rule decides who presents the menu. It does not decide whose thinking wins. Those are different questions and it is worth keeping them apart, because conflating them is how a coordination layer turns into a promotion.

The standard that caught the thing everyone believed

Partway through I changed what a test criterion is allowed to be.

A criterion names what would falsify the claim and where the evidence is.

In code that means an assertion, a file and line, and the artifact demonstrating it. A criterion that names only a behaviour, “it works”, “the output is correct”, cannot be checked. And something that cannot be checked is not a criterion. It is a hope with a checkbox next to it.

This was not a philosophical exercise. A line in a README recorded a rule as a behaviour rather than as a location. The rule turned out to be implemented in four separate places, only one of which had ever executed, and a second lane reasonably inferred the wrong one. An afternoon went into unpicking it across two lanes.

Applying the new standard to the same component produced the finding that mattered most that month: it had never run. Not in testing, not anywhere. The code was written, the contract on either side of it was checked in isolation, and the call site had never once executed. Under the old standard it read as working. Under the new one it read as three verified items and a large silence.

Two lanes reasoning from the same conversation produce confident, matching errors. Two lanes reasoning from separate artifacts is the check that actually works. If it matters, make the second lane verify from a different source than the first one used.

What this is really about

There is a version of this essay that is about productivity, and it would be a worse essay. Eight agents did not make me eight times faster and I would not claim it in a room where anyone could check.

What the apparatus bought was something else. It let the work proceed without me in the middle of it, and it made the output checkable, which for this kind of work is the only property that finally matters. A pipeline that produces plausible artifacts nobody can verify is not an asset. It is a liability with good formatting.

Which is the same thing I have been circling for twenty years from a different direction. Social Trust Anchors asks how you establish trust in information when the source of any claim is increasingly opaque. That was about the open internet. This is the same question with the opacity moved inside the building: the source is a machine you are directing, the claims are arriving faster than anyone can read them, and someone still has to sign their name.

The answer turns out to be unglamorous and portable. Say in advance what would prove you wrong, and say where you would look.


The protocol is written up in full, including the parts that went wrong, at lanes. Client material is stripped; what remains is the mechanism and the reasoning.

← Back to aboutface.io