Commit graph

15 commits

Author SHA1 Message Date
b232265264 docs: estate-wide consistency pass (workflow audit, 36 findings, all verified before fixing)
Nine parallel readers audited every doc against measured ground truth; every
finding was re-verified against the file before any edit, and the sweep fixed
by PROPERTY, not by flag — wording the readers caught in one repo was hunted
in all siblings (the two-button README sentence existed in all four forks,
not the three flagged; likewise the cone-overclaim in TRUSTED-BASE item 1).

This repo: see the diff. Records were not rewritten; clarifications are
dated. Doc-only except where noted in the estate summary; every gated doc
change was followed by a green button run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 16:00:54 +02:00
ddbb5a4fd8 fix(verify_consistency): restore RFC 9162 Step-7 terminal sn==0 check
The deployed consistency verifier implemented the RFC 9162 2.1.4.2
bit-navigation loop but its final return checked only the two
reconstructed roots, omitting the terminal condition that the new-size
navigation counter reach zero. That condition couples the consumed proof
length to the claimed tree sizes; without it, a valid proof for one
transition verifies under a lied (power-of-two) old size. Flagship: a
valid 2->3 proof is accepted under the false claim 1->3 with the size-2
root.

Fix: add `and sn == 0` to the final return.

This is the corpus's Known Gap 14 (3,867 deployed-accepts-only cases in a
pinned 73,573-case family, recorded in public log entry 13). It was
found by the project's own differential harness; a post-appeal review
round added a faithful RFC oracle as a third comparison, which showed
the deployed verifier — not the mechanized model — was the one deviating
from RFC 9162, and traced it to the missing terminal check.

Scope: verify_consistency's only production caller is the consumer-side
pin store, reached only behind a verified head signature. Generation is
RFC-correct and unaffected; the live provider service does not run this
verifier; the published standalone verify.py has no consistency verifier.
An empirical search found 0 realizable pin-advance poisons against an
honestly pinned consumer, consistent with Known Gap 14's non-claim.

Verification:
- New fail-first three-way regression test
  test_consistency_lied_size_three_way_agreement (deployed / recursive
  ConsRec model / independent faithful RFC 9162 transliteration) over the
  honest AND lied-size families; fails pre-fix, passes post-fix.
- Historical differential tests (164,479 inclusion; 164,224 consistency)
  unchanged — the fix rejects nothing honest.
- Full suite: 145 passed, 0 failed.

Public log entry 13, the attested accumulator commit, and the IACR
submission PDF are all unchanged. Vulnerable state tagged
vulnerable/sn0-consistency-fd2f6ba. See
docs/security-2026-07-23-consistency-terminal-check.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:34:23 +02:00
37429335e6 docs: coherence + portability audit — clean-clone bootstrap proven
Audit question: is the documentation coherent, and is the app portable
to a fresh machine (macOS) with proper isolation? Findings and fixes:

- README never mentioned the cockpit/deck/lab manual (three rounds of UI
  evolution invisible at the front door). Added: human-surface section
  with the one command, expanded Install (editable-from-clone is the
  supported mode — repo files are part of the product; zero-install
  PYTHONPATH=src alternative; fresh-machine skip behavior), macOS
  openssl/LibreSSL Ed25519 prerequisite with a one-line self-check,
  wallet commands in the command list.
- The lab manual violated the repo's own macOS law (AGENTS.md): GNU
  sha256sum -> shasum -a 256; GNU sed -i -> portable python3 -c
  one-liner (executed and output-matched before shipping: entry 0 hash
  mismatch, BROKEN, exit 1).
- Fresh-clone bootstrap was actually tested end to end in a scratch
  clone: zero-install suite 130 passed / 0 failed / 14 skipped after
  fixing the one unguarded test (test_ledger_is_hash_chained now skips
  like its siblings when the dogfood binary is absent - capability gap,
  not failure); venv + pip install -e . -> pacta console script serves
  bridge/deck/manual/sample-prefill/drift-tripwire with no PYTHONPATH.
