Agents
What Should AI Need Before It Can Change the Real World?
A human yes is not a force field. Bind approval to one exact target, operation, payload, cost, permission scope, and set of preconditions, then prove what happened.
Use this when
you need the work to hold up in real use.
Decide when an AI agent may act autonomously, when one exact action needs human approval, and what evidence must bind approval, execution, verification, and rollback.

An AI agent drafts a customer update. You read it, check the recipient and message, and approve the send.
Thirty seconds later the workflow retries. The recipient changed from the test account to the customer list. The message picked up a new link. The tool still has the same broad permission. The approval record still says yes.
What, exactly, did you approve?
This is where most human-in-the-loop designs get mushy. They ask a person for permission, save a decision, and treat that decision as a reusable glow around whatever the agent does next. That is approval theater.
An approval should authorize one canonical action: one operation, one target, one payload, one cost ceiling, one permission scope, and one set of material preconditions. Change any of those and the approval expires. The workflow stops and asks again.
I learned the hard edge of that rule while building WarpOS, my agentic operating-system project. Its frozen approval guards could require an approval record before a release or outside-service transition. The same frozen evidence also contains a release YAML that says deployed and a report that says not deployed. A permission record and a status label are not the outside world.
The decision here is narrower than a general autonomy policy. Which actions may run automatically? Which exact action needs a person? Which action should remain blocked? Once approved, what proves that the authorized action happened and can be recovered from?
Key takeaways
- Bind approval to one canonical action fingerprint, not a broad capability or a chat message.
- Choose APPROVE, REQUIRE_HUMAN, or BLOCK from impact, recoverability, sensitivity, cost, permissions, and verifiability.
- Invalidate approval when the target, operation, payload, cost, permission, material precondition, or expiry changes.
- Treat the execution receipt and independent postcondition as separate evidence.
- Preserve unknown outcomes, exception state, and rollback evidence so a retry cannot quietly repeat the action.
What changes when an AI agent can act?
Drafting is cheap to undo. Sending, purchasing, publishing, deleting, deploying, or changing a customer record creates a second system whose state may outlive the agent session.
That outside state introduces four separate moments: proposal, approval, execution, and verification. Collapsing them into one approved flag is how drift hides.
The target can change after review. A payload can be regenerated. A price can move. A permission can become broader. A precondition can expire. A retry can repeat an action that already succeeded. The agent can also report success when the downstream system timed out, rejected the request, or accepted only part of it.
The operating rule is simple: approval must match the action. Execution must produce a receipt. The target must prove the postcondition.
Human approval handles judgment. It does not replace authorization enforcement, transaction integrity, idempotency, downstream receipts, or rollback.
Which actions should run automatically, require a person, or stay blocked?
Start with impact and recoverability, then account for data sensitivity, permissions, cost, scope, and whether the result can be verified.
Do not turn REQUIRE_HUMAN into the default for every tool call. That creates a queue of low-context prompts until people click yes on instinct. Automate the safe class with narrow policy. Reserve attention for actions where human judgment changes the risk.
Also keep the decision action-level. Allow email is a capability grant. Send this digest to these three recipients with this subject and body before 5 p.m. is an action.
| Verdict | Use it when | Required boundary | Example |
|---|---|---|---|
| APPROVE | The action is low impact, bounded, reversible, within an existing policy, and independently verifiable | Programmatic policy evaluates the exact fingerprint immediately before execution | Update a local draft fixture inside an isolated workspace |
| REQUIRE_HUMAN | The action affects another person or system but a named reviewer can understand the significant data, contain the impact, and recover from failure | Show the exact target, operation, payload, cost, permission, expiry, and preconditions; approve one fingerprint | Send one reviewed customer email, publish one reviewed page, or deploy one identified revision |
| BLOCK | The result is irreversible, high impact, outside available authority, impossible to verify, or impossible to contain and recover | No credential or tool path may bypass the block | Destructive production migration without a tested backup or unknown recipient with sensitive data |
What should an action-level approval contract contain?
The contract needs enough information to reconstruct what was proposed, what was authorized, what executed, and what happened next.
Canonicalization matters. Two equivalent JSON objects should not produce different fingerprints because their keys were reordered. Two materially different recipient lists should not produce the same fingerprint because the approval display hid the recipients.
Use the significant data a reviewer actually needs. OWASP calls this what you see is what you sign in transaction authorization. The target and amount of a transfer are the classic example. For an AI action, significant data may include recipients, public visibility, revision, environment, price, permissions, or deletion scope.
Recompute the fingerprint at the final control gate. Do not trust the proposal-time hash if the executor rebuilt the payload later.
| Field | What it controls |
|---|---|
| action_id | Stable identity across proposal, approval, execution, receipt, verification, and rollback |
| target | Exact account, environment, repository, customer record, endpoint, recipient set, or deployment target |
| operation | One granular verb such as send, publish, charge, deploy, update, delete, or grant |
| payload_digest | Digest of canonical significant data, with sensitive content stored under the right privacy boundary |
| action_fingerprint | Digest over target, operation, payload digest, cost ceiling, material preconditions, and permission scope |
| risk_class | Policy input for APPROVE, REQUIRE_HUMAN, or BLOCK |
| cost_ceiling | Maximum money, tokens, quota, retries, records, or recipients this approval covers |
| preconditions | Current revision, target state, dependency versions, freshness, environment, and required evidence |
| approver and decision | Identity allowed to authorize this risk class, decision, reason, and decision time |
| expiry | Time and invalidation events after which the decision cannot execute |
| permission_scope | Minimum credential, tool, resource, and operation rights available during execution |
| idempotency_key | Stable key that lets the downstream system reject duplicate execution where supported |
| receipt | Downstream identifier, timestamp, status, request digest, response digest, and actor identity |
| postcondition | Independent query that proves the intended target state from the target itself |
| exception_path | What a timeout, partial result, duplicate, rejection, or unknown outcome does next |
| rollback | Tested containment or reversal procedure, owner, deadline, and retained evidence |
What does the local mutation experiment prove?
I built a side-effect-free Node.js fixture around one temporary local JSON file. No account, API, customer, deployment, purchase, message, or remote system was touched.
The starting file is an internal-review draft. The proposed action replaces it with an internal-review published record. Its fingerprint covers the target, operation, payload digest, zero-dollar cost ceiling, starting file digest, local environment, and narrow write permission.
The fixture approves that fingerprint, then changes one field: audience becomes public. The changed action is rejected as BLOCKED_ACTION_MISMATCH. The target digest remains unchanged.
The fixture then submits the exact approved action, rechecks the starting digest immediately before execution, writes the file, records a receipt, reads the target independently, verifies the after-digest, restores the original bytes, and verifies the starting digest.
That result proves a narrow mechanism. It does not prove production safety, distributed rollback, credential security, downstream idempotency, concurrent-write handling, or approver identity. Those controls must exist at the real boundary.
The useful part is the failure shape. A one-field material change invalidates the old approval before the write. That is the behavior to plant in a test.
| Check | Observed result | Verdict |
|---|---|---|
| Exact approved action | Fingerprint dc8fede...938f0 | APPROVED_EXACT_ACTION |
| Mutated payload | Different fingerprint 666ec590...e9a3 | BLOCKED_ACTION_MISMATCH |
| Rejected mutation | Starting target digest unchanged | PASS |
| Execution | Receipt bound to approval ID and action fingerprint | RECORDED |
| Postcondition | Observed target digest equals receipt after-digest | VERIFIED |
| Rollback | Restored target digest equals starting digest | VERIFIED |
What do current agent tools provide, and what still belongs to you?
Current agent products expose useful approval and permission surfaces. They do not remove the need for your application contract.
The OpenAI Agents SDK can pause a run when a tool call needs approval. Its documented interruption contains the tool name and arguments, and approval is scoped to a specific call ID unless a developer deliberately chooses a sticky decision. The SDK also supports serializing run state across a long approval wait. That is valuable orchestration. Your application still decides which arguments are significant, how they are canonicalized, when approval expires, what downstream credential is used, and what receipt proves success.
Claude Code's current permission model separates allow, ask, and deny rules, with deny taking precedence. Its documentation says the runtime enforces those rules rather than relying on the model. That is a real boundary. A shell permission rule still describes a class of commands. It is not a business approval for one deployment target, revision, cost, and rollback plan.
OWASP's Excessive Agency guidance recommends minimizing tool functionality and permissions, executing in the user's context, requiring human approval for high-impact actions, and enforcing authorization in downstream systems. Its transaction authorization guidance says significant data should be visible to the approver, changed data should invalidate authorization, the final execution gate should recheck authorization, and authorization should be unique and time-limited.
What did frozen WarpOS evidence teach me about approval?
WarpOS had sensible hard ceilings. The frozen autonomy document reserved remote pushes, paid-service signups, production deploys, destructive migrations, and secrets sent to remote systems for an operator decision.
Its external-service gate blocked a descriptor that required approval unless the recorded state was approved or waived. Its approval hook also checked that a release had an approval reference pointing to an approved or waived record before deploy.
Those controls were better than asking the model to be careful. They also exposed the next problem.
The approval hook checked a pointer and state. It did not bind target, operation, payload, cost, permission, preconditions, expiry, receipt, or rollback. Its own header said parse errors failed open, and an environment variable could disable it.
The frozen release records made the evidence problem concrete. RL-20260611-045.yaml says deployed to internal-canary, names an approval reference, timestamp, and actor. Its companion report says preparing, not deployed, no approval recorded, and deployment not performed.
I cannot infer the real deployment state from that disagreement. The YAML may be newer. The report may be stale. The external target may tell a third story. That is precisely the point.
A release record is not a deployment receipt. A rendered report is not a target postcondition. If two internal artifacts disagree, stop pretending a status label settles reality. Query the deployment target, bind the receipt to the action, regenerate or invalidate stale reports, and keep the mismatch visible until reconciled.
What should happen after approval?
Approval is the start of controlled execution, not the end of review.
Unknown is a first-class result. If the network times out after a send request, retrying blindly can send twice. The next action is not try again. It is query by idempotency key or receipt, determine whether the first action happened, then decide.
How do you implement the first exact-action gate this week?
Pick one reversible action with a real consequence but a contained blast radius. Do not start with money movement, broad deletion, or an irreversible production migration.
Write its canonical schema. Name the significant fields. Create the fingerprint. Display those same fields at approval. Make any material change invalidate the decision. Use a credential that can perform only that operation on that target. Capture the downstream receipt. Query the target. Exercise rollback in a safe environment.
Then plant three failures: change the target after approval, change one significant payload field, and let the approval expire before execution. All three should block before the outside call.
FAQ
What actions should always require human approval from an AI agent?
Require a person when an action has meaningful impact on another person or system and human judgment can contain the risk. Common cases include sensitive messages, public publishing, spending money, changing permissions, production deploys, durable deletion, and regulated or customer records. Block the action when the result cannot be understood, verified, contained, or recovered from.
Is a tool permission prompt enough approval?
No. A permission prompt can authorize a capability or one tool call. The application still needs to bind significant target, operation, payload, cost, permission, and precondition data to the decision, enforce it at execution time, and verify the downstream result.
What should invalidate an AI action approval?
Invalidate approval when the target, operation, significant payload data, cost ceiling, permission scope, material precondition, environment, or expiry changes. High-impact actions should also invalidate after a failed or unknown execution until the target state is reconciled.
What is the difference between a receipt and a postcondition?
A receipt records what the execution path says it attempted or accepted. A postcondition is an independent observation of the target state you intended to create. A deployment command can return success while the wrong revision is live, so you need both.
Should an AI agent retry a timed-out outside action?
Not automatically when the first outcome is unknown. Query the target by receipt or idempotency key first. Retry only after proving the first action did not happen or after using a downstream idempotency guarantee that makes the repeat safe.
How should approval survive a long-running AI workflow?
Store the exact proposal, fingerprint, decision, approver, expiry, pending execution state, receipts, and recovery instructions durably. On resume, revalidate the current action and preconditions. Never treat a resumed session as proof that the old approval still matches.
Conclusion
A human yes is not a force field.
Bind it to one action. Recompute the match at the execution gate. Use the smallest permission. Keep the receipt. Ask the target what happened. Preserve the exception and rollback state for whoever has to recover the workflow later.
Approval must match the action.
Sources
- OpenAI Agents SDK human-in-the-loop guide
- Claude Code permission documentation
- OWASP LLM06:2025 Excessive Agency
- OWASP Transaction Authorization Cheat Sheet
- WarpOS frozen public source
- WarpOS external-service approval gate
- WarpOS autonomy ceilings
- WarpOS approval guard
- WarpOS release helper
- WarpOS frozen release record
- WarpOS frozen release report
Next move
Want me to audit your AI workflow?
Bring one product-delivery bottleneck, operations workflow, or early MVP. I will help decide what AI should own, where human judgment stays, and how to measure the result.
Talk about an AI workflowAbout the author
Related articles
Keep going
What an AI Building System Needs: 12 Practical Parts
A plain-language guide to the 12 parts that keep AI-assisted work accurate, reviewable, and recoverable, backed by a frozen WarpOS audit.
How to Prove AI Work Is Actually Done
A practical completion-evidence contract, runnable three-case experiment, and frozen WarpOS release lesson for teams that need to verify AI agent output.
How to Make AI Work Pick Up Where It Left Off
A practical guide to recoverable AI work, with a portable resume packet, a hard-kill experiment, and evidence from a frozen WarpOS audit.