{"_id":"@axiru/agent-spend-guardrails","_rev":"2-6ba9f6aedfb6b618e2e9484060b62a45","name":"@axiru/agent-spend-guardrails","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@axiru/agent-spend-guardrails","version":"0.1.0","keywords":["ai-agents","agent-payments","spend-controls","guardrails","policy-engine","x402","stablecoins"],"author":{"name":"Axiru"},"license":"Apache-2.0","_id":"@axiru/agent-spend-guardrails@0.1.0","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/agent-spend-guardrails#readme","bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"dist":{"shasum":"d5e262469760e0ca0fb167a0baf50648b4ca36cd","tarball":"https://registry.npmjs.org/@axiru/agent-spend-guardrails/-/agent-spend-guardrails-0.1.0.tgz","fileCount":23,"integrity":"sha512-ViQuU46u36/lyBg9bgUW0XqQhlXC7uXvkOuOyF7AVDX4B3P8Q2W5GWk1I61R5Co7bBAYfKycgFvnZoWC7CWyHw==","signatures":[{"sig":"MEYCIQDzh3zoVNFhkDjXBM2r04g52Yi1OP0EklBWKR7kzy0FzwIhAPKI4/Z9GuifDy46YIAwMZPfvaIi+zfKmmGr3Nq6p7Vr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":227013},"main":"dist/agent-spend-guardrails/src/index.js","type":"module","types":"dist/agent-spend-guardrails/src/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/agent-spend-guardrails/src/index.d.ts","import":"./dist/agent-spend-guardrails/src/index.js"}},"gitHead":"9601ad2c5bda7c27bbf866b78f390fc0f3ee8ee7","private":false,"scripts":{"lint":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node scripts/bundle-engine.mjs && node dist/agent-spend-guardrails/src/index.test.js && node dist/agent-spend-guardrails/src/presets.test.js","build":"tsc -p tsconfig.json && node scripts/bundle-engine.mjs","prepack":"pnpm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"repository":{"url":"git+https://github.com/AxiruAI/axiru-oss.git","type":"git","directory":"packages/agent-spend-guardrails"},"_npmVersion":"11.8.0","description":"Deterministic spend guardrails for AI agents. Define policies, evaluate spend intents, get allow / require_approval / deny with stable, replayable reason codes. No SaaS dependency.","directories":{},"_nodeVersion":"24.13.1","dependencies":{"@axiru/spec":"workspace:*"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/agent-spend-guardrails_0.1.0_1785886203889_0.1574942214210837","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@axiru/agent-spend-guardrails","version":"0.1.1","description":"Deterministic spend guardrails for AI agents. Define policies, evaluate spend intents, get allow / require_approval / deny with stable, replayable reason codes. No SaaS dependency.","license":"Apache-2.0","private":false,"author":{"name":"Axiru"},"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/agent-spend-guardrails#readme","repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/agent-spend-guardrails"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"type":"module","main":"dist/agent-spend-guardrails/src/index.js","types":"dist/agent-spend-guardrails/src/index.d.ts","exports":{".":{"types":"./dist/agent-spend-guardrails/src/index.d.ts","import":"./dist/agent-spend-guardrails/src/index.js"}},"keywords":["ai-agents","agent-payments","spend-controls","guardrails","policy-engine","x402","stablecoins"],"scripts":{"build":"tsc -p tsconfig.json && node scripts/bundle-engine.mjs","lint":"tsc --noEmit","typecheck":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node scripts/bundle-engine.mjs && node dist/agent-spend-guardrails/src/index.test.js && node dist/agent-spend-guardrails/src/presets.test.js","example":"node examples/run-demo.mjs","prepack":"pnpm run build"},"engines":{"node":">=18"},"publishConfig":{"access":"public","provenance":true},"dependencies":{"@axiru/spec":"^0.1.0"},"devDependencies":{"@types/node":"^25.9.1","typescript":"^5.6.3"},"gitHead":"a231ab3f691b1d3e0b18ff6f22a5d14ecaaf5cf3","_id":"@axiru/agent-spend-guardrails@0.1.1","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-4zRx0E6dnlN57Y5CSTd/5gGMabyI+fgU3L1ynI/Ftq3qIrDk+K8KSLjSdOizdRTwP1M6p/A3zu+JdLDorZmDNQ==","shasum":"1703198852b7f64b4ca266eab22f72125c8947e5","tarball":"https://registry.npmjs.org/@axiru/agent-spend-guardrails/-/agent-spend-guardrails-0.1.1.tgz","fileCount":23,"unpackedSize":230719,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDOpPgfzL/cDawwuMLsomP8F2ejFyDuKFWXN2JazqEe6AIhAP4ShuOmPUxlVQE34yZIR0NPRkxRZ+QUZZ212Ul0P+6X"}]},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"directories":{},"maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-spend-guardrails_0.1.1_1786468576576_0.4157931581686374"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T23:30:03.700Z","modified":"2026-08-11T17:16:16.931Z","0.1.0":"2026-08-04T23:30:04.048Z","0.1.1":"2026-08-11T17:16:16.731Z"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"author":{"name":"Axiru"},"license":"Apache-2.0","homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/agent-spend-guardrails#readme","keywords":["ai-agents","agent-payments","spend-controls","guardrails","policy-engine","x402","stablecoins"],"repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/agent-spend-guardrails"},"description":"Deterministic spend guardrails for AI agents. Define policies, evaluate spend intents, get allow / require_approval / deny with stable, replayable reason codes. No SaaS dependency.","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"readme":"# @axiru/agent-spend-guardrails\n\nSpend guardrails for AI agents in 30 lines of TypeScript.\n\nYour agents can already move money: x402 micropayments, stablecoin transfers, Stripe refunds. This package answers the question every one of those transfers should pass through first: **is this agent allowed to make this payment, right now, to this counterparty, at this amount?**\n\n```\nallow | require_approval | deny\n```\n\nDeterministic. Replayable. No SaaS dependency. Apache-2.0.\n\n## Why this exists\n\nProtocol-level controls (x402 payment extensions, wallet policy engines, per-key spending limits) answer \"can this key sign this transaction\". They are necessary and this package is complementary to them, not a replacement. What they cannot answer is the org-level question: is this spend consistent with *your* rules across every rail your agents touch, with an audit trail a human can replay?\n\n`agent-spend-guardrails` is that org-level layer, extracted from the production decision engine behind [Axiru](https://axiru.com). It runs entirely in your process:\n\n- **Deterministic.** Same intent, same policies, same history, same timestamp: identical decision, identical reason codes, identical `sha256:` fingerprint. No wall clock reads (when you pass a timestamp), no I/O, no randomness.\n- **Replayable.** Every result carries a canonical-JSON fingerprint and a decision id derived from it. Persist the inputs and you can reproduce any decision bit for bit, years later.\n- **Fail closed.** Unknown rails, unevaluable rules, and missing velocity aggregates never fall through to a silent allow. The worst case is always `require_approval` or `deny`.\n- **Zero heavy dependencies.** Node 18+, `node:crypto`, and the pure evaluator. Nothing phones home.\n\n## Quickstart\n\n```bash\nnpm install @axiru/agent-spend-guardrails\n```\n\n```typescript\nimport {\n  defineSpendPolicy,\n  guardAgentSpend,\n  humanApprovalAboveAmount,\n  perAgentDailyCap\n} from \"@axiru/agent-spend-guardrails\";\n\nconst policies = [\n  // Anything at or above 50 USDC goes to a human first.\n  humanApprovalAboveAmount({ currency: \"USDC\", threshold_minor_units: \"50000000\" }),\n\n  // This agent may spend at most 100 USDC per rolling 24h.\n  perAgentDailyCap({ agent_id: \"agent_procurement_1\", currency: \"USDC\", cap_minor_units: \"100000000\" }),\n\n  // And a custom rule: never let agents pay wallets in embargoed countries.\n  defineSpendPolicy({\n    name: \"Block embargoed countries\",\n    rules: [{ kind: \"counterparty\", country_in: [\"KP\", \"IR\"] }],\n    effect: { kind: \"deny\", reason_code: \"customer.deny.embargo\", reason_text: \"Embargoed country\" }\n  })\n];\n\nconst result = guardAgentSpend({\n  intent: {\n    rail: \"x402\",\n    action: \"pay\",\n    amount: { currency: \"USDC\", minor_units: \"12000000\" }, // 12 USDC, always integer strings\n    agent: { id: \"agent_procurement_1\", model: \"claude-sonnet-4-6\", scope: \"payments.create\" },\n    counterparty: { id: \"https://api.datavendor.example/reports\", kind: \"merchant\" },\n    timestamp: new Date()\n  },\n  policies,\n  history: { amount_24h: \"38000000\", count_24h: 6 } // this agent's prior 24h spend\n});\n\n// result.decision     -> \"allow\" | \"require_approval\" | \"deny\"\n// result.reason_code  -> e.g. \"guardrails.deny.daily_cap_exceeded\"\n// result.reasons      -> full audit trail, winner first\n// result.fingerprint  -> \"sha256:...\" replay and idempotency key\n```\n\nExecute the transfer only when `result.decision === \"allow\"`. On `require_approval`, hold it and route to a human. On `deny`, drop it and log the reasons.\n\n## Use it from your own agent code\n\nMost adopters wire this into a custom agent built on an SDK or framework. The [`examples/`](./examples) directory has three worked integrations with a shared README: a [LangGraph payment tool node](./examples/langgraph-guarded-tool.ts), a [CrewAI tool that calls the hosted decision API from Python](./examples/crewai-guarded-tool.py), and a [plain Anthropic SDK tool-use loop with a guarded executor](./examples/sdk-tool-runner-guard.ts), plus a runnable demo (`pnpm example` after a build). The core is always the same ten lines, shown here exactly as they appear in this package's test suite (`testReadmeTenLineExample`, a passing test):\n\n```typescript\nconst policy = defineSpendPolicy({\n  name: \"Deny large transfers\",\n  rules: [{ kind: \"amount\", currency: \"USDC\", gte: \"10000000\" }],\n  effect: { kind: \"deny\", reason_code: \"customer.deny.too_large\", reason_text: \"Over the limit\" }\n});\nconst result = guardAgentSpend({\n  intent: {\n    rail: \"usdc_solana\", action: \"transfer\",\n    amount: { currency: \"USDC\", minor_units: \"25000000\" },\n    agent: { id: \"agent_1\" }, counterparty: { id: \"vendor_api\" },\n    timestamp: new Date(\"2026-07-08T12:00:00.000Z\")\n  },\n  policies: [policy]\n});\n```\n\nHere `result.decision` is `\"deny\"` and `result.reason_code` is `\"customer.deny.too_large\"`: 25 USDC against a 10 USDC ceiling. Put those lines in front of your tool executor and no payment tool can fire without a decision.\n\n## The API\n\nTwo functions. That is the whole surface.\n\n### `defineSpendPolicy(init)`\n\nBuilds a policy document conforming to the [Agent Spend Policy Spec v0.2](../../docs/oss/agent-spend-policy-spec-v0.2.md) (`schema_version: 2`), with sensible defaults: `enforcing` mode, `version: 1`, local org. Rules within a policy are ANDed; separate policies are ORed. Ten rule kinds are available: `rail`, `rail_action`, `amount`, `initiator_kind`, `initiator_id`, `agent_scope`, `counterparty`, `rolling_window`, `time_of_day`, and `custom_expression` (a sandboxed, budgeted, deterministic expression language).\n\n### `guardAgentSpend({ intent, policies, history })`\n\nEvaluates one spend intent against the policy set and returns `{ decision, reason_code, reasons, summary_code, fingerprint, decision_id, evaluated_at }`.\n\n- `intent` is the simplified shape shown above: rail, action, amount (currency + integer-string minor units), agent, counterparty, timestamp.\n- `history` is optional precomputed rolling-window aggregates (`amount_24h`, `amount_30d`, `count_24h`, `count_30d`) covering PRIOR activity only. The evaluator never does I/O, so velocity rules compare against whatever you supply. Scope the aggregates to match your policy's intent: per-agent caps want per-agent sums. `sum_amount` comparisons are request-inclusive (the engine adds the intent under evaluation before comparing), so a single oversized transfer cannot leap an amount cap.\n- Precedence: `deny` beats `require_approval` beats `allow`. One matched deny wins no matter how many allows also matched.\n\n**Zero-sentinel escalation:** if an enforcing policy in scope has a `rolling_window` rule and you supply no history (or all zeros), the guard cannot tell \"no prior activity\" from \"forgot to compute aggregates\". It demotes a clean allow to `require_approval` with `guardrails.pending.velocity_inputs_unavailable`. A brand-new agent's first transfer under a velocity policy gets exactly one conservative approval. This is deliberate and inherited from the production engine.\n\n## Presets\n\n| Preset | What it does | Effect | Reason code |\n| --- | --- | --- | --- |\n| `perAgentDailyCap` | Trailing-24h spend cap for one agent | deny | `guardrails.deny.daily_cap_exceeded` |\n| `humanApprovalAboveAmount` | Route single transfers at or above a threshold to a human | require_approval | `guardrails.pending.above_approval_threshold` |\n| `counterpartyAllowlist` | Deny payment to any counterparty not on the list | deny | `guardrails.deny.counterparty_not_allowlisted` |\n| `businessHoursOnly` | Block (or escalate) spend outside business hours in an IANA timezone | deny or require_approval | `guardrails.deny.outside_business_hours` |\n| `velocityCountCap` | Circuit breaker on transfer count per window (catches runaway retry loops) | require_approval or deny | `guardrails.pending.velocity_count_exceeded` |\n\nEvery preset accepts `mode: \"shadow\"` to observe before enforcing.\n\n## Graduated autonomy\n\nThe intended adoption path, and the one the hosted platform is built around:\n\n1. **Shadow.** Ship every policy with `mode: \"shadow\"`. Decisions stay `allow`, but the reason trail records what *would* have happened (`guardrails.deny.shadow_mode_forced` in `summary_code`). Watch it for a billing cycle.\n2. **Enforce with a human lane.** Flip to `enforcing` with `require_approval` effects. Agents keep working; the risky tail waits for a person.\n3. **Widen autonomy.** As an agent earns trust, raise its caps and convert approval lanes to allows. Tighten instantly by editing a policy; no agent redeploys.\n\n## Determinism and replay\n\nEvery decision is a pure function of `(intent, policies, history, timestamp)`. The result's `fingerprint` is a SHA-256 over the canonical-JSON form of the intent (sorted keys at every level, integer-string amounts, no floats), computed with `node:crypto`. Store the inputs alongside `fingerprint` and `decision_id` and you have an audit log you can replay against any future version of the engine to detect drift.\n\nIf you want that as a service (a tamper-evident evidence ledger, approvals inbox, multi-rail ingestion, decision replay across policy versions, SOC 2 export), that is [Axiru's hosted platform](https://axiru.com), which runs this exact evaluator. The OSS package is complete without it.\n\n## Relationship to protocol-level controls\n\n| Layer | Example | Question answered |\n| --- | --- | --- |\n| Key / wallet | Per-key spending limits, MPC policy engines | Can this key sign this transaction? |\n| Protocol | x402 payment extensions, facilitator limits | Is this payment well-formed for this rail? |\n| **Org (this package)** | **agent-spend-guardrails** | **Is this spend consistent with our rules, across all rails, with a replayable audit trail?** |\n\nRun all three. Protocol controls cannot see cross-rail velocity or org-wide counterparty policy; org controls cannot stop a leaked key. They compose.\n\n## Spec\n\nThe policy document format, rule semantics, precedence ladder, and reason-code namespaces are specified in the [Agent Spend Policy Spec v0.2 (draft)](https://github.com/AxiruAI/axiru-oss/blob/main/docs/oss/agent-spend-policy-spec-v0.2.md), published July 2026 under Apache-2.0 and derived from the production engine. Conforming implementations exist in TypeScript (this package and the hosted engine); the spec includes a conformance checklist for independent implementations.\n\n## Related packages\n\n- [`@axiru/spec`](https://www.npmjs.com/package/@axiru/spec) is the shared policy and evidence vocabulary this package speaks.\n- [`@axiru/x402-policy-middleware`](https://www.npmjs.com/package/@axiru/x402-policy-middleware) applies the same decision to x402 facilitator flows.\n- [`@axiru/x402-receipt-verifier`](https://www.npmjs.com/package/@axiru/x402-receipt-verifier) verifies the evidence that comes back after settlement.\n\n## License\n\nApache-2.0. Copyright 2026 Axiru. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}