README.md
9.4 KB · 208 lines · markdown Raw
1 # pqc-reasoning-ledger
2
3 ![PQC Native](https://img.shields.io/badge/PQC-Native-6b21a8)
4 ![ML-DSA-65](https://img.shields.io/badge/Signature-ML--DSA--65-0ea5e9)
5 ![SHA3-256](https://img.shields.io/badge/Hash-SHA3--256-22c55e)
6 ![Merkle](https://img.shields.io/badge/Proofs-Merkle-f59e0b)
7 ![License](https://img.shields.io/badge/license-Apache%202.0-blue)
8 ![Version](https://img.shields.io/badge/version-0.1.0-7c3aed)
9
10 **PQC-signed neurosymbolic reasoning ledger.** Sign chain-of-thought steps in real time
11 during AI inference. Produces legally defensible, quantum-safe reasoning trails for
12 regulated industries where the reasoning chain itself must survive a decade of
13 adversarial review.
14
15 As AI is used for high-stakes reasoning (legal analysis, medical diagnosis, financial
16 risk, regulatory decisions), courts and regulators are asking *"how did the model reach
17 this conclusion?"* This library records every step of the model's thought process as a
18 hash-chained, Merkle-rooted, ML-DSA-65 signed **reasoning trace** that is tamper-evident
19 end-to-end and verifiable by third parties without any trust in the original recorder.
20
21 ## Install
22
23 ```bash
24 pip install pqc-reasoning-ledger
25 ```
26
27 ## Quick start
28
29 ```python
30 from quantumshield.identity.agent import AgentIdentity
31 from pqc_reasoning_ledger import ReasoningRecorder, TraceVerifier
32
33 identity = AgentIdentity.create("legal-advisor-signer")
34 rec = ReasoningRecorder(identity)
35 rec.begin_trace(
36 model_did="did:pqaid:gpt-legal",
37 model_version="2.1",
38 task="contract-review",
39 domain="legal",
40 )
41
42 rec.record_observation("Contract contains a liquidated damages clause capping at $1M.")
43 rec.record_retrieval("NY CPLR 3215; Truck Rent-A-Center v. Puritan Farms 2nd (1977).")
44 rec.record_hypothesis("Clause is likely enforceable if sum is reasonable relative to harm.")
45 rec.record_deduction("Given $1M cap and projected $1.2M harm, clause is reasonable.")
46 rec.record_self_critique("Should also check whether plaintiff must mitigate damages.")
47 rec.record_decision("Recommend signing with carve-out for force-majeure events.")
48
49 sealed = rec.seal()
50
51 # External verifier, days or years later:
52 result = TraceVerifier.verify(sealed)
53 assert result.fully_verified
54 ```
55
56 The `sealed` value is a self-contained, post-quantum-signed proof of the *exact sequence
57 of reasoning steps* the model took. Altering any step, adding a step, dropping a step,
58 reordering steps, or forging the signature will all cause `TraceVerifier.verify()` to
59 return `valid=False` with a specific error string.
60
61 ## Architecture
62
63 ```
64 +---------------------+ record_* +---------------------+
65 | Model inference | -------------> | ReasoningRecorder |
66 | (chain-of-thought)| | |
67 +---------------------+ | ReasoningTrace |
68 | step_1 --+ |
69 | step_2 --+ hash |
70 | step_3 --+ chain |
71 | ... |
72 +---------+-----------+
73 | seal()
74 v
75 +----------------+-----------------+
76 | SealedTrace |
77 | final_chain_hash |
78 | merkle_root (over step_hashes) |
79 | ML-DSA-65 signature |
80 | signer public key |
81 +----------------+-----------------+
82 | transport / archive
83 v
84 +----------------+-----------------+
85 | TraceVerifier (independent) |
86 | 1. chain integrity |
87 | 2. merkle root |
88 | 3. ML-DSA signature |
89 +----------------------------------+
90 |
91 v
92 fully_verified: True / False
93 ```
94
95 Each step records `SHA3-256(previous_step_hash || canonical_bytes(step))`, so tampering
96 with any intermediate step breaks every downstream hash. The `merkle_root` over step
97 hashes enables **selective disclosure**: you can prove a single step was in the trace
98 (e.g. "the model considered case law X") via `ReasoningProver.prove_step()` without
99 revealing the other steps.
100
101 ## Step kinds
102
103 The symbolic vocabulary for reasoning steps (`StepKind`):
104
105 | Kind | Meaning |
106 | --- | --- |
107 | `thought` | Free-form reasoning statement |
108 | `observation` | Observation about input or retrieved data |
109 | `hypothesis` | A tentative conclusion to evaluate |
110 | `deduction` | Logical deduction from prior steps |
111 | `retrieval` | Fetching external knowledge (RAG, memory, citation) |
112 | `tool-call` | Calling an external tool or function |
113 | `tool-result` | Result returned by a tool call |
114 | `self-critique` | Model critiquing its own prior step |
115 | `refinement` | Updated answer after critique |
116 | `decision` | Final decision or answer |
117 | `meta` | Metadata about the run itself |
118
119 ## Cryptography
120
121 | Layer | Primitive |
122 | --- | --- |
123 | Content hash | SHA3-256 of UTF-8 step text |
124 | Step hash | SHA3-256( previous_step_hash \|\| canonical_json(step_payload) ) |
125 | Merkle tree | SHA3-256 with RFC6962-style domain separation (0x00 leaves, 0x01 internal) |
126 | Trace seal signature | ML-DSA-65 (NIST FIPS 204) over SHA3-256 of sealed canonical bytes |
127 | Identity | Quantumshield `AgentIdentity` + DID (`did:pqaid:...`) |
128
129 All signatures are produced via `quantumshield.core.signatures.sign` and verify via
130 `quantumshield.core.signatures.verify`, so the verification path has no dependency on
131 the original signer process.
132
133 ## Threat model
134
135 | Attack | Detected by |
136 | --- | --- |
137 | Retroactive edit of an intermediate step | Chain check: step hash and all downstream hashes break |
138 | Swapped step at position k | Chain check: previous_step_hash at k+1 no longer matches |
139 | Inserted step | Chain check: step_number off by one; step_hash invalid |
140 | Dropped step | `final_chain_hash`, Merkle root, and signature all mismatch |
141 | Re-ordered steps | Chain check fails; Merkle root fails |
142 | Forged ML-DSA signature | ML-DSA-65 verify fails (PQ-secure) |
143 | Substituted public key | Signature still has to verify against attached key, but the DID is bound in the signed payload and independent public-key-infrastructure should be consulted for signer provenance |
144
145 What is **not** in scope: confidentiality of reasoning steps (this library is about
146 integrity, not secrecy - encrypt separately if needed), and mitigations against a
147 compromised signer (rotate and revoke via your identity infrastructure).
148
149 ## API reference
150
151 ### `ReasoningRecorder(identity: AgentIdentity)`
152
153 - `begin_trace(model_did, model_version, task="", actor_did="", session_id="", domain="")`
154 - `record(kind, content, references=None, confidence=1.0, metadata=None)`
155 - `record_thought(content, **kw)` / `record_observation` / `record_hypothesis`
156 / `record_deduction` / `record_retrieval` / `record_tool_call` / `record_tool_result`
157 / `record_self_critique` / `record_refinement` / `record_decision`
158 - `seal() -> SealedTrace`
159
160 ### `ReasoningTrace`
161
162 - `metadata: TraceMetadata`, `steps: list[ReasoningStep]`, `sealed: bool`
163 - `current_hash -> str` (chain-tip hash)
164 - `append(step)` - raises `ChainBrokenError` / `TraceSealedError` on violation
165 - `to_dict() -> dict`
166
167 ### `SealedTrace`
168
169 - Dataclass with `metadata`, `steps`, `final_chain_hash`, `merkle_root`, `step_count`,
170 `sealed_at`, `signer_did`, `algorithm`, `signature`, `public_key`
171 - `to_dict()` / `to_json()` / `from_dict()` / `from_json()`
172 - `canonical_bytes() -> bytes` (deterministic payload that is signed)
173
174 ### `TraceVerifier`
175
176 - `verify(sealed) -> VerificationResult` with `valid`, `signature_valid`,
177 `chain_intact`, `merkle_root_valid`, `step_count`, `error`, and `fully_verified`
178 - `verify_or_raise(sealed)` - raises `SignatureVerificationError` on failure
179
180 ### `ReasoningProver`
181
182 - `prove_step(sealed, step_id) -> StepInclusionProof`
183 - `verify_proof(proof) -> bool`
184
185 ## Why PQC for reasoning trails
186
187 AI liability law is accelerating. The EU AI Act, NYC Local Law 144, the FDA's AI/ML
188 Software Pre-Cert guidance, and state-level medical and insurance rules all push toward
189 **retrospective explainability of AI decisions**. A signed reasoning trace has to remain
190 verifiable for the full litigation horizon - often 6-10+ years - which is well inside
191 the timeline where cryptographically relevant quantum computers become a risk to
192 classical-signature archives. ML-DSA-65 is NIST-standardized (FIPS 204) and provides
193 integrity guarantees that outlive the archival window, without requiring re-signing
194 the corpus under a new algorithm.
195
196 This library is **ahead of the curve**: the reasoning trails it produces today will
197 still be defensible evidence when quantum-capable adversaries exist.
198
199 ## Examples
200
201 - `examples/legal_contract_review.py` - 6-step legal reasoning trace
202 - `examples/medical_diagnosis.py` - 7-step medical reasoning with inclusion proof
203 - `examples/tamper_detection.py` - demonstrate detection of a flipped byte
204
205 ## License
206
207 Apache 2.0 - see `LICENSE`.
208