R89.C — θ Phase 3 Staging — Audit

Purpose: Inventory the spec surface that the Phase 3 θ Consensus prompt file must cover. This is the Step 1 artefact of the 5-step chain for the R89.C staging task (β 4f718f92-12d7-4176-a3c6-3682ba27aef9).

Scope: documentation / planning only. No src/ deltas.

Sources read in full:

  • docs/spec/s06-consensus.md (60 lines) — authoritative BFT spec
  • docs/spec/s08-gossip.md (115 lines) — IHAVE/IWANT, Bloom, fanout, STA
  • docs/architecture/decisions/ADR-002-vrf-implementation.md (102 lines) — VRF library decision
  • docs/architecture/decisions/ADR-003-bft-library.md (119 lines) — BFT library decision
  • docs/3-world/physics/laws/consensus.md (217 lines) — concept doc with worked example, equivocation proof, view-change pseudocode
  • docs/guides/implementation/task-breakdown.md §Phase 3 (lines 864–967) — 7-task canonical breakdown
  • docs/5-time/roadmap.md §Phase 3 (lines 349–417) — R121+ scheduling, tools, definition of done
  • docs/guides/implementation/task-prompts/p1.1-kappa-rule-engine.md (2944 lines) — REFERENCE STRUCTURE for the per-task entry shape

Base SHA: fab4bf57 (main).


1. Greek-letter context

θ is the consensus axis. It bridges η (“one process wrote something”) and the legitimacy axis (“the network agrees it happened”). Its activation requires multi-arbiter operation, which is out of scope until Phase 1.5 multi-model at the earliest and is roadmap-targeted at R121+.

θ has declared dependencies on:

  • κ Rule Engine (Phase 1, closed R87) — rule_version_hash is part of every vote tuple (round_id, merkle_root, rule_version_hash). Equivocation detection uses canonical-serialized vote payloads, which are produced via P1.5.4 canonical serialization. The version-hash itself is produced by P1.5.1.
  • η Proof Store (Phase 0, closed R75 Wave I) — the merkle_root voted upon is η’s output.
  • λ Reputation (Phase 2, in flight at staging time) — equivocation penalty (hard scar, weight −10, arbitration domain) is applied by the λ reputation engine. The s04-reputation spec is referenced from s06.
  • ζ Decision Trail (Phase 0, closed) — view-change rotations emit VIEW_CHANGE_ACCEPTED events into ζ for audit reconstruction.

θ has declared downstream consumers:

  • ι State Fork (Phase 5) — graceful divergence path when θ cannot reach quorum. Phase 3 θ must expose hook points so ι can subscribe to fork triggers.
  • π Governance (Phase 6) — may cap an equivocating arbiter’s voting weight or suspend them.
  • μ Integrity Monitor (Phase 4) — observes consensus traces for axiom drift.

2. Surface inventory — what θ exposes

2.1 Concepts the spec describes

Concept Spec citation Phase 3 deliverable
Quorum formula floor(2n/3)+1; f = floor((n-1)/3) s06 §Quorum, consensus.md §Quorum formula + worked table Quorum computation module
5 finality levels (PENDING / SOFT / QUORUM / HARD / ABSOLUTE) s06 §Finality levels, consensus.md §Five finality levels Finality state machine
Vote tuple (round_id, merkle_root, rule_version_hash) consensus.md §What the arbiters vote on Vote message types
Commit-reveal voting protocol consensus.md §Voting protocol Round + view state machine
T_round = 30s, T_commit_phase = 10s, T_reveal_phase = 10s, T_timeout = 60s consensus.md §Voting protocol constants Round timer / governable via π
Aggregate signatures into threshold signature σ consensus.md §Voting protocol Phase C Vote aggregation module
Equivocation proof structure (JSON shape) consensus.md §Equivocation proof structure Equivocation detector
View-change procedure (timeout / equivocation_observed / malformed_proposal) consensus.md §View-change procedure View-change handler
VRF leader selection from (prev_merkle_root, round_id) consensus.md §View-change procedure, ADR-002 VRF stub library
Gossip envelope (COMMIT / REVEAL / VIEW_CHANGE / EQUIVOCATION_PROOF) consensus.md §Gossip message envelope, s08 Gossip wire format module
IHAVE / IWANT + triple-anchor validation s08 §IHAVE/IWANT + §Triple-Anchor validation Gossip protocol module
Bloom filter for dedup (p < 1%) s08 §Bloom filter algorithm Gossip dedup module
Adaptive fanout max(3, min(10, 15 − connectivity_score)) s08 §Adaptive fanout Gossip fanout module
Signed Time Anchors (STA) s06 §Signed time anchors, s08 §STA Time anchor module
Schema mcp_consensus_votes consensus.md §Phase 0 posture DB migration

