Skip to content

Commit e25e325

Browse files
committed
docs: worked example -- examples/complete_record/ with 8 real hash values
build.py computes all hashes from scratch. README.md walks through each primitive in narrative form: pack_hash, evidence_commitment, negative_proof_hash, dissent_hash (position-tamper-evident), context_reconstruction_hash, consensus_record_hash. All 8 hashes verified PASS against kernel output.
1 parent 6f2875a commit e25e325

2 files changed

Lines changed: 274 additions & 0 deletions

File tree

examples/complete_record/README.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# AIEP Complete Record — Worked Example
2+
3+
A self-contained walkthrough of a single AIEP decision cycle using the
4+
`aiep-genome-sdk` kernel. Every hash below is computed by running
5+
`python examples/complete_record/build.py` — you can verify any of them
6+
with `aiep-verify` or by reading the source.
7+
8+
---
9+
10+
## Scenario
11+
12+
A temperature sensor reads **72.4 °C**. The system activates a cooling
13+
response. The decision is recorded, committed, and is permanently
14+
machine-verifiable.
15+
16+
---
17+
18+
## 1 — Evidence Record
19+
20+
```json
21+
{
22+
"evidence_id": "00000000-0000-0000-0000-000000000001",
23+
"evidence_type": "structured_data",
24+
"content": "temperature_celsius=72.4",
25+
"collected_ts": "2026-01-01T00:00:00Z"
26+
}
27+
```
28+
29+
---
30+
31+
## 2 — Reasoning Entry
32+
33+
```json
34+
{
35+
"entry_hash": "727ccdd0e91a3783e4a32f920d57619100be76ada97c38a6f879ca85673f4c65",
36+
"kind": "ACTIVATION",
37+
"reasoning": "Temperature within safe operating range. No alert required.",
38+
"branch_id": "branch-001",
39+
"evidence_refs": ["00000000-0000-0000-0000-000000000001"]
40+
}
41+
```
42+
43+
`entry_hash` is `sha256_hex("entry-example-001")` — a stable identifier for
44+
this reasoning entry.
45+
46+
---
47+
48+
## 3 — Pack Hash (the core commitment)
49+
50+
`pack_hash(evidence_ledger, reasoning_ledger, schema_version_id)`
51+
52+
```
53+
a03f690109af14d6d70b6eac7e600e2a030ebac3558481e9ecd345b566827075
54+
```
55+
56+
This is the tamper-evident commitment to the complete decision. If any byte
57+
of the evidence or reasoning changes, this hash changes. Two nodes that
58+
independently receive the same evidence and produce the same reasoning
59+
**must** agree on this value.
60+
61+
---
62+
63+
## 4 — Evidence Commitment
64+
65+
`evidence_commitment(canonical_evidence, provenance, schema_version_id)`
66+
67+
```
68+
3a64b676a3fcf24b0c07e0e76147bc7303eba5ceac96b238b6ac048bb0183e7a
69+
```
70+
71+
A commitment to the evidence alone, independent of the reasoning. Useful
72+
for cross-referencing evidence across multiple decisions.
73+
74+
---
75+
76+
## 5 — Negative Proof (gap record)
77+
78+
During 01:00–02:00 UTC, no telemetry was received. The absence is recorded
79+
as a `negative_proof_hash`:
80+
81+
`negative_proof_hash("telemetry_reading", "2026-01-01T01:00:00Z", "2026-01-01T02:00:00Z", sv)`
82+
83+
```
84+
9c403f333a7dc45636074827ec52211ebb560f0c4ef7cefb1da68c30ea087bd1
85+
```
86+
87+
An absence that is recorded is not suppressed evidence — it is evidence of
88+
absence. A gap without a NegativeProofRecord is a protocol violation.
89+
90+
---
91+
92+
## 6 — Dissent (P27)
93+
94+
A second branch (`branch-002`) reviews the same evidence and disagrees.
95+
The dissent position is itself tamper-evident:
96+
97+
| Position | dissent_hash |
98+
|-----------|-------------|
99+
| `reject` | `841843ebd96db55a08d2677a012777732e3452e9b0178057c65207e587e7962b` |
100+
| `archive` | `4df2260cd54e9f2cc30deb78c880bc2265497a825047e8e302bf36f79a7bf67e` |
101+
102+
Changing `"reject"` to `"archive"` produces a different hash. The position
103+
cannot be silently changed after commitment.
104+
105+
---
106+
107+
## 7 — Context Reconstruction (P22)
108+
109+
`context_reconstruction_hash([pack_hash, negative_proof_hash], "sorted-asc", sv)`
110+
111+
```
112+
a848defef1e9dea0f8a4f082e8bc80640147be1db1eda143641cfe683f05d549
113+
```
114+
115+
Any node given the same set of artefact hashes (in any order) produces the
116+
same context reconstruction hash. Context cannot be selectively excluded.
117+
118+
---
119+
120+
## 8 — Consensus Record (P90)
121+
122+
`consensus_record_hash("branch-001", "HIGH", [pack_hash, negative_proof_hash], sv)`
123+
124+
```
125+
684bc397afb13583b7292db5a132cf26c8a40f9a7c8910b0fac6443d1799fbc4
126+
```
127+
128+
The swarm's consensus commitment. Order-independent: nodes that respond in
129+
different sequence produce the same hash.
130+
131+
---
132+
133+
## Running the example
134+
135+
```bash
136+
cd examples/complete_record
137+
python build.py
138+
```
139+
140+
All hashes are recomputed from scratch and printed. Compare with the values
141+
above — they must match exactly, on any machine, any OS, any Python version
142+
≥ 3.10.
143+
144+
```bash
145+
# Also verify the AIEP-VECTORS suite:
146+
aiep-verify --self-test
147+
aiep-verify --vectors path/to/AIEP-VECTORS/v1.1.0
148+
```

