# @agentguard-run/spend

## Functional-Use Disclaimer

DISCLAIMER: All terminology and labels used in AgentGuard’s materials are descriptive of
software functionality only, not legal definitions or guarantees of compliance. For example, the
terms “receipt,” “audit log,” “evidence,” “audit trail,” and “attestation” refer solely to
cryptographically-signed records produced by AgentGuard’s software. These terms do not mean
that any record is legally binding evidence, certified by any authority, or equivalent to records
maintained by banks, auditors, or courts. Similarly, references to “signed,” “verified,” or “attested”
pertain to digital signature processes, not to notarization or governmental attestation. Any use of
the word “compliance,” “compliant,” “outcome,” or “settlement” describes the software’s features in
a non-regulatory sense. In particular, “capability tier” is merely an internal category of agent
permission levels, and does not correspond to any government or industry regulatory classification.
Likewise, any statement that an operation “settles” or an outcome is “settled” refers only to the
software’s final state, not to any legal settlement. No AgentGuard tool or document should be
interpreted as providing legal, financial, or regulatory advice, or as a certified compliance
certificate. AgentGuard is not a law firm or auditor and does not guarantee adherence to laws or
standards. All use of AgentGuard software is at the user’s risk, and users must ensure
independently that their use of AI agents complies with all applicable laws and
regulations.* (CONTINUED IN NEXT PARAGRAPH)
Throughout this documentation, package metadata, CLI banners, and related materials, any word
drawn from compliance or legal contexts (such as “audit,” “evidence,” “settlement,” “credit,” “debt,”
“market,” “liquidity,” “maturity,” or similar) is used only in a functional, descriptive sense. For
instance, “audit log” simply means a sequence of recorded events; it does not imply an official
financial or regulatory audit. The phrase “satisfies” is used to indicate that one software condition
meets a programmed check (e.g. satisfying a budget cap), and is not intended to suggest that any
legal requirement has been fulfilled. Under no circumstances should AgentGuard’s terminology be
taken to indicate that our software is executing regulated financial or legal processes.*
No term in our code, documentation, or marketing is meant to designate or characterize any
AgentGuard feature as a service subject to banking, securities, derivatives, insurance, real estate, or
other regulated activities. For example, “trade,” “trading,” “liquidity,” “maturity,” and similar terms
(if ever used) describe algorithmic budget or token flows, not financial transactions. AgentGuard
does not act as a broker-dealer, clearinghouse, insurance issuer, or government agency. References
to “market” or “liquidation” are metaphorical descriptions of how the software handles tokens or
budgets. No AgentGuard action should be construed as offering financial services or operating a
regulated marketplace.*
Likewise, words like “offer,” “obligation,” “credit,” “debt,” “payment,” or “settle” in our text refer only
to hypothetical or illustrative actions of a user’s AI agent or simulated transaction flows. They do
not mean that AgentGuard is engaging in any money-handling, offering financial instruments, or
guaranteeing any settlement of obligations. If AgentGuard generates an invoice or cost-of-service
figure, it is purely illustrative of resource usage, not a binding financial bill. The term “maker/taker”
(if used in examples) is purely a naming convention and has no relation to exchange regulation.

The software’s “payment execution” tier is only a capability checkbox, not an actual payment
processor. AgentGuard does not transmit money or credit.*
Finally, any references to “certify,” “verify,” or “attest” should be read in context of cryptography and
computing. For example, when we say a receipt is “signed” or “verified,” we mean via public-key
cryptography. AgentGuard does not claim that receipts are admissible legal evidence by default.
Users remain responsible for any legal implications of presenting AgentGuard logs or receipts in
regulatory audits or court. This disclaimer is intended to ensure AgentGuard’s terms (in this
README, license, package descriptions, CLI banner, customer agreements, and /llms.txt) make clear
we provide a technical audit tool only. The functionality is delivered “as-is” with no implied
regulatory endorsement.

> **AgentGuard proves what your AI agent attempted, who authorized it, what it cost, and whether it succeeded.**
>
> Local-runtime spend caps, capability-gated model routing, and Ed25519-signed receipts for AI agents.

> Also available in: [Español (LATAM)](README.es-419.md) · [Português (BR)](README.pt-BR.md)