- PYTHONPATH incantations simplified: cockpit needs src only (provider
  never imported by src/pacta); manual + cockpit.md updated.
- threat-model.md: cockpit attack-surface note (no mutating routes,
  no auth because nothing to operate, localhost-only disclosure risk,
  probe-only network I/O, fake-cockpit = host-compromise boundary).
- products.md: cockpit named as the shared human surface of all four
  profiles. AGENTS.md: doc-portability law + the cockpit's three laws
  added to the standing guidance.

Suite 144 green here; 130/0/14 on a bare clone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 18:00:08 +02:00
1d712a884a cockpit: the lab manual — a study-club course in six chairs (/manual)
Operator asked for a real big fat user manual: read on one monitor with
the deck on the other, worked like a lab from beginning to end, with
highest didactical skill — the goal being to educate ONE person in ALL
roles, as if to BECOME each role. Shipped as a full course:

- docs/warden-lab-manual.md (canonical, ~7100 words): 8 sessions +
  capstone. Fixed didactic ritual per role-session: why the role exists
  -> the mind of the role -> concepts -> LAB (numbered machine exercises
  with checkpoint rails) -> never-list with whys + thought experiment ->
  handoff artifact -> self-test -> recap card. Notation: do / checkpoint
  / write / optional. Capstone 'incident day': one incident walked
  through all six chairs producing seven written artifacts; graduation
  session maps the path to a real wallet; Appendix A command reference
  by chair, Appendix B full self-test answers.
- Session 4's tamper drill: copy the demo wallet, flip one character of
  ledger history, watch verify-ledger AND a second cockpit catch it.
  Every checkpoint in the manual was executed by the author before
  commit: status fields, intact-chain exit 0, tampered-chain 'entry 0:
  hash mismatch / BROKEN' exit 1, CUSTODY EVIDENCE BROKEN banner.
- src/pacta/mdlite.py: deliberately small stdlib Markdown renderer
  (headings/anchors+TOC, bold/italic/code with placeholder stashing,
  fences, lists, quotes, tables, links); tested against the real manual
  for zero artifact leaks.
- /manual route with syllabus TOC; manual typography (checkpoint boxes,
  session borders); nav tab, deck wizard cross-link, cli hint.

Suite 142 -> 144 green; read-only sweep covers /manual.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 17:26:09 +02:00
15421ac4d0 cockpit: the deck — tmux-style pane grid + the color-camouflaged wizard
Operator asked for a tmux-type panes grid in the browser (one pane per
role, all acting in parallel, like real life) with a wizard on the right
that takes a newcomer by the hand through every role's actions, each
instruction camouflaged in that role's color.

- /deck: CSS-grid of six live panes (2-col, 3-col on wide screens),
  one per station, each an iframe onto /station/<id>?pane=1. tmux
  controls per pane: reload, single-pane zoom, open-full. Narrow
  screens: wizard first, panes stacked.
- pane mode (?pane=1): chrome-stripped shell (no h1/banner/nav), same
  station content, READ-ONLY label kept; an 8-line shim re-carries
  pane=1 on every same-origin link and form submit, so probes, incident
  browsing, and inspect verdicts all happen inside the pane.
- the wizard: a 10-step guided first watch across all six roles on the
  live demo wallet. Each step card wears the role's hue with a 'YOU ARE
  THE <ROLE>' chip, the matching pane glows, and every step states what
  success looks like + what was just learned. Step remembered per
  session (sessionStorage).
- /inspect?sample=1 pre-fills examples/wallet-evidence so the
  cryptographer step verifies (then deliberately breaks) real evidence.
- verified in a real browser: step navigation moves the glow, panes
  load their stations, Probe-now inside the pane probed live inside the
  pane (log head tree_size 13), sample flow prefilled the key in-pane.

Suite 139 -> 142 green. Read-only guarantee unchanged; byte sweep
covers /deck and pane routes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 17:04:23 +02:00
a18877612d cockpit: the bridge — six role stations, the crew law, live liveness
Operator verdict on round two: better, but 'still no coherent
application'. The cockpit must provide everything a human crew would
need if no AI were around — as distinct roles that cooperate through
handoffs and never melt into each other. This rebuilds the IA as a
bridge with six stations over shared instruments, in the control-room
tradition (overview -> station -> instrument -> raw files/CLI), with
maker-checker separation of duties encoded in the UI itself.

