NTU InnovateX 2026 finalist · Track 1: Payments and Financial Infrastructure

Cerberus — SAFR pre-execution governance runtime for AI-agent payments

An AI agent can propose a payment; Cerberus decides ALLOW / DENY / ESCALATE before the x402 request exists, and the payment key lives in a separate process.

Judge evidence for the hardened-path run of 22 August 2026 on Base Sepolia (eip155:84532). Static and read-only. Every figure and hash on this page is copied from the repository's committed evidence package and submission documents; the links to base-sepolia.blockscout.com are the independent check.

1. What this page is / is not

2. The hardened-path run — 22 August 2026, Base Sepolia

Captured on the finalist build with the payment signer, the execution-authorization signer and the audit-anchor signer held by three separate processes with three separate least-privilege database logins. The agent process holds none of them. The seeded mandate allows at most 1 USDC per transaction and 3 USDC per rolling 24 hours.

DENY5 USDC → merchant_abcCap breach. x402 never constructed; no settlement, no failed transaction either.
ESCALATE0.75 USDC → merchant_newHeld for a human, approved by reviewer:local, then SETTLED on chain.
ALLOW0.5 USDC → merchant_xyzWithin mandate; SETTLED on chain.
AMBIGUOUS OUTCOME0.5 USDC, real incidentNo blind retry; non-payment proven on chain; terminal FAILED, safe to retry.

The four scenarios

Source: docs/submission/EVIDENCE.md and artifacts/judge-evidence/08_final/evidence-summary.json. Explorer: base-sepolia.blockscout.com.
ScenarioAmountAudit idGovernance resultFinancial outcomeSettlement txAnchor tx
DENY
scenario cap_breach, counterparty merchant_abc
5 USDC against a 1 USDC per-transaction cap audit_84670a33 DENY · per_transaction_cap_exceeded · rule spend_caps.per_transaction_max · x402 never constructed None. There is no failed blockchain transaction either, because payment authority never existed. — (none) 0xfaabd09ea1829938d7d447b9aa1152743cd2eae62738873b22366eb631e9a7aa
block 45793550
ESCALATE
scenario new_counterparty, counterparty merchant_new
0.75 USDC audit_30aa1a70 ESCALATE · counterparty_not_on_allowlist · rule counterparty_policy · held for a human, approved by reviewer:local · authorization auth_f70a3e32-35f9-4427-b5e6-a8b1e72f5234 (CONSUMED) SETTLED — receipt status = 0x1, block 45795096, USDC Transfer of 750000 atomic (0.75 USDC) executor → merchant; settled 2026-08-22T00:28:02Z 0x55ba3c22d58a83a1b6093f2e289c544239d4839cd97b008b791d5a6052225469 0x3d4659c3890b2061eaf04fc4351b83bce5d496c999259e6a8a55a6290be78877
block 45795114
ALLOW
scenario clean, counterparty merchant_xyz, invoice_884
0.5 USDC audit_ff45a977 ALLOW · within_mandate · authorization auth_8b204222-ac27-40b9-a5dc-d5a3dc8cb875 (CONSUMED) SETTLED — receipt status = 0x1, block 45796303, USDC Transfer of 500000 atomic (0.5 USDC) executor → merchant; settled 2026-08-22T01:08:17Z 0xfe4d02288ea8882d8b75e520cf627e97d57b04e4f3a3cc81e40b780a36c995fa 0xdb4eed29be7f44d0c7af7375721047219cf6c74c0f87a08b373938a6b9596368
block 45796318
AMBIGUOUS OUTCOME
a real incident during the run set, not staged
0.5 USDC audit_0aaac796 ALLOW · within_mandate · x402 reached · authorization auth_4920d58f-1337-4d44-ba7a-70b3f0fdff9a (CONSUMED) · execution became ambiguous after signing No transfer. Capacity stayed held; nothing was blindly retried; the keyless reconciler returned deferred 17 times; the EIP-3009 authorization expired unused. Terminal state FAILED, settlement_tx NULL, “EIP-3009 authorization expired unused; safe to retry”. — (none) 0x156f3ed3e17d65a59ca37593befa8eb47b02dae8b44eafbe5b008318db8d62e3
block 45795806

