The weakest moment in many agent systems is not the model's reasoning. It is the instant a plausible plan becomes a committed side effect.
A support agent drafts a refund. A coding agent prepares a migration. A browser agent updates a vendor portal. An operations agent restarts a service. In each case, the user may see a calm summary that says, in effect, “I am about to do the right thing.” That is not enough. The system needs to show exactly what will happen before the action crosses the commit boundary.
That missing layer is a dry-run contract.
A dry-run contract is a typed pre-execution packet produced before an agent performs an externally visible or hard-to-reverse action. It says: this is the operation, this is the target resource, this is the authority being used, these are the expected side effects, this is the risk class, this is how rollback or compensation would work, this is the human or policy approval required, and this is the trace ID that will connect the preview to the final result.
That sounds heavier than a chat confirmation, but it is the difference between approving a sentence and approving an action.
Why approval screens are too thin
Most agent approval flows still treat the human as the safety system. The model writes a summary. The interface asks for approval. The human clicks yes or no. That can be useful, but only if the human is shown the actual operational facts.
A good approver should not have to infer whether “update the customer record” means adding a note, changing a billing field, cancelling a subscription, or triggering an email. A platform policy should not have to parse prose to decide whether the action is allowed. An audit log should not have to reconstruct intent after the fact from a transcript that may contain drafts, retries, and abandoned plans.
The dry-run contract makes the commit boundary explicit. It turns “approve this agent response” into “approve this proposed operation under these constraints.”
That matters because many safety mechanisms already point in this direction. OpenAI's Agents SDK documentation describes guardrails and tripwires, including blocking guardrails that complete before the agent starts and are useful when avoiding potential side effects from tool calls. Its human-in-the-loop flow also treats interruption and resume as runtime state, not just conversational etiquette. The Model Context Protocol authorization specification frames restricted server access as an authorization problem at the transport layer. OpenTelemetry's Generative AI semantic conventions point toward standardized observability for AI operations. NIST's AI Risk Management Framework emphasizes govern, map, measure, and manage.
A dry-run contract is the practical glue between those ideas.
What the contract should contain
At minimum, the contract needs six fields.
First, the action identity: the tool, operation, version, and mode. “Send message” and “update CRM field” should not be hidden behind the same generic agent step. If the tool schema changes, the contract should say which schema version the agent is using.
Second, the target: the account, patient, repository, ticket, environment, endpoint, file, or record being changed. This field should be specific enough for policy and human review. “Production database” is not specific. “Customer 18472 billing_status from trial to cancelled” is closer.
Third, the authority basis: the user consent, role, delegated credential, policy grant, or workflow mandate that allows the action. This is where the runtime joins the action to authorization rather than trusting the model to remember it. If the authority expires, changes scope, or requires a step-up approval, the dry run should fail before execution.
Fourth, the side-effect forecast: what will become visible or irreversible if the action succeeds. Will money move? Will a customer be contacted? Will infrastructure restart? Will a downstream webhook fire? Will a medical, legal, or compliance record change? The point is not perfect prediction. The point is to force the system to name the expected blast radius before it acts.
Fifth, the recovery plan: rollback if rollback is possible, compensation if it is not. Some operations can be undone cleanly. Others require a new action, a customer communication, a ticket, or an escalation queue. If the agent cannot name a recovery path, the runtime should treat the action as higher risk.
Sixth, observability: a preview ID, trace ID, policy decision ID, approver identity when applicable, and later an execution receipt. The dry run and the committed action should be joinable. If the execution differs from the preview, that delta should be visible without spelunking through a transcript.
How to implement it without boiling the ocean
Start with the actions that can hurt you.
Do not try to wrap every read-only tool call on day one. Begin with operations that write to customer records, spend money, change permissions, deploy code, modify infrastructure, send external messages, or touch regulated data. Put those tools behind a two-phase interface: preview, then commit.
In the preview phase, the agent must produce the dry-run contract. The runtime validates it against schema, policy, authorization, and environment state. Guardrails run before the tool has a chance to create side effects. A human approval step can be inserted here, but the human reviews the contract, not a free-form paragraph.
In the commit phase, the runtime executes only the approved contract. That means the final tool call should be constrained by the same target, arguments, credential scope, and risk classification that appeared in the preview. If the agent tries to mutate the request after approval, the runtime should reject it and require a new dry run.
After execution, the system emits a receipt. The receipt says what actually happened, whether it matched the forecast, which trace captured it, and what follow-up is required. This closes the loop from intent to authorization to side effect to audit.
This pattern also makes agent evaluation more realistic. Instead of asking only whether the agent chose the right next step, teams can test whether it produced a valid dry-run contract, identified the right authority, named the side effects, selected the right recovery path, and refused to commit when the contract failed validation.
The practical rule
If an agent action is irreversible, externally visible, financially meaningful, operationally risky, or regulated, it should not execute from a chat summary alone.
The system should be able to answer four questions before the action happens: What exactly will change? Why is this agent allowed to change it? What happens if the change is wrong? How will we prove what occurred later?
A dry-run contract does not make agents perfectly safe. It does something more useful: it gives humans, policies, logs, and tests a concrete object to inspect before the agent commits. That is the control surface production teams need as agents move from recommendations into real work.
Build AI Systems That Survive Contact With Real Work
We help teams turn AI research into practical automations, agent workflows, and operational systems that can be evaluated and improved.
Get the Field Guide — $10 →