Every policy decision runs inside your process. Prompts, completions, provider API keys, signing keys, policies, and cost overrides never go to AgentGuard infrastructure. OpenRouter calls go directly from your runtime to `openrouter.ai` with your key.

## Quickstart in 90 seconds

```bash
npm install @agentguard-run/spend
agentguard auth openrouter
agentguard wizard
```

The wizard writes:

- `~/.agentguard/policy.yaml`
- `~/.agentguard/quickstart.ts`
- `~/.agentguard/quickstart.py`

It also prints the snippet to paste into your app:

```ts
const response = await guardedClient.chat.completions.create({
  model: 'openai/gpt-4o-mini',
  messages: [{ role: 'user', content: 'Run the governed task.' }],
});
```

Then run your agent. AgentGuard decides locally before any provider call starts, signs the receipt, and applies allow, downgrade, shadow, or block.

By default the wizard wires a file-backed `NdjsonDecisionLogStore` and a locally generated Ed25519 signing key, so every decision is signed and appended to `~/.agentguard/my-tenant/decisions.ndjson` with no extra setup.

### See it: run `agentguard serve`

After your agent runs (or after `agentguard demo`), open the local dashboard to SEE governed spend, the dollars saved by policy, per-agent and per-provider breakdowns, and a tamper-evidence badge with click-to-verify receipts:

```bash
agentguard serve
# → dashboard at http://localhost:8787
```

The dashboard reads only your local `~/.agentguard/*/decisions.ndjson`. No outbound network calls.

## Workflow-level caps

Use `agentguard.workflow()` when one agent run spans many outcomes and needs one shared budget envelope. The SDK signs each step as receipt schema v2, writes checkpoints, and validates the prior chain before resume.

```ts
import { agentguard } from '@agentguard-run/spend';

await agentguard.workflow({
  name: 'migrate_legacy_payments',
  budget_cap_usd: 500,
  duration_cap_hours: 72,
  checkpoint_every_outcomes: 50,
  resume_if_exists: true,
}, async (workflow) => {
  for (const record of records) {
    await workflow.outcome('migrate_payment', () => migratePayment(record));
  }
});
```

Share the public replay URL at `https://agentguard.run/verify/workflow/<workflow_id>`.

## Need help configuring? Run `agentguard advisor`

`agentguard advisor` uses your OpenRouter key, or any OpenAI-compatible endpoint you pass with `--base-url`, to run a local setup dialogue in your terminal. AgentGuard infrastructure never sees the prompts, completions, keys, policy details, or session log.

```bash
agentguard advisor
```

Advisor writes `~/.agentguard/policy.yaml`, a language-aware quickstart file, projected savings math, and a local JSONL session log under `~/.agentguard/advisor-sessions/`.

## Governance Posture

Advisor asks for one operating-style input and uses it to shape the generated policy.

- `velocity`: high-ship software and AI teams. Starts in `shadow`, uses permissive capability tiers, and downgrades aggressively to cheaper models.
- `standard`: most SaaS, e-commerce, real estate, agencies, local services, and startups. Starts in `enforce`, uses balanced capability tiers, and keeps 90 days of audit retention.
- `compliance`: law, healthcare, dental, accounting, SOX, fintech, and regulated workflows. Starts in `canary`, requires stricter capability tiers, blocks regulated overflow instead of downgrading, and keeps 7 years of audit retention.

Override the suggestion when you already know how the team operates:

```bash
agentguard advisor --posture velocity
agentguard advisor --posture compliance
```

`custom` posture is reserved for the Solo tier Outcome Builder.

## Why OpenRouter?

One OpenRouter key gives your team access to hundreds of models across many providers. Your CFO sees one invoice. AgentGuard enforces who uses what, which task tiers can reach which models, and what each call can spend. The OpenRouter key can live in `OPENROUTER_API_KEY` or `~/.agentguard/openrouter-key` with mode `600`.

Sync pricing when you want local cost math refreshed:

```bash
agentguard models --sync-pricing
agentguard models --task payment-approval
agentguard models --search gpt-4o --json
```

Pricing overrides are stored locally in `~/.agentguard/cost-overrides.json`.

## Verify any receipt

Share https://agentguard.run/verify with an auditor or reviewer. Paste a receipt and public key in the browser to verify the Ed25519 signature, entry hash, and chain link. The receipt never leaves the page.