Identities

npm run audit:verify5/5 anchored records proven on chain. Each record's digest was reproduced from the stored record and matched against its own anchor transaction — the four scenario records above plus one further record from the same run set, audit_03117a66 (anchor 0x98b34f10e47aac9e2e46b18ee4e049500866cd83af0743e43a8f6a3189ede2da, block 45793552). Transcript: artifacts/judge-evidence/08_final/final-verification.log.

Why the ambiguous outcome is the strongest evidence, not the weakest

A merchant's HTTP response is not financial truth. When the response to a signed execution never resolved, Cerberus did not treat “the merchant said it failed” as proof that money did not move — it kept the mandate capacity held and refused to retry. The keyless reconciler (it holds no private key) deferred 17 times rather than guess.

The proof of non-payment is read from the chain, not from the merchant. Calling USDC.authorizationState(payer, nonce) for the reservation's own EIP-3009 authorization returns false, and that authorization's validBefore has elapsed. The money did not move, and cannot move under that authorization. That is positive non-payment evidence.

Reservation
res_bcaf9720-4b9a-4710-946c-cb9d00d04a36
Payer
0x35820e5cC60F961515EF987C94D4328a82Df38Fc
EIP-3009 nonce
0x8dbcbebfc0c876c91a6b64f0e716f5b52f09257901583d7692b38d06dc9739dc
validBefore
1787359784 = 2026-08-22T00:49:44Z (elapsed)
authorizationState
0x00…00false; never consumed on chain
Terminal state
FAILED, settlement_tx NULL, reconciliation attempts 17, “EIP-3009 authorization expired unused; safe to retry”

Reading the raw logs and the Phase 5 screenshot. The demo CLI prints a generic note that a failed settlement and unanchored records “are expected until the payer wallet is funded”. That wording is stale informational text carried by the runner and does not describe these runs: the payer was funded, both permitted scenarios settled, and all five records are anchored. The authoritative facts are the on-chain receipts and the payment_reservation rows, both re-read in 08_final/final-verification.log. Historical logs are kept byte-for-byte rather than edited after the fact. 05_escalate/escalate-raw.log is the first ESCALATE attempt, which timed out waiting for a human reviewer; it is retained on purpose — the human gate is a real cross-process hold, not an in-memory pause.

3. Recordings & screenshots

Seven screen recordings (WebM) and five screenshots, copied unchanged from artifacts/judge-evidence/11_videos/ and 10_screenshots/. Videos do not preload; tap to play. If your browser cannot play WebM inline, use the “open file” link under each recording.

Screen recordings — phases 0 to 7

Phases 0–1 — Environment and database (54 s). Environment capture, Postgres runtime, migrations, the least-privilege database logins and npm run db:verify. open file
Phase 2 — Credential boundaries (12 s). The payment, authorization and anchor signers are absent from the agent process. open file
Phase 3 — Runtime health (19 s). Merchant, control plane, isolated executor, reviewer dashboard, reconciler and anchor worker. open file
Phase 4 — DENY (23 s). 5 USDC against the 1 USDC per-transaction cap; the x402 client is never constructed; audit_84670a33. open file
Phase 5 — ESCALATE with human approval (31 s). 0.75 USDC to merchant_new is held for a human, approved by reviewer:local, then settled; audit_30aa1a70. open file
Phase 6 — ALLOW, settled (26 s). 0.5 USDC within mandate, settled on Base Sepolia; audit_ff45a977. open file
Phase 7 — Ambiguous outcome and reconciliation (16 s). The real incident: the keyless reconciler defers, the EIP-3009 authorization expires unused; audit_0aaac796. open file

Screenshots

