The part that says no,
before anything is signed.
An agent's mistakes are cheap right up until it can move money. The guard is the boundary: it evaluates every intent against policy you declared, returns a verdict with a reason, and writes both to a ledger you can hand to a finance team.
import { createGuard } from "@moneolabs/guard"; const guard = createGuard({ perTransaction: { max: "$250" }, rolling24h: { max: "$2,000" }, velocity: { max: 20, per: "1m" }, counterparties: "allowlist-only", allow: ["x402:*", "0x9f3c…a71b", "stripe:acct_1Nz"], deny: ["mixer:*"], escalate: { above: "$500" },}); // Hand it to a wallet and it runs before every signature.const wallet = await createWallet({ agent, signer, rail, guard });Six primitives, composed however your risk team wants.
A ceiling per transaction, per counterparty, per asset class. The smallest useful policy is one line and stops the worst outcome.
Rolling windows rather than calendar months: an hour, a day, a week. A stuck retry loop burns the budget, then stops, instead of the balance.
Counterparties by address, domain, x402 endpoint, or merchant ID. Deny by default is the sane setting when the caller is a language model.
Rate limits on money, not requests. Ten payments a minute to the same address is a bug signature, whatever the amounts look like.
Above a threshold, the action pauses and a human approves it in Slack, email, or your own webhook. The agent gets a pending handle, not a failure.
Replay a proposed policy against last month's ledger before shipping it. See what would have been blocked, and what it would have cost you.
Every attempt, verdict included.
Blocked attempts are kept, not discarded. They are the record of what your agents tried to do, the most useful thing you own when tuning a policy.
Decision ledger
Guarded execution, all the way to the fill.
The Trading SDK routes every order through this same policy engine.