2.2 Concepts roadmap.md names

From docs/5-time/roadmap.md §Phase 3 (lines 359–401):

  • src/consensus/voting.ts — QuorumCalculator, equivocation detection
  • src/consensus/finality.ts — 5 finality levels, FinalityVote
  • src/consensus/gossip.ts — Bloom filter, adaptive fanout, Triple-Anchor
  • src/consensus/time-anchors.ts — signed timestamps, median clock
  • src/consensus/vrf.ts — VRF proof for arbiter rotation
  • src/consensus/tools.ts — consensus MCP tools

Named MCP tools (4):

  • consensus_propose — propose an event
  • consensus_vote — sign a vote
  • consensus_finality — query finality level
  • consensus_gossip — exchange state with peer nodes

These are roadmap.md’s surface; the prompt file may refine names (e.g. vrf_eval for direct VRF access, parity harness tool) based on spec reading.

2.3 Concepts task-breakdown.md names (7 canonical sub-tasks)

ID Title Effort Depends on
P3.1.1 Vote Message Types M P1.4.1
P3.1.2 Quorum Computation M P3.1.1
P3.1.3 View Change Protocol L P3.1.2
P3.2.1 Finality State Machine L P3.1.2
P3.3.1 IHAVE/IWANT Messages L P3.1.1
P3.4.1 Signed Timestamps M P3.1.1, P2.1.1
P3.5.1 Equivocation Enforcement M P3.1.2, P2.2.2

Note on the dispatch’s “12–15 entries” target vs the 7-task canonical: κ exhibited the same pattern (10 → 20 sub-tasks via granularity refinement during R76.P1). The 7 canonical tasks above are coarse — e.g. P3.1.1 “Vote Message Types” rolls Ed25519 signing, canonical JSON serialization, and the full envelope into a single L bucket. The prompt file should split these where it makes scoped-PR sense (kappa precedent: per-file or per-concern splits) while keeping the canonical mapping documented. Decision: target ~13 entries by splitting BFT voting (3→4), adding VRF as its own slice (was bundled into view-change), giving gossip Bloom and fanout their own slices (3→3 stays), and adding a parity harness mirroring P1.5.5.

3. ADR status flags

3.1 ADR-002 (VRF) — PROPOSED

Status quoted from file: **Status:** PROPOSED (line 11).

Decision text (line 36): **TBD — requires PM decision.**

This means the prompt file MUST either:

  • (a) ship the VRF slice as a stub (constant-output, deterministic, fast) pending PM decision — analogous to how P0.5.1 shipped a stub for δ per ADR-005, with the proper interface so swapping in Option A or B is purely internal, OR
  • (b) defer the VRF slice entirely and flag that θ cannot dispatch its view-change / leader-election sub-tasks until ADR-002 is Accepted.

Recommendation in the prompt file’s intro: option (a) — ship VRF as a HMAC-SHA256 stub (Option A path) with a clear comment that the swap to Option B (@noble/curves) is gated on ADR-002 acceptance. This mirrors the κ discipline of shipping libraries with stub-quality semantics while the wire shape is final.

3.2 ADR-003 (BFT library) — PROPOSED

