v0.13.0 — External-Review Hardening
Converts a professional external critique into normative documentation, protocol-level distinctions, and cross-language interop proof. No frozen-core semantics changed — everything is additive.
The six critiques → the six answers
| # | Critique | Fix in v0.13 |
|---|---|---|
| 5 | "JCS-subset" invites JCS conformance expectations | docs/CANONICALIZATION.md — PiProof Canonical Profile v1 vs RFC 8785, rationale per deviation, 6 conformance requirements + 15 interop vectors agreed byte-exact by two independent implementations (Node + from-scratch Python stdlib), CI'd on Py3.10/3.12 × Linux/Windows — incl. the raw-sort divergence case and NFC key-collision rejection |
| 7 | FileNonceStore is not distributed replay protection | docs/NONCE_STORES.md — normative deployment matrix per store × topology; Redis single-strongly-consistent-authority requirements; eventually-consistent backends unsupported by design; safe multi-region patterns |
| 13 | optional registry_root conflates portability with state trust | protocol-level binding classes: every verdict carries EPOCH_BOUND / LOCAL; policy rule require_epoch_bound; passport weakest-link aggregation (EPOCH_BOUND/LOCAL/MIXED); dispute question IS_THE_PROOF_EPOCH_BOUND (document-intrinsic); CLI proof-export --epoch-bound & passport-create --require-epoch-bound |
| 17 | "Dispute Engine" risks overclaim | repositioned everywhere as a deterministic evidence adjudication layer — no quorum, no challenge periods, no arbitration market, no settlement |
| 18 | Policy engine simpler than its name | docs/POLICY_MODEL.md — v1 grammar table, evaluation order, monotone-narrowing guarantee, explicit non-goals (no AND/OR, no nesting, no delegation) |
| 19 | HMAC pseudonymization ≠ anonymity | SECURITY.md section: keyed tags are non-invertible outside the issuer but NOT unlinkable; per-app uid secrets are load-bearing |
Maturity honesty (#21)
docs/MATURITY.md: reference implementation ✅ · security-engineering prototype ✅ · production infrastructure ❌ — with a 12-row missing-evidence register and presentation language rules. Linked from the top of the README.
Verification
- 110/110 tests (7 new binding tests)
- attack suite 20/20 rejected
- canonical vectors 15/15 byte-exact in Node AND independent Python
- pure-Python Ed25519 cross-verify unchanged: 1 valid accepted, 20 attacks rejected
Full changelog: v0.12.0...v0.13.0