Stars, commits and capability columns all read 12 September 2026 · re-measurable

How Cedulon compares

Including the places where the other projects are ahead of us. Every cell says whether it comes from the project's own documents or from a function we found in its code, because those are two different kinds of evidence and a comparison written by a vendor is worth exactly as much as its verifiability.

Read this first. Cedulon is the smallest project on this page: 0 GitHub stars against x402's 6,606 and AP2's 3,176. Nothing here moves real money; the repository runs on mock fixtures and one read-only testnet window. If you need a payment rail, pick a rail. Cedulon is not one; it sits above x402 and AP2 as an audit layer. Keep reading only if what you need is a signed receipt per spend, a refusal when the policy engine is missing, and a reconciliation that finds the spend that left no receipt.

How to read a cell. Docs is what the project's documentation says. Code names the function we found producing that behaviour at the pinned commit, or says not found when we did not find one in the files we read. Not found is not proof of absence. Nothing was executed; this is a static reading of open code and public documents. Cedulon's own row is held to the same notation.

The table

Star counts, licenses and last-commit dates were read from the GitHub API on 12 September 2026 with the commands at the bottom of this page. The last-commit date is the committer date of the newest commit on the default branch. Capability columns were read the same day, from each project's documentation and from the source files linked under the table. If we got something wrong about your project, write to us and we will correct the page and note the correction.