Status quoted from file: **Status:** PROPOSED (line 11).

Decision text (line 29): **TBD — requires PM decision.**

ADR-003 names three options:

  • Option A — Build BFT from scratch (~5–6 weeks, full control)
  • Option B — Build on libp2p (@libp2p/libp2p + GossipSub, ~5–7 weeks total)
  • Option C — Two-phase approach (2-week spike on the BFT state machine alone, then Option A or B decision with real code evidence)

The ADR explicitly recommends Option C (line 87: “This is the recommended approach per MASTER-TASKS.md”).

Prompt file response: the BFT-state-machine half of the surface (voting, quorum, view-change, finality, equivocation) is independent of the network transport choice. The prompt file can stage ALL state-machine slices safely under the Option C interpretation — they’re the “Phase 3a spike” content. The gossip transport slices (P3.3.x) MUST be flagged: their executor prompt should say “blocked on ADR-003 acceptance OR Option C spike completion”.

4. Dependency graph — visualized

P1.5.1 version-hash  ──┐
                       ├──→ P3.1.1 Vote Message Types
P1.5.4 canonical    ──┘            │
                                    ├──→ P3.1.2 Quorum
                                    │       │
                                    │       ├──→ P3.1.3 View Change
                                    │       │           ↑
                                    │       │           VRF stub (ADR-002)
                                    │       │
                                    │       ├──→ P3.2.1 Finality SM
                                    │       │
                                    │       └──→ P3.5.1 Equivocation
                                    │                   │
P2.2.2 penalties (λ)  ──────────────┼───────────────────┘
                                    │
                                    ├──→ P3.3.1 Gossip IHAVE/IWANT
                                    │           │
                                    │           ├──→ P3.3.2 Bloom dedup
                                    │           │
                                    │           └──→ P3.3.3 Adaptive fanout
                                    │
P2.1.1 reputation schema ──┐        │
                            ├──────→ P3.4.1 Time Anchors (STA)
P3.1.1                  ──┘

(downstream)
P3.1.2 → P5.1.1 ι Fork Create (fork trigger hook)
P3.1.2 → P6.1.1 π Governance Proposals

5. Parallel-wave shape

After P1.5.1 (κ — shipped) + P1.5.4 (κ — shipped) seal as the version-hash and canonical-serialization predecessors, the entry point for Phase 3 is P3.1.1 Vote Messages. After P3.1.1 lands, the graph fans out wide: P3.1.2, P3.3.1, P3.4.1 can all start in parallel. After P3.1.2, another fan-out: P3.1.3, P3.2.1, P3.5.1 (plus VRF stub) can run in parallel.

Wave structure recommended in the prompt-file intro:

  • Wave 1: P3.1.1 (Vote Messages) — solo, gates everything
  • Wave 2 (3 parallel): P3.1.2 (Quorum) + P3.3.1 (Gossip core) + P3.4.1 (Time Anchors)
  • Wave 3 (4 parallel): P3.1.3 (View Change) + P3.2.1 (Finality SM) + P3.5.1 (Equivocation) + P3.6.1 (VRF stub)
  • Wave 4 (3 parallel): P3.3.2 (Bloom dedup) + P3.3.3 (Adaptive fanout) + P3.7.1 (MCP tools)
  • Wave 5: P3.8.1 (Parity harness) + P3.9.1 (ι Fork Hook stub) — closer

This mirrors κ’s 5-wave R86 → R87 close shape.

6. Spec surface → prompt-file sub-task mapping (preview)

This maps every concept inventoried in §2.1 to a planned per-task entry. Full per-task copy lands in Step 4 (the prompt file itself).

