`crisis-agents demo --live` swaps the three honest MockAgents for
LiveClaudeAgent instances that issue one Anthropic Messages API call
per turn. The byzantine joiner stays mocked: making the byzantine
deterministic with an LLM would require multiple API calls per turn
(one per peer subset) for unreliable yields. Better demo legibility
to keep the equivocator scripted.
Prompt shape: the honest agent receives the reference doc, a list of
statements still to adjudicate, and the last 12 claims observed from
peers; it responds with a JSON array of {statement_id, verdict,
confidence, evidence} objects. The parser tolerates markdown fences
and per-item validation failures; malformed responses produce no
emissions rather than crashing the demo.
Default model: claude-haiku-4-5-20251001 — fast enough and cheap
enough for short-form structured-output adjudication. Override with
`--model <id>`.
Dependency: anthropic SDK as an optional install — `pip install -e
".[live]"`. Lazy-imported so the mocked path never needs it.
Tests: 6 new tests in test_live_agent.py using a fake Anthropic client
(no real API calls in CI):
- clean JSON response parsing
- markdown-fence tolerance
- malformed-response graceful degradation
- per-item validation skipping
- already-adjudicated statement filtering (the agent doesn't keep
re-asking about statements it has already answered)
- evidence-length truncation to Claim.EVIDENCE_MAX_LEN
Suite: 145 -> 150 tests, all green in 0.77s.
Manual test (not in CI; requires API credits):
pip install -e ".[live]"
export ANTHROPIC_API_KEY=...
crisis-agents demo --live
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
A new sibling Python package, `crisis_agents`, that lifts the Crisis
protocol from "consensus between machines" to "consensus between AI
agents". Threat model: a team of sub-agents normally talks freely
with its orchestrator (the "mothership"); when the team's boundary
opens and an external agent of unknown trust joins, the mothership
activates the Crisis layer so byzantine equivocation is detectable.
Two-phase orchestration model:
Phase 1 — closed team, no Crisis: agents emit claims directly, the
mothership collects them flat.
Phase 2 — boundary opens: every subsequent claim is wrapped into a
Crisis Message with the agent's stable process_id and a PoW nonce,
delivered into per-agent LamportGraphs, and after each turn the
mothership scans for mutations via LamportGraph.find_mutations.
Phase 3 — proof: when an alarm fires, the mothership emits a
replayable JSON proof-of-malfeasance document with the contradictory
witnesses, their delivery sets, and DAG cross-references showing
which honest agents saw what.
Modules:
- claim.py Claim dataclass + JSON round-trip
- boundary.py membership tracker + open() trigger
- agent.py CrisisAgent abstract + MockAgent + MockByzantineAgent
(the latter equivocates by emitting two variants to
disjoint peer subsets at the same logical turn)
- mothership.py orchestrator driving both phases, building Crisis
Messages from Claims, per-agent LamportGraphs, log
- alarm.py scan_for_mutations: same-agent same-turn distinct
digests with non-identical delivery sets, verified
spacelike via LamportGraph.are_spacelike on the
honest-agent graphs
- proof.py build_proof + ProofDocument + JSON serializer +
verify_proof_self_consistent
- cli.py `crisis-agents demo` + `crisis-agents verify`
- scenarios/ fact_check: reference doc + 6 statements + scripted
honest/byzantine agents producing a deterministic
equivocation on statement s03
Tests: 50 new tests across test_claim, test_boundary, test_mothership,
test_alarm, test_proof, test_demo_fact_check. End-to-end test runs the
fact_check scenario, asserts exactly one alarm raised, proof is built,
re-serialized JSON passes self-consistency. Full suite (existing
crisis + new crisis_agents) green in 0.77s — 145 tests.
Out of scope (deliberately): visualization (separate CrisisViz upgrade
later), real TCP gossip (agents talk via in-process function calls in
the mothership), false-claim detection without equivocation (an
agent that consistently lies but never equivocates is out-voted, not
"caught"; catching it would require a ground-truth oracle).
Reuse from existing crisis package: Message, Vertex, LamportGraph,
LamportGraph.find_mutations, ProofOfWorkWeight, digest. The new code
is a thin adapter layer; the protocol substrate did the heavy lifting.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pre-existing tests covered crypto / graph / message / order / rounds /
weight, but left three high-value modules unverified:
- voting.py — 25 KB of BBA virtual leader election + safe voting
pattern (Algorithms 6 & 7), the heart of the protocol. Zero
tests. Now 14 tests covering the four public entry points
(`build_knowledge_graph`, `select_quorum`, `voting_set`,
`compute_safe_voting_pattern`, `compute_virtual_leader_election`)
plus `initial_vote`. Uses a small in-process Simulation to
produce realistic multi-round graphs.
- recorder.py — the bridge that turns simulation runs into the
JSON consumed by CrisisViz. Zero tests despite being the choke
point: if recorder silently drops fields, the viz lies. Now 11
tests covering EventRecorder bookkeeping (sequence, filtering),
SimulationRecording integration (STEP_BEGIN/END,
MESSAGE_CREATED/DELIVERED), capture_snapshot well-formedness,
and JSON-serializability of both snapshots and event data.
- test_simulation.py extended with three regression guards:
- test_byzantine_vertices_flagged_in_snapshots: ensures the
`is_byzantine_source` flag survives the recorder pipeline.
CrisisViz's Ch10 (byzantine) chapter relies on this to
colour Dave's lane red.
- test_recorder_deterministic_with_seed: same seed produces
identical event-stream length and type ordering. Tightens
the existing vertex-count determinism check.
- test_consensus_pipeline_progresses: a fast claim that rounds
advance past 0 and the SVP / voting code paths engage. The
stronger claim (full convergence + non-empty total order)
takes minutes in pure Python and belongs in a separate
long-running benchmark, not the unit-test suite — but the
weaker claim is sufficient to catch the dead-pipeline
failure mode that motivated regenerating crisis_data.json
on 2026-05-04.
Suite: 72 -> 100 tests, all green in ~0.75s.
Explicitly out of scope (separate engineering effort):
- gossip.py / node.py TCP integration tests — heavy harness;
- export_json.py — thin composition of tested layers;
- Swift XCTest — the CrisisViz testbed harness already covers
the curriculum-correctness layer.
Co-Authored-By: Claude Opus 4.7 <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>