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>
3.4 KiB
Runbook: the custody latch fired
You are here because outbound custody is frozen and every signing request
returns CUSTODY_LATCHED. This is the wallet doing its job: an
unexplained quorum divergence or a firewall quarantine occurred, and the
wallet refuses to certify anything — including its own refusals, which
now arrive unsigned on purpose.
Do not unlatch first. Diagnose first. The latch is cheap; a released forged signature is not.
1. Read what happened (2 minutes)
pacta wallet status --wallet <dir> # latch reason + incident ref
cat <dir>/latch.json
cat <dir>/incidents/<ref>.json # the full divergence trail
ls <dir>/quarantine/ # any withheld signatures
pacta wallet verify-ledger --wallet <dir> # is the history itself intact?
The incident file names, per quorum member, its verdict and its binary hash at the moment of divergence. That table is your suspect list.
2. Classify (the incident file already did; check its work)
classification: semantic-edge(severitynote) — the input hit a documented degenerate class (small-order R, non-canonical s). This does NOT latch by itself; if you are latched, something else also happened.classification: unexplained(severitytamper) — members disagreed with no documented reason, or one errored. Assume fault or tampering until shown otherwise.
3. Investigate the three usual suspects, in order
- A corrupted/updated member binary. Compare each member's current
hash against the capsule:
shasum -a 256 dogfood/state/quorum/pacta-verify-*(GNU:sha256sum) vscapsule.json→members[].binary_sha256. A mismatch on exactly the dissenting member is the common benign case (a rebuild happened); a mismatch you cannot explain is not benign. - Hardware/memory fault. Re-run the exact input from the incident
file through the quorum (
payload_sha256,signature_hex,public_key_hexare all recorded). A divergence that does not reproduce points at a transient fault; log that finding in the unlatch note. - Actual tampering. Divergence reproduces, hashes match the capsule, input is not a documented edge → treat the host as suspect: rebuild members from pinned sources on a machine you trust, re-run, compare.
4. Remediate
- Benign rebuild drift → rebuild all members (
pacta wallet build-quorum), then re-init or re-seal the capsule so the pins match reality again. - Transient fault → document it; consider the machine's RAM.
- Suspected tamper → do not unlatch on this host. Preserve the wallet directory (it is the evidence), stand up a fresh wallet from fresh builds + fresh evidence elsewhere.
5. Unlatch — a deliberate, recorded act
pacta wallet unlatch --wallet <dir> --note "<what happened, what you checked, why it is safe now>"
The note is permanent: it lands in the hash-chained ledger next to the latch it releases, and shows up in every future audit. Write it for the auditor you hope never needs it. An empty or lazy note defeats the design; the CLI requires the flag, your discipline supplies the content.
6. Afterwards
Re-run a signing smoke test and confirm unanimous-accept; check
pacta wallet status shows latched: false, chain intact, and the
incident count where you expect it. If this wallet participates in a
choir, expect peers to ask about the head gap — that is the system
working.