Compatibility: Pactmark 0.1.x. This scenario uses the runtime effect and decision surfaces. The public authoring facade currently exposes read tools — see Limits and the approval-purchase-boundary example, which demonstrates this boundary honestly rather than simulating success.

The situation

A support agent handles a refund request. The assistant should gather the order, check eligibility against policy, compute the amount, and — if a human agrees — issue the refund through the payment provider. Every hard problem in agent engineering shows up in this one flow:

The effect is irreversible

Money leaves. There is no undo, only a compensating transaction that is itself a business action.

The amount is model-influenced

A model computed it. A human must see the normalized value, not the model’s narration.

The API can time out

A lost response tells you nothing about whether the refund was issued.

Someone will ask about it

Three months later, in a dispute, with a specific transaction id.

The WorkOrder

Three details do most of the work:
refund_approver
The person who asked is not automatically the person who may approve. Support agents raise refunds; approvers approve them.
delegate_review
The run is allowed to do the work, and the output is reviewed before it counts as done.
500 EUR
A hard ceiling with an explicit price-bound version and expiry. Above it, the run cannot proceed regardless of what anyone approves.

The policy

R3 and R5 have no rule, so they are denied. That is not an omission — it is the default working correctly.

The tools

maxCallsPerRun: 1 on the refund tool. If the model somehow proposes a second refund in the same run, the ceiling refuses it before policy even has to think about it.

The approval

Figure 1. The approver sees a normalized preview, re-authenticates, and consumes a one-use proof. The proof never travels through the browser, a log line, or the model. What the approver actually sees:
Note that the amount appears in materialConsequence, derived from the normalized payload — not from a sentence the model wrote. If the model’s narration and the payload disagree, the human sees the payload.

The day the payment API times out

Figure 2. reconcilable was registered on the tool before any of this happened. That prior declaration is what makes the recovery path legitimate rather than improvised. The sequence:
1

EffectPrepared

With an effectKey derived from the order and idempotency key, and strategy: "reconcilable".
2

EffectDispatched

Attempt 1. The POST goes out.
3

The connection drops

No response. EffectUncertain, then EffectNeedsReconciliation with effectMayHaveOccurred: true.
4

The run parks

It does not retry. It does not fail with “refund failed” either, because that would be a false statement.
5

Reconciliation looks it up

The provider is queried by idempotency key. If the refund exists, its real outcome is recorded.
6

Or it is abandoned, honestly

If the provider cannot answer, abandon_uncertain records that the effect may have occurred. Anything depending on it raises KAF_EFFECT_ABANDONED_UNCERTAIN. That friction is the point.
Compare with the common alternative: retry on timeout. On a payment provider without perfect idempotency, that is a double refund. Pactmark makes you decide before the outage which of those two failure modes you are willing to accept.

The evidence

Read doesNotProve again. “That the customer received the funds” is a genuinely different claim from “the provider acknowledged the refund”, and conflating them is how disputes go badly.

What you still own

The desk limit

€500 is a number you chose. Pactmark enforces it faithfully whether or not it is right.

The approver's understanding

An accurate preview can still be misread. TM-05 records this residual risk explicitly.

Provider idempotency

reconcilable is your assertion about the provider. If it is wrong, the strategy is wrong.

Someone to resolve parked effects

Parked runs need a human on a rota, not a dashboard nobody opens.

Approval integration

Building the operator flow correctly.

Tools and effects

Why the strategy must be registered in advance.