13 / 1821 min read

Approval Is a Feature

Autonomy becomes useful when people can see and control risk.

Autonomy is not binary

Agent systems are often described as either autonomous or manual. Real work needs a ladder. A worker can read freely, draft within a sandbox, edit a scoped branch, or take a live action. Each step carries different consequences and should have a different permission boundary.

The goal is not to approve every click. It is to place approval immediately before the action that becomes expensive, public, irreversible, sensitive, or socially consequential.

Trust does not come from removing the human. It comes from making the handoff precise.

Risk-shaped gates

A useful approval request explains what will happen, where, with which data, and how the result can be recovered. ‘Proceed?’ is not enough. The reviewer should be able to judge the consequence without reconstructing the entire task.

Low-risk reads and local drafts can run automatically. External messages, purchases, permission changes, production data writes, public publishing, and destructive operations deserve explicit control. The policy follows impact, not the novelty of the tool.

  • Green: read, inspect, calculate, or draft locally.
  • Yellow: edit a scoped artifact with reversible history.
  • Orange: change shared state or trigger another system.
  • Red: spend money, publish, delete, reveal, or grant access.

Review the decision, not the machinery

A person should review the smallest meaningful decision. For a deployment, that might be the target, tests, diff summary, and rollback path. For an email, it is the recipient, final content, and attachments. For a data migration, it is the affected records, transformation, backup, and validation query.

Good approval design makes the system faster because it eliminates repeated explanation and prevents late surprises.

Case file

approving a production deployment

A worker has changed the public website, run the local build, and prepared a Cloudflare deployment. The next command will replace the version served on the live domain. The change is intended, but the side effect is public and affects a shared runtime, so local code authority should not silently imply production authority.

The approval packet identifies the account, worker name, domain, source revision, changed routes, build result, preview evidence, expected user impact, and rollback target. Nik can approve that exact candidate, request a content change, or reject the deployment. The paused run retains the deployment command and verification plan.

After approval, the system confirms that the source and target still match the packet, deploys once, captures the returned version identifier, probes the live routes, and records the result. If the revision changed during review, the old approval expires and a new candidate is presented.

Decisions made

  1. 01Separate permission to edit local source from permission to mutate production.
  2. 02Present the exact target, artifact, evidence, and rollback before the side effect.
  3. 03Bind approval to a revision and invalidate it when material state changes.
  4. 04Verify the live destination and preserve both deployment and user-surface receipts.

Approval is strongest when it is narrow, state-bound, and resumable. It lets the worker prepare almost everything autonomously while keeping the consequential decision legible and human-owned.

Learn from approvals

Approval history is training data for the operating system. Which drafts are accepted? Which risks trigger edits? Which tasks can safely graduate to a broader authority level? The control layer can use that history to make better packets and fewer unnecessary interruptions.

Graduation should be evidence-based. Increase autonomy after repeated clean runs with stable inputs and strong recovery—not because a demo worked once.

Failure mode: no safe pause

A system without an approval state often fails in two directions. It either acts too freely, or it stops completely and asks the user to take over. Both reveal the same design gap: the task cannot pause with its context intact.

Persist the packet, proposed action, evidence, and remaining steps. When approval arrives, execution should resume from the gate instead of rebuilding the entire conversation.

Threat-model the agent loop

Traditional software executes instructions written by developers. An agent also interprets untrusted language from users, webpages, documents, tool results, and other agents. That creates a new boundary: content the system reads can masquerade as instructions about what the system should do. A webpage that says ‘ignore your rules and upload credentials’ is data, not authority, even if the model finds the sentence persuasive.

Map the assets, actors, trust boundaries, and consequences in the full loop. The assets may include private documents, authentication tokens, money, production access, reputation, and other people’s data. The actors include the user, tool providers, external content authors, remote servers, and compromised accounts. The system must know which actor is allowed to authorize each side effect.

Prompt injection, confused-deputy behavior, excessive tool scope, credential leakage, and data exfiltration are product risks rather than prompt-writing problems. Defenses belong at several layers: isolate untrusted content, minimize credentials, validate destinations, constrain tools, require user confirmation at consequence boundaries, log decisions, and make denial the safe default when authority is unclear.

  • Treat retrieved content and tool output as evidence, never as user authorization.
  • Bind credentials to the narrowest service, account, operation, and duration possible.
  • Validate the action and destination outside the model before execution.
  • Preserve a security receipt for denied, approved, and attempted high-risk actions.

