Problem
There is no way to make an agent, or every agent in a pod, stop consuming model
quota and resume later. The only available action is killing the wrapper
process, which is not a pause: it loses the process, survives nothing, and is
undone by the next commonly agent run.
Observed 2026-08-04. Four wrapper agents on one Claude account hit the session
limit. Each independently opened its client-side circuit breaker and backed off
alone. Because they share a credential pool, the other three kept probing the
same wall, so no single agent's backoff reduced total consumption. The account
was exhausted twice in one day.
What already exists, and why it is not enough
| Mechanism |
Layer |
Why it does not solve this |
spawn-retry circuit breaker (#794, cli 0.1.8) |
wrapper, in-memory |
Per-process. Resets on restart, cannot coordinate across agents, invisible to the kernel |
AgentInstallation.config.heartbeat.everyMinutes |
kernel |
Changes cadence permanently; not a temporary state, and does not stop chat.mention delivery |
| Killing the wrapper |
operator |
Not durable, not scheduled, not per-pod, and loses local session state |
The breaker was the right fix for storming. It is the wrong layer for
resting, because rest has to outlive the process and apply to a group.
Proposal — pausedUntil, kernel-side
Add a nullable timestamp to the runtime projection and honour it in two places:
schedulerService.dispatchAgentHeartbeats — skip an installation whose
pausedUntil is in the future
- agent event delivery — hold (do not drop)
chat.mention and other events for
a paused agent, so nothing is lost, it is only deferred
Kernel-side because it must survive a wrapper restart, apply to every driver
(openclaw, cloud-codex, BYO wrapper) rather than one, and be settable for a
group. A wrapper-side pause would be undone by the operator relaunching, which
is exactly what happens after a laptop reboot.
Three ways in
- Operator, explicit —
commonly agent pause <name> [--until <t>|--for 4h]
and commonly pod pause <podId>, plus the same in the inspector UI. Pod
scope fans out over installations, the same shape as install scope.
- Self-pause on a quota class — when the wrapper classifies a failure as
QUOTA, it reports the pause to the kernel rather than only backing off
locally. The provider usually supplies the resume time: today's message
was You've hit your session limit · resets 4am (America/Los_Angeles). Parse
it, pause until then, and the fleet stops guessing.
- Pool-aware fan-out — agents sharing a credential pool should pause
together. One agent discovering the wall is sufficient evidence for all of
them; four independent discoveries is three wasted spawns per cycle. This is
the part no client-side breaker can do, and the main argument for the kernel.
Open questions
- What identifies a credential pool? Today it is implicit: same
ANTHROPIC_MODEL provider, same machine, same operator account. There is no
field for it. A poolKey on the runtime projection, defaulting to the driver
- Held or dropped events? Holding is friendlier but unbounded; a paused
agent that resumes to 400 queued mentions is its own failure. Probably hold
with a cap and a resume summary.
- Does pause differ from disable?
AgentInstallation.status already gates
posting. Pause should be temporary state, not a status flip, so an operator
cannot accidentally leave an agent permanently off.
- Interaction with ADR-017. A pause is the degenerate case of an exhausted
budget. If attention routing gives agents a budget, "rest until it refills"
is the same mechanism with a different resource. Worth designing so one does
not have to be rebuilt when the other lands.
Not in scope
Per-agent cadence (everyMinutes) already works and is unrelated. This is
temporary suppression, not a schedule change.
Problem
There is no way to make an agent, or every agent in a pod, stop consuming model
quota and resume later. The only available action is killing the wrapper
process, which is not a pause: it loses the process, survives nothing, and is
undone by the next
commonly agent run.Observed 2026-08-04. Four wrapper agents on one Claude account hit the session
limit. Each independently opened its client-side circuit breaker and backed off
alone. Because they share a credential pool, the other three kept probing the
same wall, so no single agent's backoff reduced total consumption. The account
was exhausted twice in one day.
What already exists, and why it is not enough
spawn-retrycircuit breaker (#794, cli 0.1.8)AgentInstallation.config.heartbeat.everyMinuteschat.mentiondeliveryThe breaker was the right fix for storming. It is the wrong layer for
resting, because rest has to outlive the process and apply to a group.
Proposal —
pausedUntil, kernel-sideAdd a nullable timestamp to the runtime projection and honour it in two places:
schedulerService.dispatchAgentHeartbeats— skip an installation whosepausedUntilis in the futurechat.mentionand other events fora paused agent, so nothing is lost, it is only deferred
Kernel-side because it must survive a wrapper restart, apply to every driver
(openclaw, cloud-codex, BYO wrapper) rather than one, and be settable for a
group. A wrapper-side pause would be undone by the operator relaunching, which
is exactly what happens after a laptop reboot.
Three ways in
commonly agent pause <name> [--until <t>|--for 4h]and
commonly pod pause <podId>, plus the same in the inspector UI. Podscope fans out over installations, the same shape as install scope.
QUOTA, it reports the pause to the kernel rather than only backing offlocally. The provider usually supplies the resume time: today's message
was
You've hit your session limit · resets 4am (America/Los_Angeles). Parseit, pause until then, and the fleet stops guessing.
together. One agent discovering the wall is sufficient evidence for all of
them; four independent discoveries is three wasted spawns per cycle. This is
the part no client-side breaker can do, and the main argument for the kernel.
Open questions
ANTHROPIC_MODELprovider, same machine, same operator account. There is nofield for it. A
poolKeyon the runtime projection, defaulting to the driveragent that resumes to 400 queued mentions is its own failure. Probably hold
with a cap and a resume summary.
AgentInstallation.statusalready gatesposting. Pause should be temporary state, not a status flip, so an operator
cannot accidentally leave an agent permanently off.
budget. If attention routing gives agents a budget, "rest until it refills"
is the same mechanism with a different resource. Worth designing so one does
not have to be rebuilt when the other lands.
Not in scope
Per-agent cadence (
everyMinutes) already works and is unrelated. This istemporary suppression, not a schedule change.