Last reviewed 2026-09-05Skill version 0.1.0Community
Prove that the refund reached the succeeded state. A Refund object does not prove that money moved. This contract proves the succeeded state on the refund resource and a refund.updated event that carries it.
idempotency_key through Idempotency-Key, retry is safe
How does the evidence correlate with this operation?
Strategy
Assurance
Keys
Required
resource_id
strong
refund_id from $action.result.id
yes
idempotency_key
strong
idempotency_key from $operation.id
no
fingerprint
weak
charge from $input.charge; amount from $input.amount
no
Which evidence does the contract require?
Minimum evidence level E2. An independent channel is required. Minimum channels: 1.
Channel
Level
Independence
Verifier
Description
refund_readback
E2
provider readback
http
Read the refund from the provider. The http verifier returns the parsed Refund object, so a condition path is $observed.refund_readback.status.
refund_succeeded_events
E3
provider event
webhook
The refund.updated events of this refund that carry the succeeded state. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A condition reads $observed.refund_succeeded_events.count.
refund_created_events
E3
provider event
webhook
The refund.created events for the charge since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second refund.
Which conditions must all hold for VERIFIED?
Condition
Meaning
Path
Operator
Expected
Evidence
refund_status_succeeded
The refund resource shows the succeeded state.
$observed.refund_readback.status
eq
succeeded
refund_readback
refund_amount_matches
The refund amount equals the requested amount.
$observed.refund_readback.amount
eq
$input.amount
refund_readback
refund_created_in_window
The provider created the refund after the operation started. Stripe writes created in seconds since the epoch.
$observed.refund_readback.created
time_after
$operation.created_at
refund_readback
refund_event_succeeded
At least one refund.updated event of this refund carries the succeeded state.
$observed.refund_succeeded_events.count
gte
1
refund_succeeded_events
Which conditions give CONTRADICTED?
Condition
Class
Reason
Path
Operator
Expected
refund_on_wrong_charge
wrong subject
The refund belongs to a different charge.
$observed.refund_readback.charge
ne
$input.charge
refund_amount_mismatch
wrong amount
The provider refunded a different amount.
$observed.refund_readback.amount
ne
$input.amount
refund_predates_operation
pre existing state
The refund is older than the operation. It proves nothing.
$observed.refund_readback.created
time_before
$operation.created_at
duplicate_refund_present
duplicate side effect
Stripe created more than one refund for the charge since the operation started. Do not retry.
$observed.refund_created_events.count
gt
1
Which observed states map to a verdict before completion?
Rule
Match
Verdict
Reason
terminal_failure
$observed.refund_readback.status in ["failed"]
FAILED
The provider reports a failed refund.
still_transitional
$observed.refund_readback.status in ["pending","requires_action"]
PENDING
The refund is still moving. The runtime observes again later.
canceled
$observed.refund_readback.status eq "canceled"
CONTRADICTED
The refund was canceled. No funds will move.
How long does the runtime observe?
Timing member
Value
Initial delay
1000 ms
Poll interval
5000 ms
Backoff
exponential factor 2, max 60000 ms
Maximum attempts
40
Timeout
604800000 ms
Stale read window
20000 ms
On timeout
UNVERIFIABLE (evidence_unavailable_before_timeout), escalated to a person