2. Prove it in SIMULATE
Real refusals, zero side effects. The mode where a wrong policy costs you a wrong line in a report.
SIMULATE runs the complete pipeline and executes nothing. No credential is
brokered, no downstream call is made, no external side effect occurs anywhere.
Refusals are real refusals — your agent sees them and has to handle them.
This is where policy correctness gets settled, because a mistake here costs you a wrong line in a report instead of a wrong row in a database.
#Switch to it
bashveefore deploy --mode SIMULATE --reason "Validating refund policy from observed traffic"
#What to do
Replay what you already saw
Preflight does this automatically, and it is the single most useful thing in the promotion flow: it re-evaluates your recent observed traffic in the target mode and tells you exactly which calls start being refused.
You can also do it directly for a specific shape of request:
bashcurl -X POST https://veefore.example.com/v1/policies/simulate \
-H "Authorization: Bearer $VEEFORE_API_KEY" \
-H 'content-type: application/json' \
-d '{
"agentId": "agt_01JAV…",
"tool": "refund_customer",
"capability": "refund.create",
"amount": 150000
}'
The response carries the decision and the full explanation: the policy, the version, the deciding rule, every rule that matched, the resolved authority and the risk signals. Simulation has no side effects of any kind — it does not even write a decision record, because a decision that did not happen does not belong in the audit trail.
Run the policy test cases
bashveefore policies test
These are the Given/Then cases you recorded during OBSERVE. They must all
pass; activation refuses while any of them fails, and there is no override flag.
Make your agent handle refusals properly
This is the step teams skip and then regret. In OBSERVE your agent never saw a
refusal, so its error handling has never been exercised. In SIMULATE it will
be.
tsimport {
VeeforeBlockedError,
VeeforeApprovalRequiredError,
VeeforeAuthenticationError,
} from '@veefore/sdk';
try {
await agent.act({ tool: 'refund_customer', amount: 250_00, currency: 'INR' });
} catch (error) {
if (error instanceof VeeforeApprovalRequiredError) {
// Expected. Hand back to a human and resume later.
return { status: 'awaiting_approval', approvalId: error.approvalId };
}
if (error instanceof VeeforeBlockedError) {
// Expected. Report the reason; never retry a policy refusal.
return { status: 'refused', reason: error.message };
}
if (error instanceof VeeforeAuthenticationError) {
// Not expected. Identity is wrong — fail loudly.
throw error;
}
throw error;
}
The important distinction: a refusal is an answer, not a transport failure. Retrying it produces the same answer and burns your rate limit. Errors and retries has the full table.
Exercise the approval path end to end
If any rule returns REQUIRE_APPROVAL, walk the whole loop at least once:
- The agent requests the action and gets
APPROVAL_REQUIRED. - An approval appears in the console queue with full context.
- A real person approves it.
- The agent retries with the
approvalIdand proceeds.
Then deny one, and check the agent reports the denial reason usefully rather than logging "request failed".
Check someone is actually watching the queue
ENFORCE with approval rules and an unwatched queue is just a slower kind of
blocked. Decide who owns the queue, what the response-time expectation is, and
what happens out of hours — before you promote, not after the first approval
times out.
Clear doctor
bashveefore doctor --strict
--strict fails on warnings too. Fix all of it. The findings that matter most
here:
- A dangerous tool permitted only by a default decision, with no rule covering it
- Trust evidence that has expired
- Credentials overdue for rotation
- An agent with no policy bound to its scope at all
#What SIMULATE will not tell you
Whether your downstream accepts the request. Nothing is executed, so a
credential with the wrong material key, a destination that resolves differently
from production, or a downstream that rejects the payload all look fine here.
Those surface on the first real ENFORCE execution.
The mitigation is to make the first ENFORCE deployment small — see
3. Turn on ENFORCE.
Timing and load behaviour. No execution means no downstream latency and no timeouts.
#Ready when
- Every policy test case passes.
- Preflight replay shows only refusals you intended.
- Your agent handles
BLOCK,REQUIRE_APPROVALandAPPROVAL_DENIEDwithout crashing or retrying. - The approval loop has been walked by a real person.
veefore doctor --strictis clean.- The approval queue has a named owner.