- / is now the Bridge: whole-system verdict strip, six crew cards with
  live data, and the dispatch (andon) board 'if this happens, who acts'
- /station/{proposer,quorum,operator,cryptographer,architect,newcomer}:
  each console has a fixed anatomy: Mission -> Duties (every duty a
  runnable, verified-real CLI command - the no-AI drill) -> embedded
  live instruments -> 'This station never...' (separation of duties) ->
  Handoffs (receives/delivers)
- Operator gets a real liveness board: on-demand parallel probes (HTTP
  GET on log head/paper/blog/mirror with observed facts + latency; git
  HEAD/cleanliness on all 9 local repos). Never probes on ordinary page
  loads. Verified live: caught this very repo as 'alive, dirty' while
  building it, and confirmed log 13/3488a2d0 + paper 7f140356
- Architect gets the live drift tripwire (ESTATE.md vs estate view)
- modularized per the standing separation-of-concerns order:
  uikit.py (primitives+style), stations.py (role model, pure),
  liveness.py (probes), walletui.py (collectors, instruments, routes)
- crew law test-enforced: bridge crew+dispatch, per-station role
  contract, station distinctness (signature phrases must not bleed
  across roles), explicit-probe semantics; read-only byte sweep now
  covers all 13 routes incl. the probe route
- narrow-viewport fix: breakany for unbreakable paths in headings

Suite 135 -> 139 green. Read-only guarantee unchanged: no mutating
routes; every custody act is a printed command, never a button.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 16:47:43 +02:00
00be6a396e cockpit: UX law — the cockpit never leaves a human in the dark
Operator verdict on the first cockpit: unusable, jargon-walled. The
evidence layer was honest but the presentation assumed the reader
already lived inside warden's head. This rebuilds the presentation
layer around a testable UX contract, additive to the design law:

- every page: verdict IN WORDS first (CUSTODY HEALTHY / CUSTODY FROZEN
  (LATCHED) / CUSTODY EVIDENCE BROKEN), then evidence, then provenance
- every page: plain-language lead saying what the page answers
- every panel: 'How to read this panel' expander interpreting every
  column and pill; jargon carries a ? linking to the glossary
- new /guide view: what warden is, how to read any page, color code,
  five-minute tour, 12-term glossary, honest 'what this cockpit cannot
  tell you'
- navigation: two-line tabs stating the question each view answers,
  present on every page; /estate gets a back-to-cockpit chip
- explained empty states (incidents: 'empty is the good state')
- narrow-viewport fix: tables/pre scroll in their own containers
- estate fact chip updated 130->135 green (both renderings)

UX contract is test-enforced (guide terms, lead+nav+explainers on every
view, empty states); read-only byte-guarantee sweep now covers /guide.
Verified by looking: served --demo, walked all six views in a browser.
Suite 131 -> 135 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 16:15:00 +02:00
b3239dba45 cockpit: --demo flag — one command from zero, custody-inert
The operator ran the documented command and hit the fail-fast (no
wallet exists on a fresh machine) — correct behavior, useless
instruction. seal_demo_wallet() now seals a throwaway DEMO wallet
(fake shell-stub members, DEMO-labeled fields, temp dir named
warden-DEMO-*, sample incident/refusal/airgap so every view has
content); 'pacta wallet cockpit --demo' serves it. Exactly one of
--wallet/--demo required. Verified by running the literal command:
all five views 200, demo quorum renders. Suite 130 -> 131.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 15:09:26 +02:00
1acbaa1a76 cockpit: estate map as a fifth view, with RUNTIME as a first-class dimension
Operator questions answered in code: (1) the estate map now lives IN the
cockpit too — /estate serves the interactive map (lanes, typed edges,
loops, clickable dossiers) to the same human audience the cockpit
serves; ESTATE.md remains the canonical committed version (renders on
GitHub, reachable by agents via llms.txt, needs no running process), and
a name-level sync test guards drift between the two renderings — the
published_assets lesson applied preemptively. (2) 'What is RUNNING?' is
now answered everywhere: an operations strip on the map (ALWAYS ON:
caddy + the LTL read-only container + Forgejo with its single 03:00
mirror cron, all droplet; ON-DEMAND: append/publish/sign ceremonies,
cockpit, MCP, operator machine only; NOT RUNNING: warden — prototype,
no deployed instance, no funds watched; everything else: static files
or external parties), a per-entity Runtime line in every dossier, and a
verified What-is-running table in ESTATE.md (container commands, :ro
mounts and read_only:true on the LTL service, and the crontab checked
on the droplet 2026-07-20, not recalled).

