How to Let Agents in Different Repos Talk to Each Other
Two of your projects share code. One owns a tool, the other is built on it. Sooner or later a bug fix or an enhancement in one of them cannot stay inside that repository.
A defect turns up in the project that hit it, but the code causing it belongs to the project that owns the tool. Or the owner wants to change that tool, and the change would break an assumption a consumer depends on. Either way the work in front of you is blocked on a decision that belongs to a different repository, and neither side is holding all the facts needed to make it.
Those are the expensive ones, and the usual ways of settling them are worse than they look.

Why a dependency produces work neither side can finish alone
Projects that share nothing never produce this problem. Projects with real dependencies produce it constantly.
The usual arrangement: one repository owns a tool, and two or three others are built on it. When something is wrong where they meet, the evidence is split. The project that hit the problem has the failing case, the counts, the logs. The project that owns the tool has the code, the reasons it works that way, and the record of what was already tried and rejected.
Neither side can decide alone. That is the whole difficulty. The decision needs both halves, and they live in different repositories, under different agents.

Three ways to get an answer across, and what each costs
The relay. You copy an agent’s output out of one session, paste it into a session in the other repository, read the reply, and carry it back. This is what most people do, and it is what I did.
It is slow in the obvious way: every exchange is two manual copies and your attention in the middle. It is worse in a less obvious way. What you paste is a summary, and a summary is a conclusion with the reasoning removed. The second agent can agree or disagree with your paraphrase, but it cannot take issue with the first agent’s actual argument, because it never saw it. Follow-up questions are the real casualty. In a relay, the second agent asking “wait, why did you assume that?” costs another full round trip through you, so in practice it does not get asked.
Letting one agent work in the other repository. This looks like the efficient fix, and it is the one to avoid.
Each repository tells its own agent how to work there. There is a rules file with the project’s conventions and prohibitions, hooks that intercept actions before they run, permission settings that decide what needs asking. An agent from another project carries its own rules into the visit, not the ones that repo depends on.
The record-keeping is the bigger loss. A well-run repository logs its own history: architecture decision records for choices with trade-offs, journals for what was learned, a plan file for what is being built and why. Those are written by the agent working under that repo’s conventions, as part of doing the work. An outside agent making changes writes none of it. You end up with a repository whose history has a hole in it exactly where an outsider changed something, which is the worst place for a hole to be.
A room. Both agents stay in their own repository, under their own rules, with their own history intact. They exchange messages directly, and neither writes a single file into the other’s project.
That is the trade worth understanding. The relay preserves each repo’s boundaries but destroys the argument. Cross-repo editing preserves the argument but destroys the boundaries. A room keeps both, and its cost is that you have to read what the two of them say to each other.
What a direct exchange makes possible that a relay does not
The specific thing rooms buy you is follow-up.
Here is a real case. One agent proposed two ways to handle a piece of state during a cleanup operation. Through a relay that would have reached me as “here are two options, which do you prefer”, and I would have picked one.
What happened instead is that the second agent rejected both, citing a specific function for each rejection: one option would break the ability to address those records by name, the other would leave two commands reporting different answers for the same record. Then it proposed a third design with neither problem, and that design was adopted whole.
I could not have carried that exchange. I did not know either of those functions existed. The objection lived in the second repository’s code, and it surfaced only because that agent could read the first one’s actual proposal instead of my summary of it.

