{"criteria_id":"settlement-evidence/v1","criteria_family":"settlement-evidence/v1","version":"1.0.0","corpus":{"id":"receipt-evidence-corpus/v1","sha256":"bbc0e3bf73fe0b4001b3c16837df494cb2f76322082686d888b8418c550b2ead"},"corpus_pin_definition":"The corpus pin is the SHA-256 of the corpus's canonical serialization (the corpus object excluding its sha256 field), computed and verifiable by the published harness (harness.mjs).","network":"solana-mainnet","asset":{"mint":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbol":"USDC","decimals":6},"price":{"usdc_units_per_call":10000,"label":"$0.01","basis":"per receipt"},"free_tier":{"per_day":100,"min_interval_ms":5000,"on_exhaustion":"402"},"input":{"body":"One JSON request body: { challenge, paymentResponse, caller? (free pre-check only) }. challenge is the captured 402 challenge object; paymentResponse is the PAYMENT-RESPONSE header value from the paid call (base64 JSON string; a raw JSON string or the already-decoded object are also accepted).","challenge":"Required captured challenge. The expected fields are taken from the challenge itself — accepts[0].payTo (recipient), accepts[0].asset, accepts[0].maxAmountRequired or amount, accepts[0].network, and the challenge memo when one is carried (challenge.memo or accepts[0].extra.memo) — never from the caller's say-so.","payment_response":"Required PAYMENT-RESPONSE header value. Decoded fields graded: success, transaction (the settlement signature), network, payer. A header whose content cannot be decoded is the paid substance: it grades RECEIPT-DECODE-FAILED, it is not a free refusal (only wrong input TYPES fail free).","over_cap":"A request body over 262,144 bytes is a free pre-gate refusal naming the cap."},"verdicts":["RECEIPT-MATCH","RECEIPT-MISMATCH","RECEIPT-UNVERIFIED","RECEIPT-DECODE-FAILED"],"engine_verdicts":["SETTLED-MATCH","SETTLED-MISMATCH","NOT-FOUND","PENDING","FAILED"],"graded_fields":["recipient","asset","amount","network","payer","success","memo"],"field_states":["MATCH","MISMATCH","MISSING","UNVERIFIABLE","NOT-IN-CHALLENGE"],"rules":{"header_unsigned":"The PAYMENT-RESPONSE header is UNSIGNED: it is a plain statement emitted by seller/facilitator software (success, transaction, network, payer), not a cryptographic attestation, and its signing key story is not the payTo key. This service reports what the header IS — its decoded fields and how they compare with the challenge and with the chain — and never upgrades it into an attestation.","decode":"The header value is base64-decoded and JSON-parsed (a raw JSON string or decoded object is accepted as the same content). Undecodable content, a non-object decode, or a missing transaction field grades RECEIPT-DECODE-FAILED with every graded field UNVERIFIABLE.","chain":"The header's transaction signature is chain-verified with the settlement-evidence/v1 engine (verifySettlement, build/engine.mjs imported unchanged, sha256 pinned in this config) using expected fields taken from the challenge: payTo = challenge recipient, amountUnits = challenge amount (EXACT u64 equality, never >=), memo = challenge memo when carried.","recipient":"MATCH when the transaction's transfer destination equals the challenge recipient's USDC associated token account (derived by the engine); otherwise MISMATCH.","asset":"MATCH when the transaction's transfer mint equals the challenge asset; otherwise MISMATCH.","amount":"MATCH when the transferred amount equals the challenge amount exactly; otherwise MISMATCH.","network":"MATCH when the header network and the challenge network name the same network (solana / solana-mainnet / solana:<genesis-hash> CAIP-2 forms are one network); a missing side grades MISSING; different networks grade MISMATCH.","payer":"MATCH when the header payer equals the transaction's transfer authority as found on-chain; a header without payer grades MISSING; a different payer grades MISMATCH.","success":"MATCH when the header success field is exactly true; otherwise MISMATCH.","memo":"Graded only when the challenge carries a memo: MATCH when the transaction's SPL Memo text equals it, else MISMATCH. Without a challenge memo the field grades NOT-IN-CHALLENGE and does not affect the verdict.","propagation":"When the engine returns NOT-FOUND, PENDING, or FAILED, the chain-dependent fields (recipient, asset, amount, memo, payer) grade UNVERIFIABLE and the overall verdict is RECEIPT-UNVERIFIED with the engine verdict named — never upgraded to a match or a mismatch on chain facts that were not established.","precedence":"RECEIPT-DECODE-FAILED outranks all; then RECEIPT-UNVERIFIED; then RECEIPT-MISMATCH (any graded field MISMATCH or MISSING); RECEIPT-MATCH requires every graded field MATCH (memo may be NOT-IN-CHALLENGE) and the engine verdict SETTLED-MATCH.","no_composite_score":"Factors are printed per field; there is NO composite score."},"engine_interface":"verifySettlement({ signature, expected }, rpc) -> verdict object; rpc is async (signature) => getTransactionResult | null. The engine is build/engine.mjs (sha256 960bf69968eba82249a0cf44f874dea3a09f17591108db03b3fb10e446248567), copied BYTE-IDENTICAL from the M-20 build and consumed through this pinned interface only; the identical block is delimited in this worker.","engine_sha256":"960bf69968eba82249a0cf44f874dea3a09f17591108db03b3fb10e446248567","boundary_b1":"Boundary vs B1 (M-20 settlement verification): B1 verifies one transaction against expected fields the caller itself supplies. B2 (this service) verifies a RECEIPT: it decodes the PAYMENT-RESPONSE header, takes the expected fields from the captured challenge (not from the caller's say-so), chain-verifies the header's transaction with B1's engine imported unchanged, and field-matches transaction against challenge. B1 does not decode headers; B2 does not take caller-supplied expected fields.","boundary_q25":"Boundary vs Q-25 (C5 subset-S reconciliation): Q-25 is a post-hoc signed report over submitted record sets inside subset S; B1 is a per-payment, per-call live chain read. The two do not share deliverables.","custody":{"ledger_closed_fields":["payer wallet","timestamp","day","price (USDC units) with the CAD fair-market-value block (rate, rate date, basis, cad_pending, refund — null unless refunded)","payment tx id","Solana fee (lamports)","criteria version","op","verdict line","receipt signature","verdict","engine verdict","house flag"],"ledger_note":"The ledger list above is closed: adding a field is a criteria/handling version change.","retention":"Submitted challenges and receipt headers are read once at call time and are never stored — not in KV, not in logs, not in the payments ledger, not in metrics. The payments ledger records only the closed field list published in the criteria (payer, time, price, the service's own payment tx, the receipt transaction signature, and the verdict). Because nothing is kept, a paid retry re-sends the receipt input."},"payment_includes":"$0.01 per receipt. The payment includes: one receipt verification — one captured 402 challenge plus the PAYMENT-RESPONSE header from the paid call — returned as the decoded header fields, a per-field match report against the challenge (recipient, asset, amount, network, payer, success, and memo when the challenge carries one), the chain verdict from the settlement-evidence/v1 engine for the header's transaction, the header's unsigned status stated plainly, and an as-of timestamp. Factors are printed per field; there is NO composite score. The service reports what the header IS — it never upgrades the unsigned header into an attestation; the chain, not the header, is ground truth for settlement. Nothing about the submitted receipt is stored beyond the payments ledger's closed field list.","unsigned_statement":"The PAYMENT-RESPONSE header is UNSIGNED: it is a plain statement emitted by seller/facilitator software (success, transaction, network, payer), not a cryptographic attestation, and its signing key story is not the payTo key. This service reports what the header IS — its decoded fields and how they compare with the challenge and with the chain — and never upgrades it into an attestation.","kill_line":"Kill line (M-21, under the operator's 2026-11-03 zero-demand doctrine): build, bank, and hold; judged at the fleet's periodic reviews. There is NO demand kill line for this item. Tripwires, all stop-and-review: refunds >5% of paid calls in any 30-day window; free use >10x paid use; a wrong verdict from undisclosed stale or partial data (stop-serving under the affected criteria version, per the corpus re-pinning discipline in the criteria).","service":"receipt-verify","endpoints":{"criteria":"GET /criteria (free)","precheck":"POST /precheck (free, input-shape validation + assessability + header-decodability only; no chain read, no verdict)","verify":"POST /verify (paid, $0.01 per receipt: signed receipt report — decoded header, per-field match report, engine chain verdict, unsigned-header statement, as-of timestamp)","metrics":"GET /metrics"}}