@axiru/spec
v0.1.0
Published
The Axiru policy and evidence vocabulary. Typed OutboundValueTransfer union, Policy v2 rule schema, rail registry, and x402 signed offer and receipt evidence records. Zero runtime dependencies.
Downloads
69
Maintainers
Readme
@axiru/spec
The policy and evidence vocabulary for agent payments.
One typed description of what an agent payment is, what a policy says about it, and what evidence proves it happened. Rail agnostic, transport agnostic, zero runtime dependencies, Apache-2.0.
npm install @axiru/specThe problem this solves
Agents can now move money over a growing list of protocols. Coinbase's x402 handles HTTP-native micropayments. Google's AP2 handles mandates and delegated authority. Catena's Agent Commerce Kit handles identity and receipts. MPP handles merchant charge intents. TAP handles travel-rule messaging between institutions. Stablecoin rails settle the value. Card rails still carry most of the volume.
Every one of those answers a different question, and none of them answers this one:
Given everything my organization knows, should this specific agent be allowed to move this specific amount to this specific counterparty, right now, and can I prove afterwards what was decided and why?
That question is not a protocol question. It is a policy and evidence question, and it has to be answered the same way regardless of which rail the money leaves on. Today every team that asks it invents its own vocabulary: a bespoke shape for "a payment an agent wants to make", a bespoke rule format, a bespoke record of what happened. None of them interoperate, none of them survive a rail migration, and none of them are auditable by anyone outside the team that wrote them.
@axiru/spec is that missing vocabulary, written down and versioned.
Where it sits
┌──────────────────────────────────────────────────────┐
│ Policy and evidence ← @axiru/spec lives here │
│ What is allowed. What was decided. What is proven. │
└──────────────────────────────────────────────────────┘
▲
│ one vocabulary across all of them
│
┌──────────┬──────────┬───────┴────┬──────────┬─────────────┐
│ ACK │ x402 │ MPP │ AP2 │ TAP │
│ identity │ HTTP 402 │ merchant │ mandates │ travel rule │
│ receipts │ payments │ intents │ │ messaging │
└──────────┴──────────┴────────────┴──────────┴─────────────┘
▲
┌─────────────────────────────┴─────────────────────────────┐
│ Settlement rails: stablecoins, cards, ACH, wallets │
└───────────────────────────────────────────────────────────┘This spec is complementary to all of them and competes with none of them. It does not move money, does not define a transport, does not define an identity system, and does not replace a facilitator. It sits one layer up and describes the governance decision that should happen before any of those protocols run, plus the evidence record that should survive after they do.
If you already speak x402, keep speaking x402. This gives you a way to say what your organization allows over it, in a form that still means the same thing when you add a second rail next quarter.
What is in the vocabulary
1. OutboundValueTransfer
A discriminated union over rail that describes any outbound movement of value, initiated by a human or by an agent. One shape for x402, mpp, ucp, tempo, usdc_base, usdc_solana, pyusd, plaid_ach, modern_treasury, dwolla, square, stripe, stripe_daa, and ad_platform.
Amounts are always integer strings in minor units. There are no floats anywhere in this spec, on purpose.
import type { OutboundValueTransfer } from "@axiru/spec";
const transfer: OutboundValueTransfer = {
rail: "x402",
rail_action: "pay",
amount: { currency: "USDC", minor_units: "12000000" }, // 12 USDC
initiator: { kind: "agent", id: "agent_procurement_1" },
counterparty: { id: "https://api.datavendor.example/reports", kind: "merchant" },
// ...rail-specific fields, narrowed by the discriminant
};The agent_payment extension carries the agent-specific facts that generic payment schemas have no place for: which model, which tool call, which session, which mandate, which principal the agent is acting for.
2. Policy v2
A rule language for the org-level question, with an explicit precedence ladder and stable reason codes.
Rule kinds: rail, rail_action, amount, initiator_kind, initiator_id, agent_scope, counterparty, rolling_window, time_of_day, custom_expression, agent_budget, agent_approval_tier, mandate_scope.
Effects: allow, require_approval, deny, quarantine. Modes: shadow and enforcing, so a policy can be observed for a billing cycle before it blocks anything.
import type { PolicyV2 } from "@axiru/spec";Reason codes are part of the contract, not a log string. The axiru.* prefix is reserved for codes the evaluator itself emits (axiru.deny.amount_exceeded, axiru.pending.approval_required, axiru.deny.unknown_rail, and the rest). Your own policies use any other prefix, customer.* by convention. A reason code is the thing an auditor reads, an alert fires on, and a test asserts against, so it is versioned as carefully as the types.
The spec is fail-closed by construction. When velocity aggregates or budget inputs are missing, an enforcing rule resolves to require_approval rather than silently treating the missing input as zero.
3. Evidence records
The x402 signed offer and receipt formats, plus the verification result types: OfferPayload, ReceiptPayload, JwsSignedOffer, Eip712SignedReceipt, VerifiedOffer, VerifiedReceipt, ReceiptMatchResult, AuthorizedSettlementExpectation.
The last one matters more than it looks. Verifying that an offer and a receipt are well formed and correctly signed is necessary but not sufficient; a valid receipt for the wrong amount is still the wrong payment. AuthorizedSettlementExpectation binds the evidence to the value that policy actually authorized, which is what closes the loop between the decision and the settlement.
4. Rail registry
Rail, PHASE_1_ACTIVE_RAILS, PHASE_2_RESERVED_RAILS, and an assertUnreachableRail helper so adding a rail is a compile error at every site that has to care, rather than a silent fallthrough.
Design rules
These are the constraints that make the vocabulary usable as a shared contract rather than one team's internal types:
- Integer strings, never floats. Every amount is
{ currency, minor_units }withminor_unitsas a decimal string. Rounding disagreements are not a category of bug this spec permits. - Discriminated unions, never optional soup. Rail-specific fields are narrowed by the
raildiscriminant. If a field only makes sense for one rail, it only exists on that rail. - Additive changes only. Every export here is a wire-format contract. Anything that is not strictly additive is a major version.
- Fail closed. Missing inputs degrade to
require_approval, never toallow. - No runtime dependencies. Types plus a handful of pure type guards. Nothing to audit, nothing to pin, nothing that phones home.
- Replayability is a first-class property. Decisions are pure functions of (transfer, policies, history, timestamp), fingerprinted over canonical JSON, so any decision can be re-run bit for bit years later.
Reference implementations
The vocabulary is implemented by these packages, all Apache-2.0:
| Package | What it does |
| --- | --- |
| @axiru/agent-spend-guardrails | In-process policy evaluator. Give it a transfer and a policy set, get allow / require_approval / deny with reason codes and a replay fingerprint. |
| @axiru/x402-policy-middleware | Pre-authorization for x402 facilitator flows, plus MPP charge-intent mapping. |
| @axiru/x402-receipt-verifier | Independent JWS and EIP-712 verification of signed offers and receipts. |
The narrative spec for the policy half, including the precedence ladder, rule semantics, and a conformance checklist for independent implementations, is the Agent Spend Policy Spec v0.2 draft.
Versioning
0.x while the vocabulary settles. Breaking changes are called out in the changelog with a migration note. From 1.0 the additive-only rule above becomes a semver promise.
Contributing
The most useful contribution right now is a rail this vocabulary describes badly. If your payment does not fit OutboundValueTransfer, or your control does not fit a Policy v2 rule kind, open an issue with the concrete shape. Gaps found by people outside the original authoring team are the only reliable evidence that a vocabulary is general.
Who maintains this
Axiru builds governance infrastructure for agent-initiated payments: a hosted evidence ledger, approvals inbox, and multi-rail ingestion built on this exact vocabulary. The spec and the reference implementations are open source and complete on their own. Nothing here requires an Axiru account. See axiru.com.
License
Apache-2.0. Copyright 2026 Axiru. See LICENSE.
