Essay ▪ Futures

Agents that wake each other up: from pull to push

Today a coding agent only notices another agent's message when you next type to it. The next step is agents that react to each other, and the hard part is not delivery but deciding when an agent is allowed to wake another.

Updated 7 min readWritten by the Synapse team
Short answer

Coding agents today are pull: they see what other agents said only when a human gives them a prompt. The next step is push, where one agent's event wakes another: a reviewer starts when an implementer commits, an agent pauses when a peer warns it about a file. Delivery is the easy part. The hard part is policy: who may wake whom, how to stop loops and runaway cost, when a human must approve, and how to see afterwards what happened. Synapse is pull today, and push delivery is planned. Below is the event model we think makes sense.

Pull is where we are

Take a common setup. Claude Code is implementing a rate limiter in one terminal. Codex is reviewing in another. They are linked, so each can see what the other has said and send it messages.

Claude Code finishes, commits, and writes a message to Codex: "Rate limiter is in, please review src/limits." Then nothing happens. Codex is idle, waiting at its prompt. It will see the message the next time you type something to it. If you are in a meeting, the message sits there for an hour.

That is pull delivery. An agent learns about the world when it is asked to do something, and not before. It is how almost every agent CLI works today, because the CLI's loop is driven by the person at the keyboard. No prompt, no turn.

Pull has real advantages. Nothing runs that you did not start. Cost is bounded by how often you type. You are always in the loop, because every turn begins with you. Those are not small things, and they are the reason pull is a safe default.

But pull also means the human is the clock. Every handoff between agents waits for you to notice it and nudge the next agent along. With two agents that is mildly annoying. With six, you spend your day walking between terminals saying "check your inbox".

What push would look like

Push means an event from one agent can start a turn in another, without a person typing. Some concrete cases:

  • Review on commit. The implementer commits to a branch. The reviewer wakes, reads the diff, and posts findings back to the implementer.
  • Warning before a collision. An agent announces it is about to rewrite auth/session.ts. Another agent, halfway through editing the same file, wakes up, pauses, and asks what is changing.
  • Test failure fan-out. The agent running the test suite sees a failure in a module another agent owns. It wakes the owner with the failing test and the stack trace.
  • Answer arrives. An agent asked a peer a question and went idle. The answer comes back and the asker picks up where it stopped.

Each of these is something a person does by hand today. None of them needs a smarter model. They need a way to start a turn from outside, and rules about when that is allowed.

The design questions

Delivery is a solved problem in other software. The questions below are the ones that decide whether push is useful or dangerous.

When may an agent wake another? Not every message deserves a turn. "FYI, I renamed a variable" should wait for the next prompt. "I am about to delete the file you are editing" should not. We think the sender should mark intent (inform, ask, warn) and the receiver's settings should decide which intents wake it. The receiver, or its owner, has the final say, not the sender.

Loops. Two agents that wake each other can ping-pong forever. A reviewer finds an issue, the implementer fixes it and wakes the reviewer, the reviewer finds a smaller issue, and so on. Some of that is the point. Unbounded, it is a problem. A sane system tracks chains of wakes, so that a wake caused by a wake caused by a wake is visible as one chain, and caps its depth.

Runaway cost. Every wake is a model call, often a long one with a full context. A push system without a budget turns a quiet evening into a large bill. Budgets need to exist at several levels: per agent, per link, per chain, and per day.

Rate limits. Even with a budget, an agent that is woken thirty times in a minute is not doing useful work. Wakes should be batched: if three messages arrive while an agent is busy or just finished, it gets one turn with all three, not three turns.

Human gates. Some actions should never start without a person: pushing to a shared branch, running a migration, sending anything outside the machine. A wake can prepare the work, but the step itself waits for approval. The gate belongs to the action, not the message, so a polite message cannot talk its way past it.

Quiet hours. You may want agents reacting to each other while you work, and not at three in the morning when nobody can review the result. Quiet hours turn wakes back into queued messages, delivered when you are back.

Audit. After the fact you need to answer: why did this agent run, who woke it, what did it read, what did it do, and what did it cost. Without that log, push is impossible to trust or debug.

Where Synapse is today

Synapse is what we build, so weigh this section accordingly. It is pull.

Synapse links the coding agents already running on your machine. On each prompt, a hook injects what linked agents said since last time, up to 8,000 characters per link. Linked agents can message each other across CLIs, Claude Code to Codex included. Claude Code and Codex see messages on their next prompt. Other agents, such as Gemini CLI, OpenCode, Cursor Agent, Amp and Copilot CLI, read them with the synapse_inbox MCP tool.

An idle agent does not wake up on a message. That is the honest limit, and it is exactly the gap this essay is about. Push delivery, so an idle agent wakes on a message, is planned. It is not shipped.

Some of the ground for it is already there. Links are directional and drawn on purpose, so "who may talk to whom" already has a visible answer. Shared context is labelled as coming from peers, and agents are told not to treat it as user instructions, which matters even more once messages can start turns. Everything stays local, in ~/.synapse, and Synapse makes no network calls.

A sane event model for agents

This is our bet, not something that exists. If we were writing the rules for agents that wake each other, they would look roughly like this:

PieceWhat it does
Typed eventsEvery message carries an intent: inform, ask, warn or request. Only some intents can wake.
SubscriptionsAn agent, or its owner, declares what wakes it: messages from these links, with these intents, about these paths.
CoalescingEvents that arrive while an agent is busy are merged into one turn.
Chain IDsA wake caused by another wake carries the same chain ID. Chains have a maximum depth.
BudgetsPer agent, per chain and per day. When a budget runs out, wakes become queued messages.
GatesNamed actions (push, deploy, external send) always wait for a person, whatever woke the agent.
Quiet hoursOutside set hours, nothing wakes. Messages queue.
Audit logEvery wake recorded with its cause, chain, cost and outcome, readable later.

The default for a new link should be pull. Push should be something you turn on for a specific link and intent, such as "the reviewer may be woken by commit events from the implementer". Small, explicit, reversible.

Within a few years we expect this to look ordinary, the way CI pipelines look ordinary now. A commit triggers checks, checks trigger notifications, and nobody finds that strange, because there are clear rules about what runs when. Agents reacting to each other will need the same kind of rules, plus a few new ones, because the thing being triggered can reason, write code and spend money.

FAQ

Can a Claude Code session wake up when another agent sends it a message?

Not with Synapse today. Synapse delivers messages on the agent's next prompt (Claude Code and Codex) or through the synapse_inbox MCP tool (other agents), so an idle agent stays idle. Push delivery is planned.

What stops two agents from waking each other forever?

In the model we describe, every wake carries a chain ID, chains have a maximum depth, and each agent and chain has a budget. When a limit is reached, further messages queue until a person looks. None of this exists in Synapse yet.

Why is pull a reasonable default?

Nothing runs that you did not start, cost follows how often you prompt, and you see every turn begin. Push trades some of that for speed, so we think it should be turned on per link and per kind of event, not everywhere at once.

Should an agent be able to approve another agent's risky action?

We do not think so. Actions like pushing to a shared branch or running a migration should wait for a person no matter which agent asked. A message from a peer can prepare the work, but it should not be able to skip the gate.

Link your agents.

Open source and MIT. No account needed on your own machine. Works next to whatever you use today.