v0.2.0 — per-destination ceilings
Ratchet is an effect gate for AI agents: an agent asks before it does anything it
cannot take back, and gets a durable decision, so the same real-world action is
attempted at most once across crashes and retries.
This is the first tagged release. Everything below is enforced by a test.
Counting a destination without ever seeing it
A ceiling could be scoped to a workspace, an API key or an effect type. None of
those is a destination, so twenty distinct $500 refunds to one bank account
passed every check. A destination lives in the payload, and Ratchet never stores
payloads.
Counting does not require reading. A caller declares dimensions on begin;
only HMAC(secret, workspace | name | value) is kept. Ratchet cannot say who the
counterparty is and cannot reverse the value — and because the workspace id is
inside the MAC, the same account in two workspaces yields two unrelated
identifiers. It can still count.
PUT /v1/policies/payment.refund
{ "required_dimensions": ["counterparty"],
"dimension_limits": { "counterparty": { "daily_micros": 200000000,
"daily_count": 20 } } }
A declaration tightens and never loosens: it adds a limit, never removes the
workspace, key or type limits; omitting a required one is refused rather than
allowed; and a retry cannot move an effect into a fresh bucket.
Three analyses over the blinded ledger
GET /v1/analysis/structuring— amounts crowding a threshold, by comparing two
equal bands beneath it. Point it at a line Ratchet does not enforce with
structuring_threshold_micros.GET /v1/analysis/fan— fan-out measured by novelty, not width (payroll
reaches five hundred people every month and is fine), and fan-in, which no
per-agent ceiling can see.GET /v1/agents/{id}/reliability— reporting rate, decision mix from receipts,
idempotency-key hygiene, declared-versus-actual cost, lease hold.
None of them is a verdict, and each says so: a cap produces bunching honestly, and
a first payroll run is 100% new counterparties.
Also in this release
- Enterprise plan, sold rather than bought —
selfServe: falsemakes checkout
refuse it structurally. - Auto-recharge for overages, and card saving for non-subscribers.
- Signup returns a runnable next step, and
blockednow names the call that
clears it. - Mail survives a spent sending quota instead of being discarded within the
hour. - Roughly 12× lower p95 on the gate after removing five sequential round
trips.
Breaking
MCP tool names are now ratchet_<verb>_<object> throughout. Seven were
renamed off a second noun_noun pattern; heartbeat_effect became
extend_lease and check_effect became get_effect. MCP clients discover tools
at connect time, and the npm bin bridges to the live service, so this needs no
client change.
Full contract: https://ratchetgate.com/openapi.json