- bundle.sh assembles CrisisViz.app (Info.plist + AppIcon.icns + resources)
and ad-hoc codesigns it so it launches as a proper Foreground app.
- Tools/MakeAppIcon.swift renders the app icon programmatically (10 sizes,
16-1024 px) as a 3-round mini-DAG matching the live node palette.
- CrisisApp.swift forces .regular activation policy via NSApplicationDelegate
so the Dock tile and menu bar appear even when launched unbundled
via `swift run CrisisViz`.
- Ignore build artifacts (.build, AppIcon.iconset, CrisisViz.app) and the
user-local .claude/ auto-memory directory.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Keynote-style presentation of the Crisis consensus protocol — 36 scenes
across 10 chapters, single-TimelineView Canvas rendering at 60fps with
Liquid Glass chrome. Driven by the simulation JSON dump.
The signature feature is the click-to-inspect overlay on Ch02: tapping a
vertex opens a recursive hash-unwrapping animation that reveals the
selected message's payload, then its parent hashes, then their pre-images
(parent messages with their own payloads + grandparent hashes), staggered
through to genesis. Makes the abstract idea of "what does a vertex know?"
visceral.
Includes a time-scrubbing testbed harness (`swift run CrisisViz --testbed`)
that captures 180 scene PNGs + 18 inspector reveal PNGs at successive time
offsets, with a MANIFEST quality checklist for human-eye verification.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The simulation now optionally records structured events (message creation,
delivery, round computation, voting, leader election) via EventRecorder and
exports a complete simulation dump to JSON via the new export_json module.
crisis_data.json captures a 10-step run that the SwiftUI visualizer consumes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Five bugs prevented the full consensus pipeline from producing results:
1. k-reachability with k=0 required weight > 0, but some vertices had
weight 0. Fixed: k <= 0 degenerates to simple past-containment check.
2. SVP incorrectly included the current round (v.round). The paper's
Algorithm 6 only includes rounds strictly < v.round. With the current
round in SVP, the voting set contained only the vertex itself (peers
are spacelike), making agreement impossible.
3. Stage delta (δ) was computed as the SVP index, but the paper defines
δ = d_{svp}(s, t) as distance from s=max(svp). Fixed: δ=0 at the
newest round (initial proposal), increasing toward older rounds.
4. The voting set was recomputed per-round, but Algorithm 7 line 6
computes it ONCE for s=max(svp). Fixed: single voting set S shared
across all stages.
5. Demo parameters (difficulty=2, pow_zeros=0) made thresholds
unreachable. Calibrated: difficulty=1, pow_zeros=2 gives weights
that cross both the is_last (3*d) and SVP (6*d) thresholds.
Result: 3 honest nodes now converge on identical total order. Leaders
are elected via the full BA* pipeline (initial proposal → presorting →
gradecast → BBA binary agreement). Byzantine nodes cannot prevent
convergence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete Python PoC of "Probabilistically Self Organizing Total Order
in Unstructured P2P Networks". Implements all 10 algorithms from the paper:
message generation, integrity checks, Lamport graphs, virtual synchronous
rounds, safe voting patterns, virtual leader election (BA*), longest chain
rule, total order via Kahn's algorithm, and push/pull gossip.
Includes simulation harness, full node binary, and 72 passing tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>