Suite 128 -> 130 (estate route + drift guard). Local-only as before:
nothing deployed, live estate untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 10:58:59 +02:00
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
5e8eba8e52 lineup: treasury LIVE, 100 tests
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:39:27 +02:00
65772b3d2e warden hardening round: policy engine, ledger rotation, MCP UX, treasury LIVE, ops docs
Tier 2:
- request_signature decomposed into named gates (latch, freshness,
  intent, policy, signer, firewall)
- ledger: O(1) tail-read appends under a dedicated lock file (survives
  rotation rename); hash-chained segment rotation at policy
  ledger.rotate_at; verify-ledger walks all segments to genesis;
  archive tampering detected (tested)
- docs/threat-model.md (attacker matrix 1-9, proven-vs-trusted, design
  invariants) + docs/runbook-latch.md (diagnose-first recovery)
- lecture 10: executable corrupt-a-member exercise (capsule pin catches
  one appended byte), honest note on what the pin does NOT stop

Lightweight policy engine (POLICY_DENIED wired):
- policy.json: per-request/per-day amount ceilings, counterparty
  allow/deny lists, per-identity overrides; rules make their intent
  fields mandatory; daily sums from the ledger
-

Agent UX:
- signed refusal receipts travel inside MCP errors (receipt +
  receipt_path in structuredContent)
- airgap over MCP: request_signature signer=airgap + request_id,
  new airgap_pending tool; park -> list -> device answers -> complete
  (tested end-to-end)
- all 8 tools carry readOnly/destructive annotations
- sliding-window rate limiter per tool class (custody/verify/liveness);
  RATE_LIMITED refusal code; surface control, not ledgered

warden-treasury LIVE:
- treasury.py: stdlib base58, compact-u16, legacy+v0 wire parsing;
  every required signature quorum-verified over exact message bytes;
  completeness gap named in every verdict; RPC fetch uses response as
  bytes only
-
- live-quorum test: synthetic Solana tx signed with wallet key ->
  authentic via 4 proven forks; flipped byte -> not authentic

100 tests green (was 85).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:38:42 +02:00
6b9f033151 warden: product-lineup presentation (docs/warden-lineup.html)
Self-contained dark-theme product page: the one idea, the trust-posture
asymmetry, the firewall diagram, the four deployment profiles, and the
non-claims. Also published as an artifact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:50:29 +02:00
ba47aa435d warden docs + study material: WALLET.md, products lineup, llms.txt, lecture 10
- WALLET.md: the product manual (one idea, trust posture table, R4 gate,
  quickstart, MCP surface, self-proving card, firewall, taxonomy)
- docs/products.md: four production-ready deployment profiles
  (solo/airgap/treasury/choir) with honest built-vs-wired boundaries
- llms.txt: agent-native discovery manifest at repo root
- README: warden intro + lecture 10 pointer
- notebooks/10_verified_custody_wallet.ipynb: ratchet-rule lecture (toy
  3-of-3 -> real four proven forks -> counterparty recomputes a card's
  inclusion proof); course README + notebook test updated
- 83 tests green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:46:27 +02:00
6cd08b771d warden: agent-native field research + design decisions (AX/MCP/A2A/AP2/x402/ERC-8004)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:20:56 +02:00