Terminal: CERBERUS — POSTGRES RUNTIME. Container safr-postgres, image postgres:16-alpine, status Up 37 hours (healthy), port 5544.
Phase 1 — Postgres runtime. safr-postgres (postgres:16-alpine) healthy on port 5544.
Terminal: npm run db:migrate reports no pending migrations.
Phase 1 — Migrations. npm run db:migrate: no pending migrations.
Terminal: npm run db:roles lists the Cerberus runtime database logins for agent, control-plane, executor, reconciler and anchor, provisioned without exposing passwords.
Phase 1 — Least-privilege database logins. npm run db:roles: separate logins for agent, control-plane, executor, reconciler and anchor, provisioned without exposing passwords.
Terminal: npm run db:verify prints thirteen OK lines and All checks passed.
Phase 1 — Schema and engine verification. npm run db:verify: all 13 checks pass; the stored mandate drives the three demo outcomes through the real engine.
Terminal: npm run demo -- new_counterparty. Proposes 0.75 USDC to merchant_new, disposition ESCALATE, reason counterparty_not_on_allowlist, rule counterparty_policy, human review approved by reviewer:local, x402 reached yes, audit_id audit_30aa1a70.
Phase 5 — ESCALATE approved in the terminal. 0.75 USDC to merchant_newESCALATE, counterparty_not_on_allowlist, approved by reviewer:local, x402 reached, audit_30aa1a70. The closing note about an unfunded payer wallet is stale runner text (see above); this run settled and its anchor landed — see the table in section 2.

4. How it works

Cerberus architecture slide: an AI agent orchestrator proposes an action; the pre-execution gate (deterministic Disposition Engine over the controls repository mandate) returns ALLOW, ESCALATE or DENY before any x402 request object exists; ALLOW proceeds to x402 settlement in USDC on Base Sepolia; every disposition writes the audit log, read by the compliance dashboard.
Concept diagram from the repository README (docs/assets/safr-architecture-slide.png, drawn at Stage 1). The pre-execution gate, the three dispositions and the audit log are unchanged; the finalist build adds the signer isolation, isolated executor, reconciler and anchor worker described below.
  1. The agent proposes. The AI agent's orchestrator produces a structured proposed payment. The agent process holds no payment key, no authorization signer and no anchor signer (Phase 2 of the run checks this).
  2. A deterministic disposition engine evaluates it against a versioned mandate — spend caps, counterparty allowlist, time windows, velocity — as a pure, rule-based library call inside the orchestrator, before any x402 request object exists. No LLM is in the decision path.
  3. The result is ALLOW, DENY or ESCALATE. DENY means the x402 client is never constructed. ESCALATE holds the action until a human reviewer approves or denies it from a separate process; the agent cannot approve itself.
  4. An isolated executor acts only on a one-use, 60-second signed authorization. The executor is the only process that holds the payment key. It accepts a short-lived, single-use Execution Authorization bound to the exact proposal, mandate version, chain, token, atomic amount, payee and resource, and consumes it one-shot.
  5. Settlement is proven by reading the chain; audit records are hash-anchored by a separate trusted worker. A payment is marked SETTLED only on exact successful on-chain inclusion of the USDC transfer — never on the merchant's HTTP response — and a keyless reconciler handles ambiguous outcomes. Terminal audit records are canonically hashed and anchored to Base Sepolia by a separate anchor worker, which makes them tamper-evident.

5. Verified gates

Figures from docs/submission/FINAL_FREEZE.md and the README “Current finalist build” table. CI reproduced the gate independently on a clean Linux runner with no wallet secrets.

