Ask permission to perform a side effect
ratchet_begin_effectCall this IMMEDIATELY BEFORE performing any side effect that touches the outside world (sending a message, charging a card, creating a resource, writing to someone else's system). Returns a decision you MUST obey. If the response carries budget_warning, a spend ceiling exists but nothing was counted toward it — surface that to the operator rather than ignoring it. Decisions:
"execute": you hold the lease. Perform the action now, then call ratchet_report_effect. If the response carries vendor_idempotency_key, send that key to the vendor as ITS own idempotency key (the response says where it goes). Where enforced is true the vendor itself will then refuse a duplicate, which protects the action even if some other caller skips this gate entirely.
"duplicate": this action ALREADY HAPPENED. Do NOT perform it. Use the returned
resultas though you had just done the work."in_flight": another process is doing it right now. Do NOT perform it. Wait
retry_after_secondsand ask again."blocked": an earlier attempt may or may not have taken effect. Do NOT perform it. Tell the user what is unresolved, or verify at the vendor and call ratchet_resolve_effect.
"approval_required": a human must approve. Do NOT perform it.
"denied": policy or budget refused it. Do NOT perform it. The idempotency_key must be derived deterministically from the work itself so that a retry of the same logical action produces the same key. Never use a random value or the current time.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | No | Groups all effects from one task or run. | |
| vendor | No | Which vendor performs this effect (e.g. "stripe", "square", "adyen"). Shapes vendor_idempotency_key so it satisfies that vendor's rules. | |
| payload | No | The action's parameters. Only a hash is stored — the raw content never persists. Reusing a key with different parameters is rejected, which catches key collisions. | |
| agent_id | No | Identifier for you, the calling agent. | |
| group_key | No | Use when this action is one step of a multi-step workflow that must succeed or fail as a whole, e.g. "booking:trip_8812". Lets the whole unit be rolled back later. | |
| effect_type | Yes | Namespaced kind of side effect, e.g. "email.send", "payment.charge", "github.pr.create". Policy is configured per type. | |
| compensation | No | How to undo THIS step if the workflow has to be rolled back. Declare it now, while you still know what undoing means — it cannot be worked out later. Steps without one are permanent. | |
| lease_seconds | No | How long you expect the action to take. Report before this elapses or the effect becomes indeterminate. | |
| idempotency_key | Yes | Deterministic identifier for this specific logical action, e.g. "welcome-email:user_123" or "invoice:2026-08:acct_88123". The SAME action retried must produce the SAME key. | |
| compensates_effect_id | No | Set when THIS call IS an undo, naming the effect it reverses. Comes from ratchet_unwind_group. | |
| estimated_cost_micros | No | What this action will cost at the third party, in micro-USD (1000000 = $1). ALWAYS SEND THIS when the action costs money. Spend ceilings are computed from it, and a ceiling with nothing declared against it never fires — the operator would be relying on a limit that cannot trigger. If the response contains budget_warning, that is exactly what has happened: tell the operator. Ratchet does not collect this money; it only counts it. |