Cedulon

Missing evidence is itself evidence.

Agents can already pay on open rails such as x402 and AP2. Cedulon sits above those rails as an audit layer: a signed spend receipt, a chained epoch checkpoint, and a reconciliation of the rail extract. If a spend left no receipt, the gap is the finding. Bookkeeping moved from single-entry records to Pacioli's double-entry; Cedulon is the later step where an external rail extract is machine-checkable.

How it works

Cedulon flow from manifest to reconciliation audit Trade Manifest signed offer before payment Policy Decision Point default deny, fail-closed Payment rail x402 or other settlement Signed Spend Receipt COSE_Sign1, Ed25519 Epoch Checkpoint totals and previous hash Reconciliation Audit rail extract versus receipts

The gap we close

Anyone can verify a receipt

A signed spend record checks as valid or tampered. That is the easy half.

Nobody sees a missing receipt

A spend that never issued a receipt leaves no object to verify. The books still look clean.

Cedulon turns the gap into evidence

The companion audit compares the rail extract to the receipt chain. A bypass in this repository prints audit: 1 settlement without receipt → FAIL

The same audit for decisions

A spend is one kind of effect. The companion profile applies the same reconciliation to a decision log: a Decision Record is a signed allow, deny or defer over a request hash and a policy hash, and an Effect Extract is what the channel actually carried. The audit pairs the two by reference and by content hash, and publishes the counts that have to close.

A refusal followed by the effect it refused

Spend audits have no word for it: an aborted receipt and a settlement under its reference read as "settlement without receipt". Here it is a finding with its own name. effect-against-refusal → FAIL

The class of the effect is under the signature

An allow names what it allowed and what kind of thing it is. A row that carries the allowed hash under another class is effect-class-mismatch, not a match.

One fixture, two independent readers

A frozen leaked-refusal fixture was read by this audit and by a second reader written elsewhere in its own vocabulary; both refused it. The run, its digests and its limits are in the external review log.

Gated spend (repository API)

import { PolicyEngine } from "@cedulon/core";
import { generateReceiptKeys } from "@cedulon/receipts";
import { gatedSettle } from "@cedulon/x402-adapter";

const engine = new PolicyEngine({
  maxAmount: 10n, maxCumulative: 30n, maxPayments: 3, windowMs: 3600000,
});
const keys = generateReceiptKeys();
const result = gatedSettle(engine, {
  req: { amount: 1n, currency: "USD", payee: "q", nonce: "n1", nowMs, tool: "spend" },
  payer: "p", paymentHeader: "mock",
}, { receiptPrivatePem: keys.privateKeyPem, receiptPublicPem: keys.publicKeyPem }, nowMs);

Use it as an MCP server

The same gated spend and extract audit are also five MCP tools on stdio, published on npm as @cedulon/mcp-server. Point Claude Desktop, Claude Code, or Cursor at it; there is nothing to clone or build. Step-by-step: Cedulon in 5 minutes.

{
  "mcpServers": {
    "cedulon": {
      "command": "npx",
      "args": ["-y", "@cedulon/mcp-server"]
    }
  }
}

Measured in this repository

Records

Questions

What does Cedulon actually do?

Cedulon sits above payment rails such as x402 and AP2 as an audit layer. It writes a signed spend receipt, a chained epoch checkpoint, and a reconciliation of the rail extract. If a spend left no receipt, the gap is the finding. The design is specified in IETF Internet-Drafts and published as open source under Apache-2.0.

Can anyone verify a spend receipt?

A signed spend record checks as valid or tampered. That is the easy half. A spend that never issued a receipt leaves no object to verify, and the books can still look clean. The companion audit compares the rail extract to the receipt chain so a missing receipt becomes a finding.

Does Cedulon take custody of funds?

Cedulon does not take custody and does not operate escrow. An optional third-party escrow role may appear in the protocol as an interface. This repository uses mock keys and a mock rail. The published packages do not touch money: no real wallets and no network rails.

How do I attach Cedulon to Claude or Cursor?

The gated spend and extract audit are five MCP tools on stdio, published on npm as @cedulon/mcp-server. Point Claude Desktop, Claude Code, or Cursor at that package. There is nothing to clone or build. A five-minute path is in the repository Quickstart document.

What does Cedulon not prove?

Cedulon does not take custody and does not operate escrow. It does not judge delivery quality beyond a hash compare against the manifest acceptance criteria. Payment rails may succeed even if Cedulon is skipped. Production key storage is out of scope in this repository. Completeness checking does not replace prevention.

Auditing what an agent spent — signed receipts, whether an x402/AP2 reconciliation standard exists, and proving which rule allowed an action, with the five adjacent IETF drafts compared →

How Cedulon compares with Stripe Agent Toolkit, Coinbase AgentKit, x402, Google AP2, AWS AgentCore Payments and Vaara — docs and code kept apart in every cell, dated, including where they are ahead of us →