proof-aware-crypto-tooling-.../docs/cockpit.md
mrwulf dcb48f453e warden cockpit: local read-only custody UI for the human operator
Operator-ordered milestone, built under an explicit no-risk constraint
while the paper application is in flight: strictly ADDITIVE (one new
module + one CLI subcommand; zero changes to wallet semantics, the
public site, or anything the paper describes), LOCAL-ONLY (never
deployed; binds 127.0.0.1), and READ-ONLY in v1 (human approve/deny is
deliberately deferred — that is a custody-semantics change belonging to
a separately reviewed milestone).

New: src/pacta/walletui.py — four views over an existing wallet:
- Posture: latch state, ledger head with FULL hash-chain
  re-verification, pinned quorum members, spending policy verbatim.
- Signature queue: airgap outbox/inbox, observed never operated.
- Incidents & refusals: verbatim records, newest first.
- Receipt inspector: paste attestation + receipt + log key; verdict,
  per-signature results, and diagnostics come verbatim from
  transparency.verify_receipt — the deployed verifier itself, reused
  not reimplemented.

Design law, stated in the module and enforced by tests: THE COCKPIT
RENDERS EVIDENCE, IT NEVER ASSERTS IT. Every panel recomputes at
request time and carries a provenance line (function + timestamp);
anything unverifiable renders a loud FAILED-TO-VERIFY panel — no cached
green, no neutral gray. Panels state what they do NOT prove (e.g.
binary pinning vs source-to-binary correspondence).

CLI: pacta wallet cockpit --wallet DIR [--host --port].
Tests (10 new, suite 118 -> 128 green): recomputed-evidence rendering,
CHAIN BROKEN on tampered ledger, loud failure on collector error,
latched-state rendering, airgap queue states, verbatim incident/refusal
rendering, fail-closed inspector on garbage, real-evidence roundtrip
(skips if example evidence absent), full-sweep BYTE-LEVEL read-only
guarantee (wallet dir hash-identical after all GETs + a POST), and
fail-fast on non-wallet dirs. Rendering additionally verified visually
against a live demo wallet (posture, quorum table, incidents).

Docs: docs/cockpit.md; WALLET.md section; ESTATE.md + llms.txt updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 18:02:17 +02:00

2.8 KiB

The custody cockpit — a read-only surface for the human operator

pacta wallet cockpit --wallet <dir> serves a local web UI (default http://127.0.0.1:8471) over an existing warden wallet. warden has always been agent-native (MCP) and CLI-native; the cockpit is the third surface — for the human who ultimately answers for the money.

The design law

The cockpit renders evidence; it never asserts it. Every panel is recomputed at request time by the same functions the wallet itself uses (Wallet.posture(), Wallet.verify_ledger(), directory listings, transparency.verify_receipt), and every panel carries a provenance line naming the function and the timestamp. Anything that cannot be recomputed renders as a loud red FAILED-TO-VERIFY panel. There is no cached green and no neutral gray — a cockpit that shows unverified green lights would be the anti-warden.

The read-only guarantee

The cockpit cannot approve, sign, unlatch, or modify custody state. It calls only read paths; the one POST route (the receipt inspector) parses submitted artifacts in memory and throwaway temp files, never near the wallet directory. tests/test_walletui.py asserts this at the byte level: a full request sweep, POST included, leaves every file in the wallet directory hash-identical. Human approve/deny is deliberately NOT here — that would be a custody-semantics change, which belongs to a separate, explicitly reviewed milestone.

The four views

view shows recomputed by
Posture (/) custody latch state, ledger head with full hash-chain re-verification, the pinned quorum members (backend, component, tier, source commit, binary hash), spending policy verbatim, incident/refusal counts Wallet.posture() / Wallet.verify_ledger()
Signature queue (/queue) parked airgap signing requests (outbox) and whether the device has answered (inbox) — observed, never operated airgap outbox/inbox listing
Incidents & refusals (/incidents) incident records and signed refusal receipts, verbatim, newest first incidents/*.json, receipts/*.json
Receipt inspector (/inspect) paste an attestation + transparency receipt + log public key; the verdict, per-signature results, and diagnostics come verbatim from the deployed verifier pacta.transparency.verify_receipt

Every panel also states what it does not prove (e.g. the quorum table says binary hashes are pinned but source-to-binary correspondence is out of scope until reproducible builds).

Serving

pacta wallet cockpit --wallet ~/my-wallet          # 127.0.0.1:8471
pacta wallet cockpit --wallet ~/my-wallet --port 9000

The server binds localhost by default and is not meant to be exposed; there is no authentication because there is nothing to operate.