The model
July 30, 2026 · View on GitHub
Actors
Worker agents
Long-running agents, each assigned one task, each unaware of the others. A worker has three obligations and no others:
- emit a typed event when something happens that a supervisor would want to know;
- park rather than block when it needs a human decision (see state and resumption);
- be resumable from the checkpoint it wrote.
A worker never composes prose addressed to a person, never picks a delivery channel, and never decides that something is urgent enough to interrupt. It can assert urgency; the gateway decides what that buys.
The gateway agent
The only actor that talks to the human. It:
- ingests worker events into a durable queue;
- triages, deduplicates and correlates them;
- holds the approval ledger — the record of what has been asked, what has been answered and what is still outstanding;
- composes the brief and delivers it on schedule;
- decides, against policy, whether anything justifies breaching the schedule;
- relays decisions back and triggers resumption.
The gateway is an agent rather than a script because the interesting part — "these four events are the same problem", "this progress note matters and that one doesn't", "this question is answerable from what agent C already found, so don't ask" — is judgement, not routing.
The human
Receives one brief per cycle. Answers approvals. Is interrupted out of band only through the override channel, and only within budget.
Event taxonomy
The data driver is the status update. Everything a worker emits is one of six types, and the type determines how the gateway may treat it.
| Type | Meaning | Interrupts? | Work state |
|---|---|---|---|
progress | Informational. Milestone reached, nothing wanted. | Never | running |
blocked | Halted, needs an input the human has. Not a yes/no. | Only by policy | parked |
approval_request | A specific proposed action awaiting a decision. | Only by policy | parked |
escalation | Something is wrong and waiting makes it worse. | Eligible | either |
completed | Task finished, with a result. | Never | terminal |
failed | Task abandoned, with a reason. | Only by policy | terminal |
The split between blocked and approval_request earns its keep: an approval is
a closed question with a proposed answer attached, so it can be batched, put to a
voice call, and answered with one word. A block is an open question and usually
needs the human to go and find something out. They belong in different sections of
the brief and they have different failure modes when ignored.
Triage
Between intake and the brief, the gateway does six things in order. Steps 1–3 are lifted more or less directly from Prometheus Alertmanager, which solved this for monitoring a decade ago — see prior art.
-
Deduplicate. Three agents hitting the same expired credential is one item, not three. Correlate on the failing resource, not the message text.
-
Inhibit. Suppress an item when a more general one covering it is already present. Five agents blocked because a credential died is one item about the credential, not five about the agents — inhibition is what expresses that when the five events are not textually similar enough to deduplicate.
-
Apply silences. "Nothing from agent X until Tuesday" is an explicit, expiring mute the human sets. Silenced items are recorded and countable, so a silence that should have lapsed is visible rather than forgotten.
-
Retire the self-resolving. An event whose condition no longer holds by the time the brief is composed does not go in the brief. A worker that was blocked at 11:00 and unblocked itself at 11:40 produced no work for the human. This is the single largest source of noise reduction and it is only available because delivery is deferred — it is the whole argument for batching in one line.
-
Score cost of delay. Not "how urgent does the worker feel", but: what is lost by answering this at the next brief instead of now? Items with a hard external deadline, a decaying opportunity, or a spend accruing while parked score high. Most things score zero.
Scoring is one-directional within a cycle: an item that has been scored high stays high until it is answered or resolves. A later, calmer event about the same thing does not downgrade it. PagerDuty's severity handling works the same way, and for the same reason — the alternative is an item flickering out of the section the human was about to read.
-
Rank, section and decide on interruption. Decisions first, blocks second, failures third, progress last and heavily compressed. Anything that survives the escalation policy in channels goes out immediately and still appears in the brief, marked as already sent, so the brief remains a complete record of the cycle.
The interrupt budget
Each cycle carries a fixed number of permitted out-of-band interruptions — start
at three per day. When the budget is spent, nothing short of the operator-defined
critical tier gets through until it refills; everything else waits for the brief.
The budget exists because urgency is self-asserted by parties who are not impartial. Every agent believes its own task is the important one, and an LLM-based worker asked "is this urgent?" will say yes far more often than a person would. A budget is robust to that in a way that better prompting is not: it caps the damage from over-reporting without needing to detect it.
Two behaviours follow from having one:
- Spending is visible. The brief reports what the interruptions were spent on, which makes miscalibration obvious after a week rather than a quarter.
- Repeat offenders get demoted. A worker whose escalations are consistently downgraded by the human has its urgency assertions discounted. Track the ratio per agent, per task type — this is the cheapest available calibration signal and it costs nothing to collect from day one.
Compression is lossy on purpose — but not everywhere
The brief must be short or it will not be read, which means the gateway summarises. Summarising an LLM's report with another LLM is a fidelity risk worth being deliberate about, so the rule is:
- Verbatim, never rewritten: the proposed action in an approval request, any identifier, any figure, any quoted external text, the exact error on a failure. These are copied through as the worker wrote them.
- Summarised freely: the narrative — what happened, what it means, what the gateway recommends.
If the human needs the full report behind any line, the brief links to it. Nothing is deleted, only folded.
Why not just read the agents' logs?
Because the supervision cost is the thing being optimised, and a log requires the human to go and look, decide what matters, and hold the state of five tasks in their head. The gateway inverts that: the human is presented with a bounded set of decisions, each with the context needed to make it, and answering them is the whole of the interaction.