ProofSpend is a Next.js MVP for receipt-backed autonomous diligence. A user submits a purchase or vendor question, the app runs a small research pipeline, enforces spend policy before every paid search, and returns a memo whose claims map back to evidence records, source URLs, and payment receipts.
- runs
Market,Evidence,Counter, and optionalSkepticresearch steps - uses
Tavily x402as the paid search layer - supports
mockmode by default for local work and CI - supports pluggable LLM providers for summarization and analyst synthesis
- shows a live timeline, spend tracker, memo, and evidence table in one dashboard
- exports completed runs as proof packets in JSON or Markdown
- stores the last 10 completed runs locally for quick reopen
- lets you click memo claims to trace them back to evidence rows and receipts
- creates shareable snapshot links for completed runs
- compares two vendor diligence runs side by side
- includes an in-app API guide for agent and webhook integrations
- surfaces a deterministic
proofScoreplus explainable confidence breakdowns and confidence gaps
Default mode:
MOCK_X402=true- no wallet required
- no API key required
- deterministic local fallback is available even if no LLM provider is configured
- receipts are synthetic and clearly marked as simulated
MOCK_X402=false- uses real Tavily x402 paid calls
- requires local wallet/payment setup
- requires a valid
AGENT_WALLET_KEY - fails closed if a paid call cannot return a usable receipt reference
This app is designed for local/private demo use, not public multi-user deployment.
Set LLM_PROVIDER to one of:
nvidiaopenaihuggingfacedeterministic
If the selected provider is not configured, ProofSpend falls back to deterministic subject extraction, summarization, and memo synthesis.
- Next.js 15
- React 19
- TypeScript
- Vitest
- OpenAI-compatible SDK integration for NVIDIA / OpenAI / Hugging Face endpoints
npm installWindows PowerShell:
Copy-Item .env.example .envmacOS / Linux:
cp .env.example .envFor the safest first run, keep:
MOCK_X402=true
LLM_PROVIDER=deterministicnpm run setup:checknpm run devThen open http://localhost:3000.
See .env.example for the full list.
Most important values:
MOCK_X402AGENT_WALLET_KEYLLM_PROVIDERPOLICY_PROFILEDEFAULT_PAID_CALL_COST_USDPROOFSPEND_API_KEYPROOFSPEND_SIGNING_SECRETWEBHOOK_SECRETWEBHOOK_MAX_ATTEMPTSNVIDIA_API_KEYOPENAI_API_KEYHF_TOKEN
| Command | Purpose |
|---|---|
npm run dev |
Start the local Next.js dev server |
npm run build |
Build the production app |
npm run start |
Run the production build |
npm run test |
Run unit tests |
npm run setup:check |
Validate local prerequisites and env basics |
npm run smoke:llm |
Check the active LLM provider setup |
npm run smoke:search |
Exercise one live paid search path |
npm run probe:awal |
Inspect raw live awal payment headers for receipt debugging |
npm run test:e2e |
Run Playwright smoke tests after installing @playwright/test locally |
- blocks sensitive queries that contain likely PII before payment
- batch-checks the planned primary run before the first paid call
- blocks over-budget paid calls before payment
- blocks duplicate normalized queries
- blocks duplicate receipts
- derives paid-call caps from policy and budget
- redacts sensitive fragments from user-visible query previews
Request body:
{
"question": "Should I spend $500 per month on Apollo.io for B2B lead generation for my early-stage SaaS startup?",
"budgetCapUsd": 0.25,
"policyProfile": "standard",
"callbackUrl": "https://example.com/webhook",
"parentRunId": "run_abc123",
"gapId": "gap-counter-deep-dive",
"suggestedQuery": "Apollo.io lawsuit compliance legal response customer complaints deliverability"
}Notes:
- response is
text/event-stream policyProfilesupportsstandardandstrictcallbackUrlis optional and receives the finalDiligenceRunJSON as a best-effort POST after completionparentRunId,gapId, andsuggestedQueryare optional and enable local-first continuation runs from a confidence gap- add
?stream=falseor body"stream": falseto receive the finalDiligenceRunJSON directly instead of SSE - when
WEBHOOK_SECRETis set, callback deliveries includeX-ProofSpend-TimestampandX-ProofSpend-Signature - when
PROOFSPEND_API_KEYis set, callers must sendAuthorization: Bearer <key> - the final run now includes:
confidence: deterministic overall confidence in the0..1rangeproofScore: user-facing trust score in the0..100rangeconfidenceBreakdown: per-agent signals, named factors, and policy adjustmentsconfidenceGaps: the top recommended next actions to raise confidence
Returns a small JSON health payload with the active payment mode, policy profile, and configured LLM provider. This route stays open even when PROOFSPEND_API_KEY is configured so the local dashboard status strip can still load without extra client auth wiring.
The payload also includes lightweight operational diagnostics:
- process uptime
- current in-memory rate-limit settings
- recent webhook delivery outcomes
- heuristic pre-run confidence ranges for the standard 3-call baseline and the optional skeptic path
Returns the current OpenAPI JSON document for the ProofSpend API.
ProofSpend also exposes a lightweight MCP-style JSON-RPC endpoint for agent integrations. Supported methods include:
initializepingtools/listtools/callresources/listresources/read
Current MCP tools:
proofspend.run_diligenceproofspend.verify_proofproofspend.get_healthproofspend.get_openapiproofspend.explain_confidence
Current MCP resources:
proofspend://healthproofspend://openapiproofspend://runs/recent
When PROOFSPEND_API_KEY is configured, MCP tools/call and resources/read requests must send the same Authorization: Bearer <key> header as the HTTP API.
Accepts a completed DiligenceRun and returns an encoded snapshot plus its attestation. When PROOFSPEND_SIGNING_SECRET is configured, the attestation is server-signed with HMAC-SHA256; otherwise it falls back to a digest-only attestation.
Accepts either a snapshot string, a proofPacket JSON object, or a run plus attestation, then returns a verification result showing whether the digest and optional signature still match.
ProofSpend now treats confidence as a first-class product surface, not just a model guess:
confidenceis the deterministic overall research confidence in the0..1rangeproofScoreis the primary user-facing trust score in the0..100rangeproofScoreComponentsbreak that into:overallcitationCoveragerunCompleteness
confidenceBreakdownincludes:- per-agent confidence and negativity signals
- named positive/negative factors
- explicit policy adjustments such as strict-mode buy suppression
confidenceGapsdescribe the highest-leverage next action to improve certainty, including estimated gain and spend- paid-search gaps can be continued with a one-click follow-up run that reuses prior evidence and only buys the missing search
Confidence is bounded by the evidence collected in the run. It is a research score, not financial, legal, or procurement advice.
POST /api/run-diligence,POST /api/sign-snapshot, andPOST /api/verify-proofare protected by simple in-memory rate limits.- completed runs can now carry
webhookDeliverymetadata when a callback was attempted - the dashboard surfaces recent webhook outcomes in local history and health diagnostics
GET /api/schedulesandPOST /api/schedulesmanage in-memory recurring diligence templatesPATCH/DELETE /api/schedules/:idupdate or remove a schedulePOST /api/schedules/:id/rundispatches a saved schedule immediatelyPOST /api/webhooks/retryretries a recent webhook delivery bydeliveryIdGET /api/observabilityreturns recent run, webhook, schedule, verify, and MCP events
This repo now includes a Playwright-ready smoke scaffold:
playwright.config.mjse2e/proofspend.smoke.spec.mjs
Install @playwright/test in your local environment before running:
npm run test:e2eIf you are running in WSL and npx playwright install warns that the host is missing browser dependencies, install the Linux packages first:
sudo npx playwright install-deps
npx playwright installThen rerun:
npm run test:e2e- Start in mock mode to verify the UI and export flow.
- Switch to live mode in WSL if your Windows
awalbridge is unreliable. - Run the Apollo.io example question.
- Click a memo claim to trace it to the evidence row and receipt.
- Export the proof packet in Markdown or JSON.
- Copy a share link or compare the run against another saved vendor.
app/
api/health/route.ts
api/mcp/route.ts
api/observability/route.ts
api/openapi/route.ts
api/run-diligence/route.ts
api/schedules/route.ts
api/sign-snapshot/route.ts
api/verify-proof/route.ts
api/webhooks/retry/route.ts
layout.tsx
page.tsx
components/
RunForm.tsx
proofspend/Dashboard.tsx
ui/*
lib/
agents/
llm/
mock/
api-auth.ts
config.ts
health.ts
observability.ts
openapi.ts
orchestrator.ts
proof-packet.ts
rate-limit.ts
recent-runs.ts
run-sharing.ts
run-service.ts
safespend.ts
schedules.ts
sse.ts
subject.ts
trust.ts
types.ts
webhooks.ts
x402-search.ts
scripts/
check-prerequisites.mjs
probe-awal.mjs
smoke-llm.mjs
smoke-search.mjs
e2e/
proofspend.smoke.spec.mjs
test/
*.test.ts
Before pushing this repo to GitHub:
- Run
npm install - Run
npm test - Run
npm run build - Make sure
.envis not committed - Keep live wallet credentials only on your local machine
For the fuller release-prep flow, use RELEASE_CHECKLIST.md.