# Gate C — local backend/blockchain acceptance

**Status: ACCEPTED LOCALLY.** Assessment date: 2 November 2026. Scope: the local, persistent API/SQLite/outbox/Hardhat integration with Mock-USDC and explicitly local test signers. This is not testnet evidence, independent security approval or a production release.

## Implemented boundary

Authorized payment terms bind the local network, vault, token, buyer/merchant addresses, amount mapping and required confirmations. Payment, dispute opening, final refund/denial and expiry each have durable, idempotent work. A submission is never a completed financial operation. Financial posting and job completion commit together only after canonical, sufficiently confirmed receipts for the expected sender, destination, method, calldata and event.

The default browser sandbox remains a simulation. The linked integration is exercised through the role-checked HTTP API and separate worker processes. The ledger records TEST-USD mirror accounting; it is not a live ERC-20 wallet balance. One cent maps explicitly to 10,000 six-decimal mock-token units. Ordinary simulated merchant withdrawals are disabled in the linked mode; local-wallet token transfers are separate and do not invalidate merchant payment finality.

## Acceptance matrix

| Criterion | Implementation and evidence |
|---|---|
| Persistent protocol, ledger, identities and API idempotency | `test/persistence.test.js`; real server process restarts through a completed refund; no repeat funding or key reactivation |
| Transactional outbox and durable transaction identity | Reservation event/outbox plus immutable lifecycle request outbox; `src/blockchain/local-vault-relay.js`, `local-vault-lifecycle.js`, `transaction-journal.js` |
| Confirmed payment before ledger credit | HTTP binding/authorization, pending receipts, lost-response handling; `solidity-test/LocalVaultRelay.cjs` |
| Complete protection lifecycle | Confirmed dispute, assigned independent reviewers, appeal, final pool refund/denial, timeout and expiry; `solidity-test/LocalVaultLifecycle.cjs` |
| Restart and duplicate delivery | Seven independent worker processes in `npm run relay:demo`; faults after broadcast and inside the ledger commit; competing workers and expired ownership tests |
| Failed or uncertain submission | Real out-of-gas/reverted receipt, missing response after accepted transfer/refund, no blind resend or early credit; `LocalVaultRecovery.cjs` and `test/chain-journal.test.js` |
| Canonical event cursor and reorg handling | Checkpoint validation, duplicate events, halted canonical reads, approved rescan and retained orphan evidence; journal and recovery tests |
| Read-only cross-system reconciliation | Ledger, requests/jobs, receipts, reservations and pool totals; live authorized `GET /v1/reconciliation`; concurrent local changes defer observations instead of fabricating failures |
| Controlled recovery | Exact-receipt recovery plan binds network, vault, current database snapshot, observed transactions, nonce and expiry. Distinct vault administrator and provider signatures are required. Wrong/single/stale/expired/replayed approvals are rejected |
| No automatic financial correction | Recovery updates observed proof metadata/cursor only; raw events, accounting and append-only signed approval history remain intact. Unresolved divergence stays halted |

## Reproducible checks

```powershell
npm.cmd run relay:demo
npm.cmd run verify
npm.cmd run verify:browser
```

The final complete verifier passed **159 Node tests and 38 Contract/Hardhat integration tests**, protocol/vault/full-relay demos, dependency audit (**zero vulnerabilities**), static build (**22 assets, 16 guides and OpenAPI**), documentation (**35 Markdown files**), secret and website checks. The separate Chromium run passed **ten acceptance groups**, including the complete default browser payment/refund flow. Local generated evidence is ignored under `reports/gate-c-verify.log` and `reports/b3-browser/report.json`.

The demo proves payment -> merchant spends tokens -> non-delivery claim -> confirmed dispute -> two independent reviewers -> appeal expiry -> confirmed pool refund. It restarts API/SQLite and runs seven isolated workers, prints the receipt references and reconciliation result, then cleans up its ephemeral database and chain fixture.

## Operator recovery

See [the worker and recovery guide](docs/local-vault-operations.md). The CLI can inspect and reconcile while processing is halted, prepare an unsigned plan and verify two externally produced approval signatures. It never automatically signs operator approvals, infers a missing transfer, or force-unlocks a mismatched ledger. A known successful canonical replacement must exist before it can be adopted.

Every accepted recovery is append-only and carries the previous observations. Orphan logs are retained for audit; the canonical projection is rescanned under a new cursor generation. If a previously orphaned block becomes canonical again, its classification can change only under another verified signed recovery.

## Remaining work belongs to later gates

- Gate D: user wallet connection/signing, testnet configuration and explicitly approved Base Sepolia deployment/verification. No mainnet or real USDC.
- Gate E: independent security/risk review, production key custody, monitoring, backups/incident operations and production identity/governance.
- Gate F/G: named provider pilot and evidence-backed ecosystem expansion.

This local acceptance does not establish hosted CI, cross-network support, external provider settlement, legal/compliance readiness, throughput/SLA or independent certification. The local fixture clock is explicit; a real deployment must use the approved chain/time and wallet model of the later gates.
