mirror of
https://github.com/saymrwulf/proof-aware-crypto-tooling-agent.git
synced 2026-09-03 19:53:43 +00:00
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>
This commit is contained in:
parent
1d712a884a
commit
37429335e6
7 changed files with 92 additions and 6 deletions
|
|
@ -6,6 +6,8 @@ Guidance for future Codex runs in this repository:
|
|||
- Do not regenerate Lean from Rust. Treat shipped Lean files in verified repos as the artifact.
|
||||
- Do not claim end-to-end verification unless theorem coverage actually exists.
|
||||
- Keep macOS and Apple Silicon portability. Do not rely on GNU `timeout`, `free`, `taskset`, Docker, Nix, or x86_64 assumptions.
|
||||
- The same portability law applies to DOCUMENTATION: commands printed in docs, the cockpit, and the lab manual must run on macOS (BSD userland: `shasum -a 256` not `sha256sum`; no GNU `sed -i` form; prefer portable `python3 -c` one-liners), and every printed command must be executed once before it ships.
|
||||
- The cockpit's three laws are load-bearing: renders-evidence-never-asserts (provenance lines, loud FAILED TO VERIFY), never-leave-a-human-in-the-dark (verdict in words, explainers, glossary links), and distinct-roles-with-handoffs (stations never melt). All three are test-enforced; keep them so.
|
||||
- Prefer explicit theorem-boundary language over marketing language.
|
||||
- Update tests with every behavior change.
|
||||
- Do not silently lower risk ratings. A lower score must explain the failed or missing evidence.
|
||||
|
|
|
|||
48
README.md
48
README.md
|
|
@ -24,10 +24,38 @@ agent-native first (an MCP server; a self-proving custody card); see
|
|||
[docs/products.md](docs/products.md), and the design research in
|
||||
[docs/agent-native.md](docs/agent-native.md).
|
||||
|
||||
For humans, warden ships the **custody cockpit** — a local, read-only web
|
||||
UI organized as a bridge of six role stations (proposer, quorum bench,
|
||||
operator, cryptographer, architect, newcomer) over shared evidence
|
||||
instruments, with a tmux-style deck showing every station live in
|
||||
parallel and a color-guided wizard. It explains itself; no prior warden
|
||||
knowledge is assumed. One command, no wallet needed:
|
||||
|
||||
```bash
|
||||
pacta wallet cockpit --demo # → http://127.0.0.1:8471/deck
|
||||
```
|
||||
|
||||
The full course lives beside it: [docs/warden-lab-manual.md](docs/warden-lab-manual.md)
|
||||
(served at `/manual`) — a study-club lab that teaches every role hands-on.
|
||||
Docs: [docs/cockpit.md](docs/cockpit.md).
|
||||
|
||||
## macOS / Apple Silicon
|
||||
|
||||
The prototype is written for Python 3.11+ and macOS on Apple Silicon. It does not assume GNU coreutils, Linux `free`, Linux `taskset`, GNU `timeout`, Docker, Nix, or x86_64.
|
||||
|
||||
One system prerequisite for the wallet features (key generation and
|
||||
signing, including `cockpit --demo`): an `openssl` on PATH that supports
|
||||
Ed25519. Stock macOS ships LibreSSL as `/usr/bin/openssl`, and older
|
||||
LibreSSL versions lack the Ed25519 key commands — self-check with:
|
||||
|
||||
```bash
|
||||
openssl genpkey -algorithm ed25519 | head -1 # must print a PEM header, not an error
|
||||
```
|
||||
|
||||
If it errors, `brew install openssl@3` and put it first on PATH (e.g.
|
||||
`export PATH="$(brew --prefix openssl@3)/bin:$PATH"`). `git` on PATH is
|
||||
needed only for the cockpit's liveness board repo probes.
|
||||
|
||||
Lean tooling is detected with `shutil.which("lean")` and `shutil.which("lake")`. If neither is available, `pacta` reports clear diagnostics and still supports offline claim-card generation and static hygiene scans.
|
||||
|
||||
## Tests
|
||||
|
|
@ -39,18 +67,38 @@ python3 scripts/mini_pytest.py # dependency-free fallback runner (same suite)
|
|||
|
||||
## Install
|
||||
|
||||
Runtime dependencies: **none** — the tool is Python 3.11+ standard
|
||||
library. The supported install is an **editable install from a clone**:
|
||||
the repo's own files (estate map, lab manual, sample evidence) are part
|
||||
of the product and are resolved relative to the checkout.
|
||||
|
||||
```bash
|
||||
git clone <this repo> && cd proof-aware-crypto-tooling-agent
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install -e ".[dev]"
|
||||
pacta wallet cockpit --demo # smoke-test the human surface
|
||||
```
|
||||
|
||||
Zero-install alternative (no venv, no pip, straight from the clone):
|
||||
|
||||
```bash
|
||||
python3 scripts/mini_pytest.py # dependency-free suite
|
||||
PYTHONPATH=src python3 -m pacta wallet cockpit --demo
|
||||
```
|
||||
|
||||
On a fresh machine with no Lean toolchain and no locally built dogfood
|
||||
binary, the suite passes with a handful of clearly labeled skips —
|
||||
capability gaps skip, they never fail silently.
|
||||
|
||||
PyYAML is optional. Without it, `pacta` can still read the included simple YAML examples and JSON-compatible `.yaml` files.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
python -m pacta --help
|
||||
pacta wallet cockpit --demo # the human surface: bridge, deck, lab manual
|
||||
pacta wallet status --wallet DIR # custody posture from the CLI
|
||||
pacta scan --config examples/repos.yaml
|
||||
pacta doctor --config examples/repos.yaml --repo-name dalek-ed25519-verified
|
||||
pacta claims --config examples/repos.yaml --repo-name dalek-ed25519-verified --offline-fixture --out claims.yaml
|
||||
|
|
|
|||
|
|
@ -159,8 +159,9 @@ pacta wallet cockpit --wallet ~/my-wallet # 127.0.0.1:8471
|
|||
pacta wallet cockpit --wallet ~/my-wallet --port 9000
|
||||
```
|
||||
|
||||
(Uninstalled, from the repo root:
|
||||
`PYTHONPATH=src:provider/src python3 -m pacta wallet cockpit --demo`.)
|
||||
(Installed per the README — venv + `pip install -e .` — the plain `pacta`
|
||||
command works. Zero-install, from the repo root:
|
||||
`PYTHONPATH=src python3 -m pacta wallet cockpit --demo`.)
|
||||
|
||||
The server binds localhost by default and is not meant to be exposed;
|
||||
there is no authentication because there is nothing to operate.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ are **production-ready product definitions**, not four separate codebases:
|
|||
each is the same `pacta wallet` core with a different signer, policy, and
|
||||
surface. Presented here as products so the shape of each is unambiguous.
|
||||
|
||||
Every profile also ships the same human surface: the **custody cockpit**
|
||||
(`pacta wallet cockpit`) — local, read-only, six role stations over live
|
||||
evidence instruments, with the deck, the guide, and the lab manual. See
|
||||
[docs/cockpit.md](cockpit.md).
|
||||
|
||||
The trust posture in [WALLET.md](../WALLET.md#trust-posture) applies to all
|
||||
four without exception. What differs is *where the boundary sits* and *what
|
||||
the wallet is wired into*.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,27 @@ lying (firewall); an attacker who fully owns the host owns the wallet.**
|
|||
- **Deliberately absent**: reproducible builds, side-channel hardening
|
||||
(R5 frontier); ML-DSA (fail-closed — no proven implementation exists).
|
||||
|
||||
## The cockpit surface (attack surface note)
|
||||
|
||||
The custody cockpit (`pacta wallet cockpit`) adds a localhost-bound,
|
||||
read-only HTTP surface. Its threat posture, stated plainly:
|
||||
|
||||
- **No mutating routes exist.** It cannot approve, sign, unlatch, or edit
|
||||
custody state; the test suite asserts byte-level wallet-directory
|
||||
identity across a full request sweep including POST. Custody-mutating
|
||||
acts are only ever printed as CLI commands for the human.
|
||||
- **No authentication because there is nothing to operate** — but it binds
|
||||
`127.0.0.1` by default and must not be exposed: it *reads* wallet state,
|
||||
so exposure is an information-disclosure risk (posture, incidents,
|
||||
member fingerprints), not a custody-control risk.
|
||||
- **It phones home never by default.** Outbound traffic happens only when
|
||||
the operator explicitly presses «Probe now» (liveness GETs) — page loads
|
||||
perform no network I/O.
|
||||
- An attacker who can serve the operator a *fake* cockpit (host compromise,
|
||||
attacker #7) can lie to the human — which is the standing host-compromise
|
||||
boundary above, not a new one; the CLI (`pacta wallet status`,
|
||||
`verify-ledger`) remains the independent second surface.
|
||||
|
||||
## Design invariants the controls enforce
|
||||
|
||||
1. **Unanimity or nothing**: no majority voting; any divergence fails
|
||||
|
|
|
|||
|
|
@ -27,10 +27,14 @@ exercises, open a *second* terminal in the same repo directory and set up two
|
|||
things once (the server keeps running in the first terminal):
|
||||
|
||||
```
|
||||
alias pacta='PYTHONPATH=src:provider/src python3 -m pacta'
|
||||
alias pacta='PYTHONPATH=src python3 -m pacta'
|
||||
export W=/tmp/warden-DEMO-xxxxxxxx/wallet # <- your printed demo path
|
||||
```
|
||||
|
||||
(If you installed per the README — venv plus `pip install -e .` — skip the
|
||||
alias: plain `pacta` already works. The alias is the zero-install path
|
||||
straight from a clone; both are equivalent for this course.)
|
||||
|
||||
**Time.** The course is eight sessions plus a capstone: roughly four to six
|
||||
hours total. Every session is self-contained — stopping after any session and
|
||||
resuming tomorrow is fine. The demo wallet is throwaway: if you come back
|
||||
|
|
@ -267,7 +271,7 @@ chair with hard walls — and in exchange, the Proposer gets something rare:
|
|||
|
||||
```
|
||||
printf 'pay 5 to bob' > /tmp/payload.demo
|
||||
sha256sum /tmp/payload.demo
|
||||
shasum -a 256 /tmp/payload.demo # GNU/Linux equivalent: sha256sum
|
||||
```
|
||||
|
||||
Change one character (`5` → `6`) and hash again. ✎ How much of the
|
||||
|
|
@ -487,7 +491,8 @@ pacta wallet verify-ledger --wallet "$W"
|
|||
|
||||
```
|
||||
cp -r "$W" /tmp/tamper-lab-wallet
|
||||
sed -i 's/genesis/gene-sis/' /tmp/tamper-lab-wallet/ledger.jsonl
|
||||
python3 -c "p='/tmp/tamper-lab-wallet/ledger.jsonl'; s=open(p).read(); \
|
||||
open(p,'w').write(s.replace('genesis','gene-sis'))"
|
||||
pacta wallet verify-ledger --wallet /tmp/tamper-lab-wallet
|
||||
```
|
||||
|
||||
|
|
@ -889,7 +894,7 @@ wallet state — real operations, operator's deliberate acts).*
|
|||
| any | `pacta wallet cockpit --demo` | seal + serve a throwaway demo wallet |
|
||||
| any | `pacta wallet cockpit --wallet DIR` | serve the cockpit over a wallet |
|
||||
| any | `pacta wallet status --wallet DIR` | custody posture (capsule, latch, ledger) |
|
||||
| Proposer | `sha256sum payload.bin` | the payload fingerprint, born |
|
||||
| Proposer | `shasum -a 256 payload.bin` | the payload fingerprint, born |
|
||||
| Proposer | `pacta wallet mcp --wallet DIR` | the front door (then `request_signature`) |
|
||||
| Proposer | `pacta wallet treasury-verify --wallet DIR --tx-file f` | quorum-verify a transaction's signatures |
|
||||
| Quorum | `pacta wallet build-quorum --sources-root DIR` | rebuild members from pinned proven sources |
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ def _payload_intent(payload: bytes) -> dict:
|
|||
|
||||
|
||||
def test_ledger_is_hash_chained(tmp_path):
|
||||
from pacta.dogfood import locate_verifier
|
||||
|
||||
if locate_verifier() is None:
|
||||
pytest.skip("dogfood signer not built")
|
||||
wallet = _seal_wallet(tmp_path, {"a": "accept", "b": "accept"}, tmp_path / "state")
|
||||
payload = b"hello"
|
||||
wallet.request_signature(_payload_intent(payload), payload, state_dir=wallet._test_state_dir)
|
||||
|
|
|
|||
Loading…
Reference in a new issue