The Boundary
An agent is a complete thing with one way in and one way out.
In: text, audio, images — stimuli. Out: text, audio, images, and actions.
That is the whole surface. It does not widen because the caller happens to be another agent rather than a person. Two agents talk the same way you talk to one.
What this rules out
No agent reaches into another. Concretely, none of these exist and none of them will:
- subscribing to another agent's hooks
- reading another agent's session or memory
- calling another agent's tools directly
- waiting on another agent's boot, or booting in a required order
- sharing a policy, a capsule, or a context between agents
Each of these looks like a small convenience in the moment. Each one turns two independent agents into one tangled thing that only works in a particular arrangement.
Why the constraint is worth it
Agents stay whole. Install an agent, run it, and it works — because it never assumed what else was running. That property is what makes agents publishable, deployable, and replaceable, and it evaporates the moment one agent depends on another's internals.
Location stops mattering. If the only way to reach an agent is a stimulus, then it makes no difference whether it is in this process, another process on your laptop, or deployed behind a URL. Moving an agent to the cloud is a change of address, not a rewrite. Shared scope would nail every agent to the machine it was written on.
Boot order stops mattering. Hooks fire during boot, before other agents exist — so cross-agent hook subscriptions aren't merely inadvisable, they're often impossible to satisfy. Independent boot has no such problem: each agent comes up on its own, and they interact once both are ready.
You do not synchronise a computer's startup with its monitor's. You assume both come up, then use them.
The escape hatch
There is one, and it is deliberately narrow: a tool can do anything.
If an agent genuinely needs a capability the protocol doesn't cover, a tool author can build it — including one that spawns or drives another agent. That stays contained, because it is one agent's implementation detail rather than a platform concept. The boundary holds at the platform level and the tool owns whatever it does inside.
This is what keeps the constraint from being a cage. Anything not expressible through stimuli is expressible in a tool, and the cost is that you own it.
When two agents shouldn't be two agents
Sometimes the coupling you want is a signal that you have drawn the line in the wrong place. The test:
Could this agent be published on its own, and would anyone else install it?
If yes, it is a real agent, and it talks to others through the protocol.
If no — if it exists solely to serve one caller that knows its internals — it is not an agent, it is a part of one. Make it a tool, a module, or a capsule-side subagent. Those are designed for tight coupling, and using them costs you nothing you wanted.
Reaching for cross-agent hooks usually means this question was answered wrong.
How agents actually talk
Two shapes, both ordinary:
Request. One agent sends a stimulus and waits for the result — an HTTP call to
another agent's route, or a request() through a handle it booted.
Emission. One agent emits and doesn't wait. Text, or speech frames, or images, into another agent's senses. Whether the receiving agent acts on it is a property of its cognition, not of the transport.
Both go through the front door. Neither requires the sender to know anything about the receiver except its address.
Next: The Agent Handle — what one instance gives you.