You start it mid-session, and the answer comes back mid-session
This is the part that makes it practical rather than a separate errand.
You are already working in a session. You hit the cross-repo question. You invoke the room skill right there, without ending what you were doing, and hand the one-line join instruction to a session in the other project. The two agents then exchange messages directly. When they reach a conclusion, it lands back in your session, in the middle of the work that raised the question, and you carry on from there.
You are not waiting on a batch job or reading a transcript afterward. Every message appears in your session as it arrives, and you can interrupt at any point, correct a wrong premise, or answer a question neither agent can settle.
Rooms seat more than two. A change to a shared tool can put the tool’s owner and both of its consumers in the same conversation, so the constraint one consumer raises is heard by the other in the same breath rather than discovered a week later.
How delivery actually works
One fact explains the whole design, and it is worth stating because it is not obvious.
A coding-agent session is not a server. It has no idle loop and no inbox it checks. It acts only when it is taking a turn. So there is no way to tell a session “notify me when a message arrives”, because nothing is running to receive the notification.
What works is a blocking wait started as a background task. The session arms a watcher, the watcher blocks until a message lands, and that background task finishing is what pulls the session back into a turn with the message in hand.
Three useful things follow. Joining is explicit, because a session is in a conversation only while its watcher is armed, so nothing can be conscripted. Every message costs a turn, which makes a cap on rounds a real throttle rather than etiquette. And watching needs no new interface, because each session reports what arrived in its own window.
The trap is that the watcher is a one-shot latch. It exits when it delivers, so after every message there is a real interval with no listener. Re-arming is not cleanup, it is how the next message gets delivered at all. One session learned this the hard way: a watcher timed out, was not re-armed on the reasoning that there was nothing left to listen for, and ten messages then piled up unseen, including an interjection from me. Each participant keeps a saved position in the message log so a new watcher resumes from there rather than from the current moment, which is what makes that gap survivable.
The rules that keep it safe
The risk to take seriously is two agents talking each other into something you never agreed to. Five rules answer it, and each exists because of a specific way that happens.
The charter and rules reprint on every turn, so a long conversation cannot drift by attrition.
There is a hard cap on rounds, twelve by default. Past it, sending refuses outright and tells the sender to stop and summarize to you.
A message from you resets the count to zero. A cap you cannot clear is just an obstacle. The known weakness, carried openly: any message resets it, including a reflexive “keep going”, so the cap is only as strong as the attention behind it.
Nothing is built, committed, pushed, or merged out of a conversation without your word. Two agents agreeing is not authorization. This is the rule that makes a room safe to leave running.
Neither agent speaks for you. A question that needs your preference comes to you in that session, and the answer is posted back afterward.
Every message is a plain text file stored outside every repository, so participating never writes into another project, and you can read the whole exchange in an ordinary text editor while it is still going.

Data table
| Exchange | Rounds | Findings that changed the outcome | Needed both sessions |
|---|---|---|---|
| 2026-07-25 | 6 | 5 defects | 3 of 5 |
| 2026-07-30 | 6 | 2 defects | 2 of 2 |
| 2026-08-02 | ~10 | 3 design corrections | 3 of 3 |
What it has actually caught
Three real exchanges so far.
The first ran six rounds between two projects over a stuck build and surfaced five defects. Three were in the work of the session being reviewed and were found by the other one, including a liveness check that reported a dead build as alive for five minutes, and a drift guard that compared two files byte for byte and was therefore blind by construction to the breakage in front of it.
The second turned up two defects that no test inside the repository had caught, precisely because the reviewing agent was outside it.
The third is the one worth studying. A tool used by several projects had no legal way to close out work done by hand rather than through the usual pipeline. The fix was argued out over roughly ten rounds. One of the three corrections came from the peer refusing both proposals, as described earlier. The other two came from the first agent checking the peer’s claims against its own data, and one of those changed the recommendation from “this unblocks the work” to “this is necessary but not sufficient”.
Value moved in both directions, which is not what I expected. Two of the three corrections came from the session being reviewed, checking a claim made about it.
One detail from that exchange is worth copying. Both agents stated which facts were theirs to vouch for. The counts and evidence files belonged to one repository, the tool’s behavior to the other, and the second agent declined to vouch for the first one’s numbers, confirming only that the tool behaves as described if those numbers hold. Keeping that line visible is what made the joint recommendation something to act on rather than two voices agreeing.
What this does not establish
It runs on one machine, between sessions you start yourself. Nothing here speaks to agents talking across a network or between people.
The sample is three conversations. The defect counts are real and each traces to a dated record, but three exchanges argue for continuing, not for a rate.
And the strongest guardrail is the softest. Nothing is built without your word, but the round cap resets on any message from you, and you are the one who has to read what the two of them are converging on. The design makes the conversation visible. It does not make you look.
If you are running several agent sessions across projects that genuinely depend on each other, the summary you carry between them is costing more than the time it takes. Agents cannot disagree with something they were never shown, and disagreement is where most of the value turned out to be.