Execution control for autonomous agents

Your agent retried.
Do you know what it already did?

Ratchet is how you let an agent do things it cannot take back — charge a card, ship a deploy, publish a package, send the email — and know what it already did, what that cost, and what it may still spend.

  • Never twice. A retry, a restart and two workers racing all get the same answer.
  • Never a guess. When nobody can know whether it happened, we say so instead of assuming.
  • It remembers for you. An agent that lost its context asks what it already did — one call, not a re-derivation.
  • It cannot overspend. Give a task a budget and the gate refuses the step that would cross it.

Works with anything that makes an HTTPS request · 1,000 effects a month, free · No card · Two HTTP calls

If you are a person

An email is all it takes — no card. The key and console are yours immediately; confirm the address and the free plan's 1,000 gated effects a month switch on.

Create a workspace

If you are an agent

Call the gate. The first request needs no credential at all — a real workspace and key come back with the decision, capped at 100 effects.

curl -X POST https://ratchetgate.com/v1/effects/begin \
  -H 'content-type: application/json' \
  -d '{"effect_type":"email.send","idempotency_key":"demo-1","payload":{}}'

Same product, two doors. An agent that started on its own can be handed to a person later: claim the workspace with an email and the cap lifts to the free plan. No migration, and the key does not change. Read the docs · Five-minute setup

The setup

Your agent is about to charge a card

It cannot know whether it already did that ninety seconds ago, in a process that died before it could write anything down.

your agent
ratchet
the vendor
1

One call, before acting

It asks first

Ratchet takes a durable record and hands back a lease. This is the only call in the entire product that costs you anything.

your agent
ratchet
the vendor
1
execute — you hold the lease

Your code, your vendor

Now it acts

Ratchet never touches the vendor. No credentials, no outbound access, no proxy. Your code does the work and reports what happened.

your agent
ratchet
the vendor
1
1charge made
succeeded — result recorded

The moment that pays for itself

Then the retries arrive

A supervisor re-runs the task. Two workers pick it up in parallel. The agent wakes from a crash and tries again. Four more callers, one after another.

your agent
ratchet
the vendor
1
2
3
4
5
1charge made
duplicate — replay the result, do not act

The case nobody else admits to

And when it crashes mid‑charge?

The lease expires with nothing reported. Ratchet does not guess. The effect becomes indeterminate — a known unknown — and your policy for that effect type decides what happens next. Never a silent retry.

your agent
ratchet
the vendor
?
indeterminate — verify before you touch it

New: reversible effect groups

Four steps in. Step five fails.

Declare the steps as one unit of work and how to undo each. When it breaks, Ratchet hands back the exact rollback plan — in reverse, because the last thing done is the first thing to undo.

undo hotel.book → hotel.cancel
undo flight.book → flight.cancel
undo seat.reserve → seat.release
each undo is itself gated — no double refunds

Both of those, run for real

A booking agent gets four steps in and the payment declines. A loop bug fires a hundred distinct charges. Here are both, against the live service, with the transcripts — and the number we had to throw away.

Read the worked scenarios
100 concurrent attempts, settled in 341ms:
    80  denied
    20  execute

Reached the vendor: 20. Held back: 80.

The problem is not that agents fail. It's that they retry.

An LLM's control flow is non-deterministic. Network calls fail ambiguously. Processes die mid-action. So the same logical action gets attempted zero, one, or several times — and nothing in your stack knows which.

The timeout that wasn't

Your agent posts a charge. The connection drops before the response. Did it go through? The agent guesses, retries, and the customer is billed twice.

The helpful second try

A supervisor loop notices a subtask “didn't finish” and re-runs it. The subtask had already sent the announcement to 4,000 people.

The parallel worker

Two agents pick up the same queue item a second apart. Both check “has this been done?” in their own memory. Both see no, and both act.