CLI verification is still local:

```bash
agentguard demo
agentguard verify --trace latest
```

## Task templates

`agentguard wizard` ships templates for:

- `risk-review`: read-only review with a $0.50 per-call cap
- `payment-approval`: payment initiation review with a $5.00 per-call cap
- `chargeback-evidence`: evidence assembly with a $1.00 per-call cap
- `agent-support`: data-write support workflow with a $0.25 per-call cap
- `code-scan`: long-context read-only scan with a $0.10 per-call cap

Each template sets recommended OpenRouter model assignments, capability tier, fallback model, caps, and system instructions.

## Provider bindings

TypeScript includes native OpenAI, Anthropic, and Bedrock bindings. Each wraps a direct provider client in one line, with per-provider cost tables and response-shape handling. Enforcement semantics are identical across all three (and the OpenRouter path): the same policy blocks, downgrades, shadows, or allows a call before any bytes leave the process. Streaming usage is settled from provider usage events when available, with local token-estimator fallback when usage is missing. Settlement entries are signed into the same hash chain as enforcement decisions.

Wrap a direct **OpenAI** client:

```ts
import OpenAI from 'openai';
import { withSpendGuard } from '@agentguard-run/spend';

const openai = withSpendGuard(new OpenAI(), { policy, scope: { tenantId: 'acme' } });
await openai.chat.completions.create({ model: 'gpt-5', messages });
```

Wrap a direct **Anthropic** client:

```ts
import Anthropic from '@anthropic-ai/sdk';
import { withSpendGuardAnthropic } from '@agentguard-run/spend';

const anthropic = withSpendGuardAnthropic(new Anthropic(), { policy, scope: { tenantId: 'acme' } });
await anthropic.messages.create({ model: 'claude-sonnet-4-6', max_tokens: 1024, messages });
```

Wrap a direct **Bedrock** runtime client:

```ts
import { BedrockRuntimeClient } from '@aws-sdk/client-bedrock-runtime';
import { withSpendGuardBedrock } from '@agentguard-run/spend';

const bedrock = withSpendGuardBedrock(new BedrockRuntimeClient({ region: 'us-east-1' }), { policy, scope: { tenantId: 'acme' } });
await bedrock.send(new InvokeModelCommand({ modelId: 'anthropic.claude-sonnet-4-v1:0', body }));
```

Only `InvokeModel` / `InvokeModelWithResponseStream` commands are gated; other Bedrock commands pass through untouched.

Python includes OpenAI, Anthropic, Bedrock, LangChain, CrewAI, and LlamaIndex integration helpers.

## Framework integrations

Drop-in adapters translate each framework's own hook/middleware surface into the
same shared enforcement core (`guard.decide()` + the Ed25519-signed receipt
chain). They never proxy prompts, completions, or provider keys — only redacted
request shape reaches a receipt. One line each:

```ts
// Vercel AI SDK — wrapLanguageModel middleware (runs guard.decide before generate/stream)
import { wrapLanguageModel } from 'ai';
import { agentguardAiSdkMiddleware } from '@agentguard-run/spend/frameworks/vercel-ai';
const governed = wrapLanguageModel({ model, middleware: agentguardAiSdkMiddleware({ policy, scope }) });

// OpenAI SDK / OpenAI Agents SDK — wrap the client's chat.completions.create
import OpenAI from 'openai';
import { withSpendGuardOpenAI } from '@agentguard-run/spend/frameworks/openai';
const client = withSpendGuardOpenAI(new OpenAI(), { policy, scope });

// LangChain (JS) — BaseCallbackHandler (handleChatModelStart preflights, handleLLMEnd settles)
import { ChatOpenAI } from '@langchain/openai';
import { createLangChainHandler } from '@agentguard-run/spend/frameworks/langchain';
const llm = new ChatOpenAI({ callbacks: [createLangChainHandler({ policy, scope })] });

// OpenRouter — wrap an OpenAI-compatible client pointed at openrouter.ai
import { withSpendGuardOpenRouter } from '@agentguard-run/spend/frameworks/openrouter';
const or = withSpendGuardOpenRouter(new OpenAI({ baseURL: 'https://openrouter.ai/api/v1' }), { policy, scope });

// Claude Code — PreToolUse/PostToolUse hooks
import { createClaudeCodeHooks } from '@agentguard-run/spend/frameworks/claude-code';
const hooks = createClaudeCodeHooks({ policy, scope });

// Hermes — pre-tool-call / approval / post-tool-call plugin hooks
import { createHermesPlugin } from '@agentguard-run/spend/frameworks/hermes';
export default createHermesPlugin({ policy, scope });
```

