# PROOF — revenue-ledger-panel (2026-08-27)

Prototype #6. Closes the named open item from `prototypes/ethskills-x402/PLAN.md`,
Phase 5: *"Metrics: calls/day, revenue/day → ops-dashboard panel."*

Run environment: macOS 26.5.2, Python 3.9.6 (stdlib only — the guard ships a
pure-Python Keccak-256 and needs no third-party packages). All output below is
verbatim from the 2026-08-27 session; nothing was edited.

## 1. Render (0.03 s wall)

```
$ python3 render_panel.py
rendered panel.html + machine.json (settled=17, gross=8.0, ledger_sha256=55e05a6ca9bc8aad…)
rc=0
real	0m0.028s
```

Determinism — second run on unchanged inputs, byte-identical:

```
$ sha256sum panel.html machine.json
f5d39429e4a1c7e5b368683a8d3fbcda28d9d31ddf447774d9fdeaf70535a2b9  panel.html
f5ae61890521073099376c6fa212a977bbda1901fbcc70342c74783bfc234d68  machine.json
$ python3 render_panel.py >/dev/null && sha256sum panel.html machine.json
f5d39429e4a1c7e5b368683a8d3fbcda28d9d31ddf447774d9fdeaf70535a2b9  panel.html
f5ae61890521073099376c6fa212a977bbda1901fbcc70342c74783bfc234d68  machine.json
```

## 2. Guard — panel proven consistent with the raw ledger

```
$ python3 check_ledger.py
ok    ledger integrity — 19 records: schema, checksums, tx uniqueness, ordering
ok    anchor — every record's network/USDC/amount matches pricing.json (eip155:84532)
ok    machine.json — sidecar equals independent re-derivation (incl. ledger sha256)
ok    panel.html — embedded machine block identical to sidecar
ok    display — panel data-* attributes equal re-derived values (attempts/settled/gross/payers/network)
PASS  revenue-ledger-panel: panel numbers == raw-ledger re-derivation
guard_rc=0
```

## 3. Self-test — 13/13 (3 positive, 10 poisoned/negative)

```
$ python3 check_ledger.py --self-test
  PASS  P0 keccak256 matches known vector (+ eth_utils cross-check when present) (rc=None)
  PASS  P1 positive: committed panel vs raw ledger (rc=0)
  PASS  P2 positive: independent re-derivation reproduces committed sidecar (rc=None)
  PASS  N1 display-tamper rejected (99.0 vs 8.0) (rc=1, wanted 'data-gross' in output)
  PASS  N2 doctored machine.json rejected (gross +1.00) (rc=1, wanted "machine.json field 'gross'" in output)
  PASS  N3 duplicate settled tx rejected (rc=1, wanted 'DUPLICATE' in output)
  PASS  N4 failed-with-tx rejected (rc=1, wanted 'revenue leak' in output)
  PASS  N5 wrong-tier price rejected (topic at brief price) (rc=1, wanted 'topic-tier price' in output)
  PASS  N6 non-canonical network rejected (rc=1, wanted 'non-canonical network' in output)
  PASS  N7 stale panel (ledger grew since render) rejected (rc=1, wanted 'DIFFERENT ledger' in output)
  PASS  N8 FATAL missing ledger (rc=2) (rc=2, wanted 'FATAL' in output)
  PASS  N9 non-checksummed payer rejected (rc=1, wanted 'bad payer address' in output)
  PASS  N10 poisoned optional usdc field rejected (rc=1, wanted 'bad USDC address' in output)

SELF-TEST PASS — 13/13 cases behaved as expected (3 positive incl. keccak cross-check + byte-level re-derivation, 10 poisoned/negative)
selftest_rc=0
```

## 4. Derive, don't trust — independent raw-ledger derivation

Run **before** the panel existed, with a throwaway script (not part of the
prototype), to fix the numbers the panel must show:

```
nonempty lines: 19
settled: 17 failed: 2
gross_usdc: 8.000000
networks: {'eip155:84532'}
payers: 1
days: ['2026-08-24', '2026-08-25']
by_network_usdc: {'eip155:84532': 8.0}
by_path: {'/research/gas': (7, 0.7), '/briefs/ship-a-dapp': (7, 7.0), '/live/state': (3, 0.3)}
dupe tx: none
missing-keys issues: none
```

The panel's displayed values (`data-attempts='19' data-settled='17'
data-gross='8.0' data-payers='1' data-network='eip155:84532'`) match this
independent derivation exactly, and the guard enforces that match on every run.

## 5. Inputs

```
$ shasum -a 256 ../ethskills-x402/receipts.jsonl ../ethskills-x402/pricing.json
55e05a6ca9bc8aad4e3c1c91d100f96897b5838871f5a5adbf4b819f7b928658  ../ethskills-x402/receipts.jsonl
c55c91f369f43e3a542717cc4e83a99496e1eac95be6000d903efe8c642832a2  ../ethskills-x402/pricing.json
```

The ledger sha is embedded in both artifacts (`data-ledger-sha256` in
`panel.html`, `ledger_sha256` in `machine.json`) — the guard rejects any panel
rendered from a different ledger (self-test case N7).

## 6. Defects found and fixed during the build (in place, no v2 files)

1. **Wrong checksum hash.** First implementation of EIP-55 used SHA-256 (stdlib
   `hashlib` has no Keccak); it wrongly rejected the real ledger's payer address.
   Caught by the guard's positive case (P1) failing against unmodified data —
   exactly the failure mode the guard exists to catch. Fixed: pure-stdlib
   Keccak-256 in the guard, verified against the Ethereum empty-hash vector
   (`c5d24601…85a470`) and cross-checked against `eth_utils.keccak` on 8
   message lengths (self-test case P0). Same failure class twice
   (wrong rotation table, then wrong hash) — both caught by the same P0/P1
   positive cases before they could poison the rest of the run.
2. **Hardcoded tier split** ("7× $1.00 + 10× $0.10") in the renderer would have
   gone stale on the next settlement — replaced with a value derived from
   `by_path`.
3. **JSON tuple/list round-trip** — the re-derivation produced tuples that
   compare unequal to the JSON lists in the sidecar; both sides now normalize
   through a JSON round-trip before comparison (the comparison is on the values
   as committed).

## 7. Open

- Re-run `python3 render_panel.py && python3 check_ledger.py` after any new
  settlement lands (the guard's sha check is the liveness signal).
- P5 mainnet (PAY_TO + permanent origin) remains blocked on Walter's two
  decisions; this panel is the metrics half of P5, shipped.