Vendor idempotency keys help for the handful of vendors that offer them. They do nothing for SMTP, Slack, git, internal APIs, or the other twenty tools your agent touches — and nothing at all across separate processes.

What a repeat actually costs

Not knowing is the expensive part

An agent that cannot tell whether it already charged the card has three options, and all three cost you.

Do it again

Charged twice. You refund it and eat the fee.

Don't

The work never completes, and you hear it from the customer.

Work it out

A vendor round trip plus a model turn — on every ambiguous action, forever.

The gate replaces all three with one lookup. A repeat is answered from the recorded outcome in 2.3ms, a new effect in 5.1ms, and a capped runaway loop let 20 of 100 attempts through — measured with the scripts in the repository, in process and excluding the network time to you. The transcripts.

Ratchet never sees your model calls and does not make inference cheaper. What it removes is the work you would do to find out what already happened. Your console adds up the refusals in dollars not spent at vendors, and reports it as at least that, because effects without a declared cost are not counted.

New

A run gets a memory, and a wallet

An agent's memory of what it has done lives in its context window — lossy under compaction, paid for again every turn, and impossible to check. It can sincerely believe it sent the email and be wrong.

Ask what you already did

GET /v1/runs/trip-8812

{ "done":    [ { "what": "flight.book", "outcome": "succeeded" } ],
  "unknown": [],
  "budget":  { "remaining_micros": 140000 },
  "next":    "Everything under this run is settled." }

Successes come back with their recorded results. Unknown outcomes are kept separate — the only category that can hurt you.

Give the task a budget

PUT /v1/runs/trip-8812/budget
{ "limit_micros": 50000000 }

This job may spend fifty dollars was a sentence nobody could say: daily limits bind a key or an effect type, and neither is a task.

A day is not a task. One stuck agent, three days, both limits set to $200. A daily ceiling hands the allowance back every midnight, so the same money leaves again tomorrow. A run budget never refills, so there is nothing to wait for.
Daily ceiling $600 Run budget $200 See it drawn out →

The half that matters is not the ceiling — budgets could always refuse. It is that the agent can read its own balance, and one that sees what is left takes the cheaper path or stops cleanly, instead of learning the limit exists at the moment it spends. It cannot raise that ceiling: reading needs the scope agents carry, setting needs one they do not.

A twelve-step task listed in full is 10.1KB of context. The digest is 0.6KB — about seventeen times smaller, because a memory that costs more than re-deriving the answer does not get used.

Ask before you act

One call before the action, one call after. Ratchet holds the durable record.

Ratchet never performs the action. It has no access to your vendors, your credentials, or your payload — only a hash of it.

Six answers. Only one means go.

execute You hold the lease. Perform the action, then report.
duplicate Already done. Replay the recorded result. Don't act.
in_flight Another process holds a live lease. Back off.
blocked A prior attempt's outcome is unknown. Verify first.
approval_required An operator must approve this one.
denied Policy or budget refused it.

The part that makes it worth paying for

When we don't know, we say so.

If your process dies between “go” and “done”, most systems quietly let the next caller retry. Ratchet won't. The lease expires and the effect becomes indeterminate — a known unknown, surfaced instead of buried.

block

The default, and the right choice for anything irreversible. No automatic retry. A human or a verifying agent resolves it after checking what really happened.

retry

For actions where the vendor is genuinely idempotent, or a duplicate is harmless. You opt in per effect type — never by default, because we can't know that for you.

probe

The caller must verify the outcome at the vendor and record evidence before anything else may proceed. For charges, transfers, and anything you'd have to apologise for.

Exactly-once delivery is not achievable in a distributed system, and we won't claim it. What Ratchet guarantees is at-most-once initiation, a recorded outcome that later callers replay, and an explicit state for the case nobody else admits exists.

The agent's door

The first call needs no key

An agent that finds this service shouldn't have to wait for a human to go and register. Send the first request with no credential at all: you get a real decision, and a workspace and API key come back with it.

