Patterns for the Agentic Age

Every message your agents send passes through one piece of software. It should be the dumbest thing you build.

Wire agents to each other directly and every one of them has to know every other one's inbox. One rename breaks the mesh. A post office fixes the wiring. What makes it trustworthy is the part people skip: the postmaster is a shell script, and it has no opinions about your mail.

Scripts for mechanics. Agents for judgment.

The postmaster is a shell script, and it has no opinions about your mail.

Picture a city with no post office. Every resident has to memorize every other resident's home address. Add one new resident and the whole city updates its address books. One person moves and every letter to them bounces. That is a multi-agent system wired directly, agent to agent, and it collapses under its own connections as it grows.

The fix already exists, and you use it every day. You do not know where anyone lives. You know one address, the post office, and you write a name on the envelope. A sorting facility does the rest. The mail carrier does not read your letter. The carrier does not decide whether the recipient deserves it. The carrier does not improvise a better route. That is not a limitation of the postal system. That is the whole reason you trust it with something that matters.

This page applies the same pattern to agents: one shared outbox, one registry, one routing script. That is the through-line for everything below. Each piece of judgment removed from the mail path buys a guarantee that no amount of prompt engineering would have bought.

01

The one rule: an agent never touches another agent's inbox

An agent never writes to another agent's inbox. It writes to one shared outbox and walks away. That one restriction is what makes everything else in this system possible.

The sender's job ends the moment the message hits the outbox. Addressing, permission checks, delivery, logging and failure handling stop being every agent's problem. They become one script's problem, in one place. Wire agents directly instead and each one has to know every other one's address; add an agent and every other agent's wiring changes. Route them through one shared outbox and each agent knows exactly one destination. The outbox is a directory. The message is a file.

The path of one message
1

Write

Sender drops a message in the shared outbox.

2

Look up

Postmaster reads the registry to find the recipient's inbox.

3

Check

Postmaster confirms the sender is allowed to write to this recipient.

4

Deliver

Message moves to the recipient's unread inbox.

5

Log

Every action appends one line to the delivery log.

This is the hub shape → Agent Architecture names how hub shapes break
02

The postmaster is a shell script, not an agent

This is the spine of the whole system, and it should read like one. Moving a file from one folder to another, based on a lookup table, contains no judgment. An LLM doing that job is a slower, pricier, less reliable version of ten lines of shell.

Because the router has no judgment, it can be stateless. Because it is stateless, it is safe to call at any time, any number of times. It runs on a schedule; any agent that cannot wait for the next cycle just calls it directly. That escape hatch exists only because nothing is stored between runs. An agent-based router could not offer it.

This rule will not tell you exactly where the boundary sits in a harder case. It tells you that the boundary exists, and that most systems draw it far too generously in the agent's favor.

Why this matters

If a step has exactly one correct output for a given input, it is mechanics, and mechanics belong in code. Every deterministic task handed to an agent instead is a slower, pricier, less predictable version of a script.

NO JUDGMENT REQUIRED
The same restraint, one level up → The Conductor Pattern
03

The registry is the wiring diagram

The registry is an address book with one entry per agent.

Two moves make it more than that. The accepts_from field is a security filter. Permissions live in the same file as the wiring, and the postmaster rejects unauthorized mail before it ever reaches an inbox. The emits field means an agent declares not only what it receives but what it sends and to whom. That turns the address book into a complete map of every message flow in the system, readable in one sitting.

Wire the system by editing a declaration, not by editing agents. Registration happens at setup, not at runtime, so the registry stays a stable, auditable thing you can read at any moment to know exactly what exists.

# one agent's entry in the registry
- id: council.product-agent
  address: product-agent@council.internal
  inbox: ~/.dna/post-office/inboxes/council.product-agent
  accepts:
    - type: council.evaluate
  accepts_from:
    - orchestrator@council.internal
  emits:
    - type: council.vote
      to: orchestrator@council.internal
this line is the payoff
Declaration over modification, at team scale → The Handoff Graph
04

The audit trail nobody has to write

Every record in this system is a byproduct of doing the work. Nobody has to remember to write it down.

The message ID is a hash of the message body, injected at delivery. The sender cannot set it, for the same reason a Git commit cannot contain its own commit hash. That single choice makes the message self-validating, makes duplicates collapse automatically, and removes the need for any shared counter, UUID service or coordination.

Every message in one run shares a correlation ID. The postmaster numbers them by send time. Filter the log by correlation ID, sort by sequence, and the run reconstructs exactly. It is git log for a single pipeline.

An agent acknowledges a message by moving it from unread to read. The acknowledgment and the audit trail are the same act. Nothing is deleted.

The pattern underneath

Identity derived from content, not assigned by a coordinator, removes a whole class of distributed-systems problems. No central counter to contend on. The content is the ID.

A message to an unknown address, or from an unauthorized sender, does not vanish. It lands in the dead-letter queue with the reason recorded. Silent loss is the worst class of bug there is, a phone that rings with nobody picking up and neither side knowing it happened. This system cannot produce it.

DELIVERED → moved to read/
UNDELIVERABLE → dead-letter/, reason recorded
~/.dna/post-office/
  agent-registry.yml        # the address book
  outbox/                   # agents drop mail here, never in inboxes
  inboxes/
    council.product-agent/
      unread/              # new mail, not yet processed
      read/                # processed, the audit trail
  dead-letter/              # undeliverable mail, never lost
  logs/
    delivery-log.jsonl      # one line per routing action
  scripts/
    postmaster.sh           # the router, run by cron
Silent loss, named and guarded → Failure Modes

The principles that travel

Each card below is a place where taking a decision out of the system bought a guarantee. None of them are specific to agent mail.

One address, not N

Route through a hub and each part knows one destination. Wire directly and every part must know every other, and the mesh breaks on the first change.

Mechanics to code, judgment to agents

If a step has one correct output for a given input, it is mechanics. An LLM there is a slower, pricier, less reliable script.

Declaration over modification

Each part declares what it accepts and emits, so the system is assembled from declarations and integration is a config change.

Identity from content

Hash the content for its ID instead of assigning one from a coordinator. Self-validating, deduplicating, free of shared-counter contention.

Fail loud, never silent

Undeliverable mail goes to dead-letter with a reason. Make every failure leave a trace.

Acknowledge by moving

Processed work moves from unread to read. The move is the acknowledgment and the audit trail at once, with nothing deleted.

The Post-Office Pattern is one piece of a larger body of work on agentic systems.

Browse all patterns