soft3/foculus/.claude/plans/implementation.md

foculus implementation plan

status: M1 in progress. the map from spec (complete, adversarially reviewed) to code (substrate-only today).

where we start

grounded in the completeness report: ~3,900 lines of tested substrate (chain/vdf/nmt/das/erasure/store/vdisk/node/frames) inherited from the sync merge, and 0 lines of the consensus layer. the substrate implements VEC P2/P3/P6 and a file-level LWW merge for the virtual filesystem — it is not signal-level reconciliation, and the fork-choice seam does not exist yet. everything from protocol.md step 4-6, security-at-scale.md (L1/L2/T1/T2/S4/S5), beacon.md, fold-mining.md is greenfield.

the design is settled (prior sessions): one reconciliation engine, fork-choice as a pluggable strategy — Serialize (single-writer), MinHash (trusted multi-writer), Focus (trustless φ*). resolution supports both incremental (per-conflict) and batch-at-epoch (per-domain) timing. the trusted path must never compile the tri-kernel — Focus is feature-gated on tru.

key constraint the code forces

foculus's Signal (neuron, network, links, delta_pi, prev, step, height, proof) carries no nullifier. so:

  • equivocation (same neuron + step, divergent content) is detectable now — the data is present.
  • double-spend and resource-collision need the nullifier / resource-id, which the signal does not carry. either add a nullifier field to Signal (wire-format change, ripples to bbg/cybergraph) or delegate double-spend detection to bbg (which already has InsertError::DoubleSpend) and have foculus consume its verdict. this is an M5 decision; M1 builds the conflict/fork-choice machinery generic over the conflict key so it is unaffected by which way that goes.

milestones (dependency-ordered)

M1 — conflict model + ForkChoice trait + trivial strategies [first shippable]

src/conflict.rs:

  • ConflictKey (32 bytes: a nullifier, or hash(neuron ‖ step) for equivocation)
  • ConflictGroup { key, members: Vec<SignalId> }
  • conflict_keys(&Signal) -> Vec<ConflictKey> — pure function of content; equivocation implemented, double-spend a documented extension point (needs nullifier)
  • an index (key → members) that accretes as signals arrive, so detection is incremental and monotonic (matches protocol.md's "monotonic local conflict index")

src/fork.rs:

  • trait ForkChoice { fn resolve(&self, members: &[Signal]) -> usize; } — deterministic, returns winner index
  • Serialize — single-writer invariant: a conflict is a logic error, returns an explicit error/marker rather than silently picking
  • MinHash — lowest Signal::hash() wins; this is protocol.md's own measure-zero tiebreak, promoted to the general trusted rule

src/reconcile.rs:

  • the engine that ties detection to resolution, in both timings:
    • incremental: on each new signal, update the conflict index; if it joins a group, resolve immediately
    • batch: accumulate an epoch's groups, resolve all at close
  • both call the same ForkChoice::resolve

tests: equivocation detected, MinHash determinism (same set → same winner regardless of insertion order), Serialize rejects conflict, incremental vs batch produce identical winners.

deliverable: a working trusted-cloud consensus (Serialize/MinHash) with no φ* dependency.

M2 — Focus strategy (feature-gated focus, deps tru)

map CyberlinkRecord → tru Link::stake(from, to, amount), build FocusingGraph::build(links, ctx), compute_focusing(g, p), resolve a conflict group by higher φ* of its members. the trait's resolve gains the graph view it needs (Serialize/MinHash ignore it). Cargo.toml: tru = { path = "../tru/rs", optional = true }, focus = ["dep:tru"].

M3 — domain-local finality (L1/L2)

ε-support domain construction (the canonical superlevel set), adaptive threshold τ_D = μ_D + κ'σ_D over the domain, and the Φ_uncert certification gate using the existing nmt.rs P2 machinery. this is protocol.md step 6 — the finalization condition — made real.

M4 — support-switching (T1) + epoch pipeline

switching rule (consensus-only signal, VDF-rate-limited via the existing vdf.rs), epoch beacon (outer VDF over the finalized set, beacon.md), settlement fold-mining (fold-mining.md). this is the full epoch machinery and the largest milestone.

M5 — substrate reconciliation with the current spec

  • store.rs LWW-Element-Set → the G-Set + topological-sort merge vec.md P1 specifies (or update vec.md if LWW is the deliberate choice for the vfs layer specifically — decide, don't leave two merge definitions)
  • remove the f64 confidence + clock-drift float per the field-arithmetic mandate
  • resolve the nullifier wire-format decision (add field vs delegate to bbg)

verification discipline (per every milestone)

cargo check + cargo test green before commit; the substrate's 19 existing tests must stay green throughout (no regression in the DA/sync layer while the consensus layer is built on top). property tests for the invariants that matter: determinism (same signals → same winner on every node), monotonic detection (a conflict once seen stays seen), conservation where applicable.

honest scope

this is 6-8 focused sessions by the project estimation model, not one. M1 is self-contained and shippable on its own (trusted deployments). each later milestone is independently reviewable. the specs are complete and reviewed, so implementation is unblocked on design — the work is translation, not invention.

Homonyms

cybergraph/focus/implementation
soft3/tru/roadmap/implementation
implementation plan the full build order for every tru spec — from the one engine that is built (the focusing stub) to the eight-pass CT-0 compiler and the cross-repo reward settlement. each milestone has an input, an output artifact, and a verifiable predicate. dependency order is strict: a later…

Graph