## Spend-aware model router (removes vendor risk)

`createRouter(...)` composes the bindings, the enforcement engine, and the signed receipt chain into one call: it picks a candidate model across providers by policy, enforces the spend cap with the **same** enforcement path (block / downgrade / allow), executes it, and **fails over to the next provider** on a provider error/timeout or a cap breach on the chosen model. Every route is recorded in a signed, hash-chained routing receipt (candidates considered, winner, reason, resolved cost, fallbacks) that verifies with the existing `verifyChain`. No prompt/completion content or keys ever enter the receipt.

Selection policies: `cost` (cheapest capable first), `priority` (explicit failover order), or `capability` (filter by a capability tag, then cheapest-first).

```ts
import OpenAI from 'openai';
import Anthropic from '@anthropic-ai/sdk';
import { createRouter } from '@agentguard-run/spend';

const router = createRouter({
  candidates: [
    { provider: 'anthropic', model: 'claude-sonnet-4-6', client: new Anthropic() },
    { provider: 'openai',    model: 'gpt-5-mini',        client: new OpenAI() },
  ],
  policy: { mode: 'cost' },        // cheapest capable first; failover in order on error/cap
  spendPolicy: policy,             // your existing SpendPolicy — enforcement is REUSED, not forked
  signingKeys,                     // same Ed25519 keys as the rest of the SDK
  logStore,                        // routing receipts hash-chain onto the same signed log
});

const { response, chosen, reason, resolvedCents, fallbacks, routingReceipt } =
  await router.route({ messages, params: { max_tokens: 1024 } });
// chosen -> { provider, model }, reason -> 'cost' | 'priority' | 'capability' | 'failover' | 'downgrade'
```

Try it offline (mock providers, real signatures): `agentguard route-demo`.

## Sample receipts for outreach

Generate a realistic, signed sample receipt for a named flow plus a self-contained, self-verifying HTML page — "exactly what your counterparty would get":

```bash
agentguard sample --flow x402-payment   # or: refund | agent-purchase
```

This writes `receipt.json` and `verify.html`. The HTML re-derives the entry hash from canonical JSON (SHA-256) and verifies the Ed25519 signature in-browser via WebCrypto, with NO network calls; where a browser lacks WebCrypto Ed25519 it still checks the hash chain and links to agentguard.run/verify with the receipt prefilled. The signature is real; only the flow parameters are illustrative.

## External timestamp anchoring (opt-in)

Signed receipts prove internal order and integrity, but the signatures are produced in your own environment. Anchoring the chain head's SHA-256 to a public timestamp calendar (OpenTimestamps → Bitcoin) adds an EXTERNAL clock, so "this chain existed no later than <time>" is provable to a third party.

```bash
AGENTGUARD_ANCHOR=opentimestamps agentguard anchor --tenant my-tenant
agentguard verify --trace ~/.agentguard/my-tenant/decisions.ndjson
# → chain head submitted to external timestamp calendar at <time>
```

Anchoring is OFF by default; nothing changes for existing users. **Zero data plane is preserved: only the 32-byte SHA-256 of the chain head leaves the machine.** A hash reveals nothing about prompts, completions, keys, amounts, or model identity. The proof is stored alongside the ledger at `~/.agentguard/<tenant>/anchor.json` (+ `anchor.ots`).

Note: full Bitcoin-attestation verification requires the `opentimestamps` npm package, which is not yet bundled. Without it, submitted proofs are reported as `pending` (calendar commitment received; external attestation not yet confirmed) — never as a fabricated attested time.

## Completeness: sequence-gap detection

Each signed entry carries a monotonic per-tenant sequence number. `agentguard verify` and the `agentguard serve` integrity badge flag missing sequence numbers as `possible omitted actions: sequence gap at N` — evidence that an action may have been taken around the SDK and not logged, or that a logged entry was deleted. This is detection and reporting only; it never changes spend-cap enforcement.