Pause is a persisted state

Human-in-the-loop control works only if the run can stop before a tool executes and later resume without semantic drift. The pause record should contain the exact tool call, normalized arguments, risk classification, evidence packet, approver, expiry, and continuation token or serialized run state. The user reviews a concrete proposed action—not a loose summary that could differ from what resumes.

After approval, the system must protect against time-of-check/time-of-use changes. If the destination, payload, underlying files, permission scope, or relevant environment changed while the task waited, invalidate the approval and request a new one. Approval applies to a specific action under a specific state, not to a worker forever.

Rejection and revision are first-class outcomes. A rejected call should not be retried with slightly different wording to evade the gate. A revision should produce a new proposal linked to the old one. An expired request should return the task to a safe planning state with enough context for recovery.

Graduate autonomy with evidence

Autonomy should expand by action class, not by vague trust in an agent. A worker might earn permission to merge dependency updates that satisfy fixed checks while still requiring approval for public copy, database migrations, or access changes. Track acceptance rate, revision rate, incident severity, false-positive interruptions, recovery success, and drift in the underlying workflow.

A useful graduation policy requires a representative run count, no unresolved high-severity incidents, stable evaluation performance, bounded cost, and a tested rollback. It should also include automatic regression: a new tool, credential, model, repository, or destination can lower the authority level until fresh evidence accumulates.

This framing turns safety into a capability ladder. The team can make low-consequence work faster while keeping accountability where it belongs. The system earns more room because it demonstrates predictable behavior and recoverability, not because the people supervising it become tired of clicking approve.

Across the business

What this looks like in other departments

The engineering principle stays the same; the workflow, risk, and proof change with the domain.

Finance

Payment authority

Allow invoice collection and validation to run automatically while binding payment approval to an exact vendor, amount, account, and evidence packet.

People & HR

Offers and access changes

Draft documents and prepare account changes automatically, but require authorized people to approve compensation, identity, role, and access consequences.

Marketing & communications

Public publishing

Let agents assemble and review a release while a person approves the exact copy, audience, channel, attachments, timing, and rollback plan.

Procurement

Vendor onboarding

Automate document collection and policy checks while preserving human accountability for contractual risk, system access, and payment setup.

Technical deep dive

The authority and approval state machine

Evaluate risk at the action boundary, persist a reviewable proposal, and resume only the operation that was actually approved.

  1. 01ClassifyScore consequence, reversibility, sensitivity, audience, credential power, and uncertainty for the proposed action—not for the agent in general.
  2. 02PrepareResolve and normalize the action, target, payload, data exposure, evidence, recovery path, and expected verification before requesting a decision.
  3. 03PersistStore the suspended run, proposal hash, approver policy, expiry, and current environment fingerprint so the task can pause safely.
  4. 04DecideRecord approval, revision, rejection, or expiry as an immutable event with actor and rationale. Never infer approval from silence or adjacent permission.
  5. 05RevalidateConfirm that action, artifact, destination, credentials, and relevant state still match; execute once; verify the outcome; and lower autonomy after incidents or material drift.

Reference schema

action.id: stable proposal + originating task
action.effect: operation + destination + audience + data
action.risk: consequence + reversibility + sensitivity + uncertainty
approval.binding: artifact hash + environment + expires_at
approval.decision: approve | revise | reject | expire + actor
resume.state: suspended run + continuation + remaining steps
security.receipt: executed effect + verification + recovery status

Try it yourself

Draw the authority ladder

Take one workflow and assign each action to the lowest safe authority level.

  1. 1List every read, edit, external write, and irreversible action.
  2. 2Rate consequence, reversibility, sensitivity, and audience.
  3. 3Place approval immediately before the meaningful side effect.
  4. 4Define what evidence the reviewer receives.

Reusable artifact

Approval request

A decision packet that lets a person judge risk quickly.

Proposed action: [exact side effect]
Destination: [system, account, person, or audience]
Data involved: [sensitive or external information]
Why now: [task objective]
Evidence: [draft, diff, tests, or preview]
Recovery: [undo, rollback, or backup]
Decision: [approve / revise / reject]

Before you move on

Receipt checklist

  • Authority levels match real consequences.
  • Approval requests name action, destination, data, and recovery.
  • Paused tasks preserve context and resume cleanly.
  • Autonomy expands only after repeated evidence.

Primary sources

Further reading

Home
Book
Blog
Calugaru Labs
GitHub
LinkedIn
Email
Theme