examples/complete_record/build.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env python3
2+
"""
3+
AIEP Complete Record — Worked Example Builder
4+
5+
Computes and prints every hash from the README, from scratch.
6+
Run from the genome-sdk root:
7+
8+
python examples/complete_record/build.py
9+
10+
All values should match the README exactly.
11+
"""
12+
from __future__ import annotations
13+
14+
import sys
15+
from pathlib import Path
16+
17+
ROOT = Path(__file__).parent.parent.parent
18+
sys.path.insert(0, str(ROOT / "src"))
19+
20+
try:
21+
from aiep_genome.kernel.canon import (
22+
canonical_json,
23+
sha256_hex,
24+
pack_hash,
25+
evidence_commitment,
26+
negative_proof_hash,
27+
dissent_hash,
28+
context_reconstruction_hash,
29+
consensus_record_hash,
30+
)
31+
except ImportError as exc:
32+
print(f"ERROR: Cannot import kernel: {exc}", file=sys.stderr)
33+
print("Install with: pip install -e .[dev] (from genome-sdk root)", file=sys.stderr)
34+
sys.exit(1)
35+
36+
SV = "aiep.canonical.v2.0.0"
37+
38+
# ── Fixtures ─────────────────────────────────────────────────────────────────
39+
40+
EVIDENCE = [
41+
{
42+
"evidence_id": "00000000-0000-0000-0000-000000000001",
43+
"evidence_type": "structured_data",
44+
"content": "temperature_celsius=72.4",
45+
"collected_ts": "2026-01-01T00:00:00Z",
46+
}
47+
]
48+
49+
ENTRY_HASH = sha256_hex("entry-example-001")
50+
51+
REASONING = [
52+
{
53+
"entry_hash": ENTRY_HASH,
54+
"kind": "ACTIVATION",
55+
"reasoning": "Temperature within safe operating range. No alert required.",
56+
"branch_id": "branch-001",
57+
"evidence_refs": ["00000000-0000-0000-0000-000000000001"],
58+
}
59+
]
60+
61+
# ── Compute ───────────────────────────────────────────────────────────────────
62+
63+
ph = pack_hash(EVIDENCE, REASONING, SV)
64+
ec = evidence_commitment(canonical_json(EVIDENCE), "lab/sensor/v1", SV)
65+
nph = negative_proof_hash(
66+
"telemetry_reading",
67+
"2026-01-01T01:00:00Z",
68+
"2026-01-01T02:00:00Z",
69+
SV,
70+
)
71+
dh_reject = dissent_hash("branch-002", ph, "reject", EVIDENCE, SV)
72+
dh_archive = dissent_hash("branch-002", ph, "archive", EVIDENCE, SV)
73+
crh = context_reconstruction_hash([ph, nph], "sorted-asc", SV)
74+
crec = consensus_record_hash("branch-001", "HIGH", [ph, nph], SV)
75+
76+
# ── Expected values (from README) ────────────────────────────────────────────
77+
78+
EXPECTED = {
79+
"entry_hash": "727ccdd0e91a3783e4a32f920d57619100be76ada97c38a6f879ca85673f4c65",
80+
"pack_hash": "a03f690109af14d6d70b6eac7e600e2a030ebac3558481e9ecd345b566827075",
81+
"evidence_commitment": "3a64b676a3fcf24b0c07e0e76147bc7303eba5ceac96b238b6ac048bb0183e7a",
82+
"negative_proof_hash": "9c403f333a7dc45636074827ec52211ebb560f0c4ef7cefb1da68c30ea087bd1",
83+
"dissent_hash_reject": "841843ebd96db55a08d2677a012777732e3452e9b0178057c65207e587e7962b",
84+
"dissent_hash_archive": "4df2260cd54e9f2cc30deb78c880bc2265497a825047e8e302bf36f79a7bf67e",
85+
"context_reconstruction": "a848defef1e9dea0f8a4f082e8bc80640147be1db1eda143641cfe683f05d549",
86+
"consensus_record": "684bc397afb13583b7292db5a132cf26c8a40f9a7c8910b0fac6443d1799fbc4",
87+
}
88+
89+
COMPUTED = {
90+
"entry_hash": ENTRY_HASH,
91+
"pack_hash": ph,
92+
"evidence_commitment": ec,
93+
"negative_proof_hash": nph,
94+
"dissent_hash_reject": dh_reject,
95+
"dissent_hash_archive": dh_archive,
96+
"context_reconstruction": crh,
97+
"consensus_record": crec,
98+
}
99+
100+
# ── Report ────────────────────────────────────────────────────────────────────
101+
102+
failures = []
103+
print()
104+
print("AIEP Complete Record -- Worked Example")
105+
print(f" schema_version_id: {SV}")
106+
print()
107+
108+
for name, computed in COMPUTED.items():
109+
expected = EXPECTED[name]
110+
status = "PASS" if computed == expected else "FAIL"
111+
label = f"{name:<26}"
112+
if status == "PASS":
113+
print(f" {status} {label} {computed[:20]}...{computed[-8:]}")
114+
else:
115+
failures.append(name)
116+
print(f" {status} {label}")
117+
print(f" computed: {computed}")
118+
print(f" expected: {expected}")
119+
120+
print()
121+
if failures:
122+
print(f" {len(failures)} FAILURES -- canon divergence detected")
123+
sys.exit(1)
124+
else:
125+
print(f" All {len(COMPUTED)} hashes match -- canon is deterministic")
126+
print()

0 commit comments

Comments
 (0)