## Multi-agent DAG trust attestation

Single receipts prove one agent's action. Real workflows are graphs: agents fan out, fan in, and hand capabilities to each other. A DAG Trust Attestation Token (TAT) is a signed receipt node that also records its parents, so a terminal agent can verify the whole causal chain before it acts. Each node carries version, timestamp, a truncated msg_hash of the screened payload, a trust score, a blocked flag, the screener id, the inferred topology (`linear` | `fan_in` | `fan_out` | `diamond`), the SHA-256 hashes of its parents, and an Ed25519 signature over the canonical serialization. It reuses the exact same signing and canonical-JSON hashing as the decision log, and it is metadata-only: no prompt, completion, key, or PII ever enters a node.

`verifyReceiptDag` checks every signature, runs Kahn's algorithm to reject any cycle (the circular-dependency-injection defense), confirms diamond branches correlate to a shared uncorrupted ancestor, and returns the minimum-of-chain trust score with the DAG depth. `gateCapability` then turns that into an authorization: higher tiers (`READ_ONLY` < `TRANSACT` < `ADMIN` < `ORCHESTRATE`) require both higher min-of-chain trust and greater depth, so an agent cannot escalate on a shallow or low-trust chain.

```ts
import { signDagNode, verifyReceiptDag, gateCapability } from '@agentguard-run/spend';
// or the subpath: '@agentguard-run/spend/receipts/dag'

// Canonical diamond: A fans out to B and C, both fan in to terminal D.
const a = await signDagNode({ sequence: 0, privateKey, publicKey, capability: 'READ_ONLY', trustScore: 0.96,
  decision: { action: 'allow', agent: 'A', step: 'ingest_invoice' } });
const b = await signDagNode({ sequence: 1, privateKey, publicKey, parents: [a], trustScore: 0.93,
  decision: { action: 'allow', agent: 'B', step: 'analytics_score', ancestor: a.msgHash } });
const c = await signDagNode({ sequence: 2, privateKey, publicKey, parents: [a], trustScore: 0.88,
  decision: { action: 'allow', agent: 'C', step: 'validate_payment', ancestor: a.msgHash } });
const d = await signDagNode({ sequence: 3, privateKey, publicKey, parents: [b, c], topology: 'diamond', trustScore: 0.91,
  decision: { action: 'allow', agent: 'D', step: 'settle_invoice', capabilityClaim: 'payment_initiate' } });

const result = await verifyReceiptDag([a, b, c, d], publicKey);
// { valid: true, compositeTrust: 0.88, depth: 3, topologySummary: { diamond: 1, ... } }

gateCapability('TRANSACT', result).granted;     // true  — trust + depth clear the bar
gateCapability('ORCHESTRATE', result).granted;  // false — TRUST_BELOW_THRESHOLD
```

See it end-to-end (builds the diamond, verifies it, gates capabilities, and rejects an injected cycle):

```bash
agentguard dag-demo
```

For large agent swarms, `merkleRoot` / `compressReceiptDag` / `merkleInclusionProof` / `verifyInclusion` compress a DAG to a single root with per-node inclusion proofs. As with everything here, this is detection, verification, and reporting only: it never touches spend-cap enforcement.

## No proxy

AgentGuard Spend is a library, not a gateway. It does not proxy traffic, store prompts, hold provider keys, or host policy state. The signed log lives in your storage.

## Telemetry

Telemetry is opt-in. Set `AGENTGUARD_TELEMETRY=1` or run `agentguard telemetry enable`. The beacon sends only SDK version, runtime, OS family, anonymous install ID, CI flag, TTY flag, and event name. No prompts, completions, provider keys, signing keys, policy details, or cost overrides are sent.

## License and usage thresholds

The SDK is free for evaluation, prototyping, non-commercial development, and production deployments processing up to 10,000 enforcement calls per calendar month. Commercial use above that threshold requires a paid license from Dunecrest Ventures Inc. Full terms are in `LICENSE`.

## Patent notice

Protected by U.S. patent-pending technology (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626; 64/071,781; 64/071,789). 35 U.S.C. § 287 constructive notice. Additional patents pending.