curl -X POST https://ratchetgate.com/v1/effects/begin \
  -H 'content-type: application/json' \
  -d '{"effect_type":"email.send","idempotency_key":"welcome:user_123","payload":{}}'

→ { "decision": "execute",
    "workspace": { "api_key": "rk_live_…", "quota": 100 } }

Store the key — it is returned once. The workspace is a real gate, not a demo that always says yes, and it is capped at 100 gated effects until you claim it with an email. Claiming lifts it to the free plan.

It provisions a new workspace and can never reach an existing one, so this is the only unauthenticated write in the service. Everything that touches data you already have still needs a key.

Signed receipts

Don't trust us. Check us.

A gate's work is invisible. The charge that did not happen leaves no trace, and "trust us, we stopped it" is unfalsifiable — a poor place to stand for a product whose pitch is rigour.

Every decision leaves a signed receipt, refusals most of all. Verify one offline against a published Ed25519 key, without asking us anything. They are hash-chained, so removing one breaks every link after it.

And a gate only sees the calls that reach it — the old cron job that never asked is invisible to us and to you. POST /v1/reconcile closes that: send the keys your vendor acted on, and we say which ones we authorised. Anything we do not recognise is a path where a retry can act twice. How all of this is built, and what we do not claim.

Two of the three below are issued by somebody who is not us. The third is a self-certification against a public checklist — labelled as one, because that is what it is.

Measured, not asserted

Forty refunds. One run gated, one not.

scroll to run

The vendor performs every request it receives; a quarter of the responses are lost coming back. The agent retries, because retrying is correct. Each mark is a refund the vendor really made.

without the gate with the gate
Duplicate refunds0
Paid out twice$0
With the gate$0

Assume it has been turned

The agent is compromised. It still cannot get out.

scroll

A poisoned instruction, a stolen key, a loop that will not stop. Twenty payouts of $500, all to one destination, every one correctly authorised. A ceiling of $2,000 a day is configured on that destination — and Ratchet has never seen what the destination is.

Permitted0
Refused0
Withheld$0

 

That is the whole product.

Everything below is optional depth — the controls you will want on the day you need them, and the practical answers about platforms, payment and price.

The rest of it, in one place

Each of these is a real control with a real page behind it. None of them is something you need on day one.

  • A loop that never fails Every call succeeds, so nothing alerts — and the bill arrives anyway. Set a ceiling per effect type, or a multiple of your own normal, and the breaker trips.
  • Agents that never ask The gate only stops the code that calls it. Where a vendor honours idempotency keys, Ratchet derives the one they deduplicate on, so the refusal happens at their end whether or not your agent cooperated.
  • Step five of five fails Declare the steps as one unit and how to undo each. Ratchet returns the rollback plan in reverse order — and each undo is itself gated, so a retried refund cannot double.
  • Approvals, webhooks, audit Effects above a threshold can wait for a human. Every decision fans out to your webhooks, signed. Everything lands in an audit trail you can read.

Works with whatever you're building on

Plain HTTP, or MCP over stdio and streamable HTTP. No SDK required.

Verified against Claude Code / Claude Desktop, Cursor, and any MCP client that speaks stdio or streamable HTTP. The REST API is provider-neutral — nothing about it assumes a model vendor.

Paying for it

Card or crypto, never custody

Subscribe with a card, or top up prepaid credit with USDC on Solana. Crypto is non-custodial: payments go straight to an address the operator controls and Ratchet only watches the chain. It holds no key and takes custody of nothing.

Quotes are struck in USD and the credit granted is the USD amount, so a price move between quote and settlement cannot mint credit that was not paid for. Volatile assets are refused rather than quoted at a guessed price — that is a treasury decision, not an engineering one.

Priced on what you're protecting

One meter: a gated effect — the first time you ask about a given idempotency key. Duplicate suppression, in-flight checks, retries, reports, and reads are all free. You are never charged for the retry behaviour the product exists to absorb.