diff --git a/README.md b/README.md
index 33920b2..3d63a47 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,156 @@
# crisis
-A proof-of-concept and educational artifact for Mirco Richter's [_Crisis_ paper](Crisis.mirco-richter-2019.pdf) — a DAG-based BFT consensus protocol with a data-availability layer.
+A proof-of-concept and educational artifact for Mirco Richter's [_Crisis_ paper](Crisis.mirco-richter-2019.pdf) — a DAG-based BFT consensus protocol that achieves total order on messages in fully open, unstructured peer-to-peer networks through **virtual voting**: votes are never sent explicitly but are deduced from the causal relationships encoded in Lamport graphs.
-This repo contains:
+This repository contains:
-- a small **Go PoC** of the protocol (`src/`, `tests/`),
-- a **Python recorder** that exports a simulation run to JSON (`pyproject.toml`),
-- **CrisisViz** — a native macOS / SwiftUI curriculum visualizer that walks the protocol end to end across ten chapters: cast intro, gossip mechanics, partition, round derivation, virtual voting, leader election, total order, the data-availability problem, erasure-coded recovery, and Byzantine fork detection.
+- a **Python implementation** of the protocol (`src/`, `tests/`),
+- an **event recorder** that exports a deterministic simulation run to JSON,
+- **CrisisViz** — a native macOS / SwiftUI curriculum visualizer that walks the protocol end-to-end across ten chapters: cast intro, gossip mechanics, partition, round derivation, virtual voting, leader election, total order, the data-availability problem, erasure-coded recovery, and Byzantine fork detection.
-Everything is in extreme slow motion and serialized for didactic clarity. A signed speed slider scrubs the chapter forward and backward at any rate from −16× to +16×; narration in the overlay is bound to whichever beat the playhead is on.
+Everything in the visualizer is in extreme slow motion and serialized for didactic clarity. A signed speed slider scrubs the chapter forward and backward at any rate from $-16\times$ to $+16\times$; narration is bound to whichever beat the playhead is on.
-Build:
+---
+
+## Architecture at a glance
+
+```mermaid
+flowchart TD
+ Paper["📄 Paper — the spec
Crisis.mirco-richter-2019.pdf"]
+ Paper --> Algos
+
+ subgraph Algos["🧮 Pure protocol algorithms — src/crisis/"]
+ direction LR
+ Crypto["crypto.py"]
+ Msg["message.py"]
+ Graph["graph.py"]
+ Weight["weight.py"]
+ Rounds["rounds.py"]
+ Voting["voting.py"]
+ Order["order.py"]
+ end
+
+ Algos --> RealRT
+ Algos --> SimRT
+
+ subgraph RealRT["🌐 Real runtime — node.py + gossip.py
scalable, deployable"]
+ Node["CrisisNode
asyncio · TCP push/pull gossip
3 concurrent loops
CLI: crisis-node"]
+ end
+
+ subgraph SimRT["🧪 In-process toy runtime — demo.py
deterministic, recordable"]
+ SimNode["SimulatedNode
direct in-memory message passing
NetworkParams: delays / drops / silences"]
+ SimCtl["Simulation controller
spins up N honest + K byzantine
CLI: crisis-demo"]
+ SimNode --- SimCtl
+ end
+
+ SimRT --> Rec
+ Rec["📼 Recorder — recorder.py
instruments every algorithm call
captures events + per-step snapshots"]
+ Rec --> Export
+ Export["📦 JSON exporter — export_json.py
writes crisis_data.json"]
+ Export --> Viz
+
+ subgraph Viz["🎬 CrisisViz — native macOS / SwiftUI"]
+ Player["Keynote-style player
10 chapters · ~18 min @ 1×
scrubbable −16× to +16×"]
+ Testbed["Testbed harness
invariants · source audit
PNG sweep · 36 MP4 clips"]
+ end
+
+ classDef paper fill:#fdf6e3,stroke:#586e75,color:#073642
+ classDef pure fill:#eee8d5,stroke:#586e75,color:#073642
+ classDef real fill:#fce5cd,stroke:#cc4125,color:#660000
+ classDef sim fill:#d9ead3,stroke:#38761d,color:#0b3d0b
+ classDef rec fill:#cfe2f3,stroke:#2c5f8f,color:#062b4d
+ classDef viz fill:#ead1dc,stroke:#741b47,color:#3d0a26
+ class Paper paper
+ class Algos pure
+ class RealRT real
+ class SimRT sim
+ class Rec,Export rec
+ class Viz viz
+```
+
+**Key architectural fact** — the recording pipeline that feeds CrisisViz only exercises the **`SimulatedNode`** path (in-process, deterministic, in-memory message passing). The **`CrisisNode`** TCP runtime is a separately developed PoC of how a real network deployment would look; it is _not_ what produces `crisis_data.json`. The two runtimes are siblings, not layers.
+
+---
+
+## Repository layout
+
+```
+crisis/ ← git root
+├── Crisis.mirco-richter-2019.pdf the paper
+├── README.md this file
+├── INSTALL.md fresh-macOS install guide
+├── LICENSE MIT (code only; paper is CC-BY-4.0)
+├── pyproject.toml Python ≥3.11, networkx, pytest
+├── crisis_data.json simulation export (source of truth)
+│
+├── src/crisis/ ── PROTOCOL PoC (Python) ──
+│ ├── crypto.py, message.py random-oracle hash + Message/Vertex
+│ ├── graph.py, weight.py, rounds.py Lamport DAG + PoW weight + round derivation
+│ ├── voting.py, order.py BBA virtual voting + total order
+│ ├── gossip.py, node.py real TCP runtime (CrisisNode)
+│ ├── demo.py in-process simulation harness
+│ ├── recorder.py event instrumentation
+│ └── export_json.py JSON exporter for CrisisViz
+├── tests/ pytest suite
+│
+└── CrisisViz/ ── VISUALIZER (Swift / macOS 26) ──
+ ├── Package.swift, bundle.sh, package-dmg.sh
+ ├── Sources/CrisisViz/ App, Engine, Model, Chapters, Views, Glass, Testbed, Canvas
+ ├── README.md Swift-side human guide
+ └── HANDOFF.md agent-to-agent engineering log
+```
+
+---
+
+## Quick start
+
+There are three audiences. Pick the one that matches what you want to do.
+
+### 🧮 Verify the protocol — pytest
+
+```sh
+cd crisis
+source .venv/bin/activate # set up per INSTALL.md if first time
+pytest -q
+```
+
+Runs the algorithm unit tests (crypto, graph, rounds, weight, message, order, voting, recorder, simulation). Should be green in under a second.
+
+### 🧪 Run a deterministic simulation — Python CLI
+
+```sh
+python -m crisis.demo --nodes 4 --byzantine 1 --rounds 10
+```
+
+Spins up four honest + one byzantine `SimulatedNode`, runs ten consensus rounds in-process with a deterministic seed, prints the resulting total order. To export a fresh `crisis_data.json` for CrisisViz:
+
+```sh
+python -m crisis.export_json --steps 80 -o crisis_data.json
+cp crisis_data.json CrisisViz/Sources/CrisisViz/crisis_data.json
+```
+
+### 🎬 Watch the visualizer — Swift / macOS
```sh
cd CrisisViz
-swift build # dev binary
-./bundle.sh # produce CrisisViz.app + open
-swift run CrisisViz --testbed # PNG sweep + invariant + MP4 harness
+./bundle.sh # builds CrisisViz.app and opens it
+# or:
+./package-dmg.sh # builds CrisisViz.dmg for distribution
```
-The viewer is the master of time. Pull the slider.
+Then arrow keys ←/→ to navigate, **Space** to play/pause, the bottom slider to scrub at any signed speed from $-16\times$ to $+16\times$.
+
+---
+
+## Where to read next
+
+- **[INSTALL.md](INSTALL.md)** — clone-to-running on a fresh macOS box. Prerequisites, Python venv setup, Swift toolchain, regenerating sim data, troubleshooting.
+- **[CrisisViz/README.md](CrisisViz/README.md)** — Swift-side guide: serial-timeline pattern, testbed outputs, controls, cast convention.
+- **[CrisisViz/HANDOFF.md](CrisisViz/HANDOFF.md)** — engineering log for the next coding agent: current state, architecture pointers, hard-won rules.
+
+---
+
+## License
+
+- **Code** (`src/`, `tests/`, `CrisisViz/`) is licensed under the [MIT License](LICENSE).
+- **Paper** (`Crisis.mirco-richter-2019.pdf`) by Mirco Richter is a separately licensed artifact under CC-BY-4.0.