ProjectStarsLast commitLicense Signed receipt per spend Refuses when the policy engine is missing or faulty Reconciles the rail's own extract Human approval step Third party can verify the receipt Records stay on your machine
Cedulon02026-09-12Apache-2.0 YesCode: signReceiptCose() writes a COSE_Sign1 receipt, generateReceiptKeys() makes Ed25519 keys (packages/receipts/src/index.ts). YesCode: failClosedEvaluate() returns a refusal with engine-unavailable when there is no engine and engine-fault when it throws (packages/core/src/fail-closed.ts). YesCode: packages/audit/src/index.ts reports settlement-without-receipt; the cedulon_audit tool accepts a signed rail extract as the settlement side. NoDecisions are allow or deny (packages/core/src/policy.ts); there is no hold state and no approval queue. The payee countersignature is a key, not a person. Yescedulon_verify_receipt tool; docs/RUN_AS_VERIFIER.md reruns the whole suite on a clean machine. Without an issuer key you hold out of band the check is self-referential, and the tool description says so. YesA stdio process over its own ledger; sections 1 to 6 of the verifier document touch no network. Not measured with packet capture.
Stripe Agent Toolkit1,8012026-09-11MIT Not statedCode: not found in the toolkit. Different thingDocs: restricted API key permissions. Code: ToolkitCore.initialize() connects to Stripe's remote MCP server; there is no local spend engine to fail closed. Not statedDocs: payment data is readable through the API; automatic matching is not stated. Code: not found. Recommended, not enforcedDocs: confirmation is recommended in the MCP client. Code: no mandatory approval step in the toolkit. Not statedCode: no receipt verifier found. NoRemote MCP over HTTP: StripeMcpClient.createTransportAndClient() (mcp-client.ts).
Coinbase AgentKit1,3092026-09-03Apache-2.0 LICENSE.md says so; the GitHub API reports NOASSERTION PartialDocs: x402 payment proof. Code: X402ActionProvider; no separate signed outcome receipt found. PartialDocs: URL allowlist and a default 1 USDC per-request limit. Code: isServiceRegistered() refuses on an empty list, validatePaymentLimit() checks the amount (x402/utils.ts). Behaviour when the check itself faults is not stated. Not statedCode: not found. OptionalDocs: two-step flow or direct pay. Code: X402ActionProvider offers both; neither is mandatory. PartialDocs: x402 payment proof. Code: no independent receipt verifier found. NoHTTP and wallet-provider calls.
x402 foundation repository; the CDP facilitator is Coinbase-hosted6,6062026-09-11Apache-2.0 OptionalDocs: Offer/Receipt is an optional extension. Code: createReceiptJWS() and createReceiptEIP712() (offer-receipt/signing.ts). Whether every CDP settlement emits one is not stated. Not statedDocs: payment signature and settlement are verified. Code: no spend-policy engine in this extension. Not statedDocs: settlement returns a transaction id; a full extract sweep is not stated. Code: not found. NoMachine-to-machine by design. PartialDocs: portable JWS / EIP-712 proof. Code: signing is there; verifyReceiptMatchesOffer() (client.ts) compares fields, and its own comment says it does not verify the signature. NoThe facilitator can be Coinbase-hosted and settlement is on chain; the receipt travels in the HTTP response, no mandatory local archive found.
Google AP23,1762026-04-29Apache-2.0 SpecifiedDocs: the v0.2 specification says a signed Payment Receipt MUST follow accept or decline. Code: ReceiptClient.create_payment_receipt() and create_jwt() (receipt_wrapper.py). Emission on every real payment path not verified. Not statedDocs: mandate verification must be deterministic. Code: PaymentMandateChain.verify(); a fault-to-refusal guarantee across execution paths is not stated. Not statedDocs: the receipt references the mandate; rail-extract reconciliation is not stated. Code: not found. YesDocs: human-present and pre-authorised autonomous flows. Code: the SDK verifies the mandate chain; the human interface is the integrator's. YesCode: ReceiptClient.verify_receipt() calls verify_jwt(); needs the issuer's public key and a reference-check callback. Up to youDocs: storage is up to the implementation. Code: no mandatory local archive.
AWS AgentCore Paymentsn/an/aManaged service Not statedDocs: the transaction proof is signed; a separate signed audit receipt is not stated. Code: not public. PartialDocs: over-limit and expired sessions are refused; the engine-missing case is not stated. Code: not public. Not statedDocs: session ledger and transaction status; an external extract sweep is not stated. Up frontDocs: the user grants the payment tool explicit authority; no per-payment confirmation is claimed. Not stated NoAWS-managed ledger and observability.
Vaara122026-09-12AGPL-3.0 commercial option PartialDocs: action evidence, signed at export. Code: extract_receipt() (audit/receipts.py) extracts a hash-bound record; not verified as an automatic signed receipt per payment. PartialDocs: deny or escalate stops execution. Code: govern.wrapper() calls intercept(); a scorer exception records a refusal and raises. shadow=True does not block. Own trail onlyDocs: gap detection inside its own trail. Code: settlement/release.py evaluates evidence only; no link to a rail extract found. YesCode: request_approval() and resolve_escalation() (approvals.py); the review queue is optional. YesCode: verify_signed() in audit/verify.py, CLI vaara trail verify; Ed25519 public key and chain check. YesCode: InterceptionPipeline.__init__() defaults to ~/.vaara/trail/audit.db (pipeline.py).

Files and documents read, 12 September 2026

Where they are ahead of us

Five things, stated before the parts that favour us.

Where we are different

Different, not better. Each of these is a design choice with a cost attached.

Not in the table, and why

Verify this page yourself

Do not take the numbers on trust. They take about a minute to gather.

# Stars, license and newest commit on the default branch
for r in dogrucanemek-alt/cedulon stripe/ai coinbase/agentkit x402-foundation/x402 \
         google-agentic-commerce/AP2 vaaraio/vaara; do
  gh api "repos/$r" --jq '"\(.full_name)  stars \(.stargazers_count)  \(.license.spdx_id)"'
  gh api "repos/$r/commits?per_page=1" --jq '.[0].commit.committer.date'
done

# Read the same file we read, at the same commit
gh api -H "Accept: application/vnd.github.raw+json" \
  "repos/x402-foundation/x402/contents/typescript/packages/extensions/src/offer-receipt/client.ts?ref=04c750e" \
  | grep -n "does NOT verify"

# Run Cedulon as a verifier: under ten minutes, no network in sections 1 to 6
git clone https://github.com/dogrucanemek-alt/cedulon
cd cedulon && npm install && npm run test:all

The verifier document walks through the rest: a tampered receipt reads as tampered, and one settlement with no receipt makes the audit print FAIL.