Guarded Automation: Agents That Run Operations Module 2 · The Envelope

Bound the Parameters

Last reviewed · content updated

Intermediate

What you'll learn

~18 min
  • Read a run-budget denial and explain why counting from the receipt chain, not an in-memory counter, makes a budget authorization-bearing
  • Read a seven-row table of agent-permission surfaces and name where each one's enforcement actually sits, and as of when
  • Recognize a budget that only binds a caller using the polite API, and name the fix

Before the detail — Decision: bound how much of the world one unattended action, and one unattended run, may move (its blast radius) — not just which actions are allowed. Outcome: a run that cannot be talked into fourteen crews when its envelope allows three, and cannot outrun its receipt-derived budget after a restart. Artifact: a run-budget denial receipted by name, and a seven-row table naming where the same idea is enforced, and where it is only a hint, across seven agent-permission surfaces today. Status of what follows: reusable guidance, dated where the practice memo dates it.

Prompt first: size the blast radius before the first run

Read-only: for one action-taking agent, list every parameter of every
tool it can call, and answer three questions for each:
- what is the largest single value this parameter could carry that
would still look like a normal request?
- how many times could this action run before someone notices,
inside one hour?
- is there a budget enforced anywhere that would stop it before
that count is reached?
Where the third answer is "no", say so plainly rather than
estimating a number that has never been tested.

A parameter bound answers “how much can one call move”; a run budget answers “how much can one run move before anyone looks” — they are different numbers, and a policy that only sets the first has answered half the question.

Blast radius is a number, and this run’s is enforced

MU-AI-011’s envelope declares both kinds of bound on the same action. pre_position_crew accepts crews between 1 and 3 — a single-call limit. max_actions_per_run: 10 counts prior agent-action receipt rows for the run; max_mutating_actions_per_run: 4 counts prior non-read-only outcomes that touched the target. The first caps attempted actions; the second caps changes — two different counts, not one ceiling read twice. On the training’s own storm night, the agent’s plan calls for fourteen crews in one move against a feeder carrying the night’s highest risk. The guard’s answer is immediate, and it never reaches a second step:

STEP - DENY 'crews'=14 exceeds the envelope maximum 3
RESULT denied exit 3

The committed nine-call anchor records this denial as 3:3 — call 3, exit 3.

The run budget is the sharper case, because it is not a static ceiling — it is counted live from the receipt chain the guard has already written for that run. A separate run against the same envelope drafts four work orders, each one a mutating action, and the fifth is refused before anything is planned:

STEP - DENY run RUN-BUDGET-01 has already changed the target 4
times; the budget max_mutating_actions_per_run=4 is
spent, and 'draft_work_order' is class=reversible
RESULT denied-over-budget exit 3

Counting from the chain rather than from a counter in memory is what makes the budget mean something under audit: an in-memory count resets the moment the process restarts, and a log the agent itself could edit would let the same agent edit its own ceiling. That is exactly why the receipt store is not a path this agent may write to — a fact Lesson 2.4 makes literal in the envelope’s own list of writable state paths.

Seven permission surfaces and their enforcement points

These surfaces do not all express a numeric budget. The table separates what each exposes from where enforcement sits, showing where a custom run budget would have to live:

SurfacePolicy is expressed asEnforced atAs of
Claude Codepermissions.allow/ask/deny; three consecutive or twenty total blocks pause auto mode, not configurableCLI harness, outside the prompt2026-08-29
OpenAI Agents software development kit (SDK)needsApproval / needs_approval; input, output, and tool guardrailsyour own process — the SDK’s own guidance is to “add review and enforcement to your own harness”undated
Copilot CLI--allow-tool / --deny-tool / --allow-all; a trusted-directories list; ~/.copilot/permissions-config.jsonCLI harness2026-08-29
Azure SRE Agentper-tool allow, ask, or deny across three scopes, up to 1,000 patterns per scopethe agent service, before the call is made2026-06-02
AgentCoreCedar — Amazon Web Services (AWS)‘s policy language — plus Dogwood, its session-temporal extension — approval granted before a transfer, action-count caps, a running total kept under a budgetthe Gateway, outside the agent’s own code2026-08-29
MCPa tool’s own annotations — hints a client reads at its own discretion, never a boundwherever the client chooses to enforce one; the protocol enforces nothing itself2025-06-18
org policyAzure Policy’s deny effect; an AWS service control policy that defines a guardrail but grants no permissionbefore the Azure Resource Provider; during AWS identity evaluation for member accounts2025-03-04 · 2026-08-29