Planned sub-task Covers Maps to canonical
§P3.1.1 Vote Message Types + Canonical Wire Vote tuple, Ed25519 sig, envelope P3.1.1
§P3.1.2 Quorum Computation Quorum formula, has_quorum(), intersection property P3.1.2
§P3.1.3 Round / View State Machine Commit-reveal, T_round constants, view-change initiator P3.1.3 (partial)
§P3.2.1 Finality State Machine 5-level FSM, monotonicity, dispute window P3.2.1
§P3.3.1 Gossip Protocol — IHAVE/IWANT Wire shape, triple-anchor validation P3.3.1 (partial)
§P3.3.2 Gossip — Bloom Filter Dedup Bloom sizing, k hashes, query/insert P3.3.1 (partial)
§P3.3.3 Gossip — Adaptive Fanout max(3, min(10, 15 − connectivity_score)) P3.3.1 (partial)
§P3.4.1 Signed Time Anchors (STA) Median clock, drift detection, replay protection P3.4.1
§P3.5.1 Equivocation Detection + Slashing Proof structure, idempotent slashing P3.5.1
§P3.6.1 VRF Stub (Leader Election) HMAC-SHA256 stub, swap-to-noble interface new (rolled out of P3.1.3)
§P3.7.1 MCP Tool Surface consensus_propose / _vote / _finality / _gossip / vrf_eval new
§P3.8.1 Test Corpus + Parity Harness Multi-arbiter sim, faulty-node corpus new (mirrors P1.5.5)
§P3.9.1 Fork Trigger Hook (ι handoff stub) Schema-ready ι handoff; not implementing ι new

Count: 13 entries. Inside the dispatch’s 12–15 target. Each is targeted at ≥80 lines per the dispatch packet.

7. Open questions / blockers flagged for PM

  1. ADR-002 (VRF) is PROPOSED, not Accepted. Prompt-file recommendation: ship Option A (HMAC stub) as Phase 3 default with a clear swap-to-B path. PM should escalate ADR-002 to Accepted before Wave 3 dispatch, or accept that VRF will be a stub through the entire Phase 3 close.

  2. ADR-003 (BFT library) is PROPOSED, not Accepted. Recommended option is C (spike). Prompt file should mark gossip-transport slices (P3.3.x) as conditionally blocked on ADR-003 acceptance. State-machine slices (P3.1, P3.2, P3.5) are network-agnostic and can dispatch unblocked.

  3. λ dependency is in-flight at staging time. Prompt-file intro must say plainly: θ executor dispatch begins AFTER Phase 2 λ seals, because P3.5.1 equivocation slashing needs P2.2.2 penalties.

  4. Single-arbiter Phase 0 posture. consensus.md §Phase 0 posture says the runtime “accepts θ-shaped APIs but always returns trivially finalized”. The prompt-file Wave 5 closer (P3.7.1 MCP tools) must preserve this single-node compatibility — tools return QUORUM trivially when n=1, so the integration surface is testable without a multi-node test bed.

  5. Roadmap budget vs reality. Roadmap budgets Phase 3 at ~30 tasks / ~15 weeks. Task-breakdown.md ships 7 canonical. The prompt-file’s 13 granular entries split the difference, mirroring how κ exposed 20 sub-tasks over a ~5-week wallclock in R85→R87.

8. Heritage references — NOT cited as live

Files mentioned in spec sources that are heritage (donor / pre-R53 / Phase 0 reality-stamped to spec-only):

  • claude/webhooks/signature.js — HMAC webhook validator from AMS donor; noted in s06 line 54 as “uses HMAC for webhook signatures, not Ed25519”
  • claude/resilience/ — AMS rate-limiter; not the s10 admission gate
  • data/roadmaps/peer-to-peer/content/todo@gossip-sync-liveness.md — AMS donor roadmap stub; mentioned in s08 line 110
  • gossip.py, vrf.py — Python reference implementations from docs/reference/extractions/; ADR-002/003 cite as ports’ sources

These are documentation backing only. The prompt file should cite live spec (s06, s08, consensus.md) and the live ADRs — never the donor Python.


Audit complete. Surface inventoried. Mapping locked. ADR status flagged. Step 2 (contract) follows: behavioural contract for the prompt file itself.


Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.