GateResult
npm test384/384 tests, 78 suites, 0 failed, 0 skipped at the freeze pass · 411/411 across 83 suites after the 23 Aug presentation layer (FINAL_FREEZE.md addendum)
npm run adversarial12/12 attack classes, 80 assertions
npm run redteam12/12 attack classes, 70 assertions
npm run mutation12/12 security guards proven detectable
npm run sandbox — seeds 42 and 13371,000 actions / 50 agents / concurrency 25 per seed — 0 budget, duplicate-effect or replay violations
npm run db:verify13 checks, all pass
npm run audit:verify5/5 anchored records proven on chain
npm run evidence:verifyPASS on a clean clone (CI step “Verify portable release evidence”)
npm run typecheck · dashboard build · contracts:compile · pnpm auditclean · clean · clean · no known vulnerabilities
Continuous integrationGitHub Actions run 32301340842 on head 6d40e85bef71d2dfa51edff34a99c7a6b8eebad1 — all 21 steps green

6. Integrity

The evidence package is covered by a SHA-256 manifest. Both integrity files are served here as exact copies of the repository files:

Verify the package has not changed since capture, from a clone of the repository:

cd artifacts/judge-evidence && sha256sum -c 08_final/SHA256SUMS.txt

The recordings and screenshots served by this site are the files named in that manifest; their listed digests are reproduced here so a file downloaded from this page can be checked against the repository.

File on this siteManifest pathSHA-256 (from SHA256SUMS.txt)
media/phase-00-01-environment-database.webm11_videos/phase-00-01-environment-database.webm16c518c4fde6af1aeca51dc0cbe7e2fc7866c1089dd37807c3680e0a1aa987d8
media/phase-02-credential-boundaries.webm11_videos/phase-02-credential-boundaries.webm18854c5525c804f2de6ef2f0c97f4c9085ce50aca4a49accae6cb2c7a38cac12
media/phase-03-runtime-health.webm11_videos/phase-03-runtime-health.webm0b3d1a381cb201b7f09288eeab7ced318e984c0d4cd3126bb4e5332807f286ce
media/phase-04-deny.webm11_videos/phase-04-deny.webm0b32f2b074c8cd7a6daa3d8b38c87bdbf6df50a82ec1938315f38d7ce2896318
media/phase-05-escalate-human-approval.webm11_videos/phase-05-escalate-human-approval.webmaebb49bf8e68f0845dd39c23c8b8a950c8fbc7487c6db0643f18136c1e044081
media/phase-06-allow-settled.webm11_videos/phase-06-allow-settled.webmfa4b6978a9310ac45016a622959c1a1cb735d76f11da9080e1c2c66d8adedd2c
media/phase-07-outcome-unknown-reconciliation.webm11_videos/phase-07-outcome-unknown-reconciliation.webm6400b8d40a804724891d6ef0cf32d74bbcefce67dc5c62f41dd7df9b984827aa
screenshots/phase-00-01-01-postgres-runtime.png10_screenshots/phase-00-01/01-postgres-runtime.png90363befdba21661da6fda18a681d3c615c4a763639e30761824c69c6f0b9cdf
screenshots/phase-00-01-02-migrations.png10_screenshots/phase-00-01/02-migrations.png4bce6a01e270b44166571d331554d77562d324aea6dd162cec94779b886879d9
screenshots/phase-00-01-03-database-roles.png10_screenshots/phase-00-01/03-database-roles.pngc1c31e92191f1d55d0ad1d20ed3fa18be7f1d2c7376266af3cad389ed37348d1
screenshots/phase-00-01-04-db-verify.png10_screenshots/phase-00-01/04-db-verify.png75e9f26b1159f4c9a28bd784fd61597e47aaabd57ce178cd29af0089f810db22
screenshots/phase-05-escalate-terminal-approved.png10_screenshots/phase-05/escalate-terminal-approved.png48613f99a070f4e50e449f7607938af0f04429f4f768545db689d01c57cf7dac
evidence/evidence-summary.json08_final/evidence-summary.json183c0a7deebc02c0f985d2160cc5793455b8aa1b4230c9bf8b82a02d0707e589

The architecture slide in section 4 is the README illustration, not part of the evidence package, and is therefore not in the manifest. This HTML page is a presentation layer and is not in the manifest either; the repository is the source of truth.

7. Limitations, stated plainly