Five rows are runtime or harness permission surfaces. Model Context Protocol (MCP) supplies hints but enforces no authorization bound; organization policy is an outer guardrail that can constrain requests regardless of runtime. This training’s own guard adds a behavior none of the seven reproduce: it recounts the receipt chain on every attempt rather than trusting a number a runtime remembered from earlier in the session.

A team choosing where to build its own budget is choosing how many products it has to re-verify when one of them changes its defaults — the fewer surfaces holding the number, the fewer places a contract renewal or a version bump can quietly move it.

The budget that binds only the polite caller

A budget enforced on one verb does nothing against a different verb that reaches the same effect. A PodDisruptionBudget — Kubernetes policy limiting simultaneous voluntary disruptions to a replicated workload — states its limit plainly in Kubernetes’ documentation: “involuntary disruptions cannot be prevented by PDBs; however they do count against the budget,” and the fix it recommends is to “use tools which respect PodDisruptionBudgets by calling the Eviction API instead of directly deleting pods.” An agent with kubectl delete pod in its toolset walks straight past a budget written for evict pod, not because the budget failed but because it was never asked the question.

The same shape of gap is what Lesson 2.1’s bypass transcript showed for this training’s own gateway: a budget counted on calls that reach the guard does nothing for a call that reaches the target directly. The fix in both cases is identical — deny the impolite verb outright rather than trust that every caller prefers the polite one, and close the direct path rather than assume nobody will use it. Lesson 5.3 reads a case where the tell was not any single call but the pace of an agent’s own requests — a budget on rate, not just on count, is the same idea one dimension further out.

No runtime in this table expires what it grants

One more gap is worth stating plainly, because it is easy to assume otherwise: as of 2026-08-29, none of the five runtimes in the table above expires a granted approval on its own. Copilot CLI’s closest equivalent is a saved approval that lasts “the remainder of the session” — a session boundary, not a clock. AgentCore’s Dogwood comes closest to the shape this training needs, expressing approval-before-transfer as a session-temporal condition rather than a permanent grant — Lesson 4.1 builds an approval token with an actual expiry on top of that same idea, because none of these five ships one.

Stop and escalate when a budget’s count comes from anywhere other than the log of record — an in-memory counter that resets on restart, a total the agent itself reports, a log the agent can trim. Whether that budget gets rebuilt on the receipt chain or the runtime gets replaced is a decision for whoever owns the receipt store’s access controls, not for whoever configured the runtime’s defaults.

KNOWLEDGE CHECK

An agent's toolset includes both evict_pod, which a PodDisruptionBudget can refuse, and delete_pod, which it cannot. A budget is set on evictions. What does actually bounding the blast radius require?

Key takeaway

Blast radius is a number twice over: how much one call may move, and how much one run may move before its own log is asked. MU-AI-011’s envelope enforces both, counted from the receipt chain rather than a counter that forgets on restart; seven agent-permission surfaces place that same idea at seven different points today — some enforced, one a hint by the protocol’s own admission — and none of them expiring what they grant; and a budget written for the polite verb does nothing against the impolite one that reaches the same effect. Lesson 2.3 turns this same envelope into decision tests, so a change to any of these bounds is caught before it reaches a storm night, not after.

LEADERSHIP DECISION fund one enforced run budget per action-taking
agent, counted from its own receipt chain, not
from a runtime's remembered total
PRACTITIONER ACTION name every verb that reaches the same effect as
a bounded one, and deny the unbounded verb
outright rather than trust a preference for it
SUCCESS MEASURE zero standing tools that reach a bounded
effect through an unbounded verb - an audit
finding avoided
Search lessons