Invariants / DC-NODE-36

DC-NODE-36

DC derived enforced

Live single-selector dispatch (PHASE4-N-AO). The live participant NeedsForkChoice arm (today fail-closed in run_participant_sync, node_lifecycle.rs) routes the aggregated candidate SET to the SINGLE existing BLUE select_best_chain (DC-CONS-03) -- routed-to, NEVER duplicated: no second selector, no parallel preference, no density ordering, no operator heuristic. The selected tip is arrival-order-independent over the live multi-peer set (the live analog of the CN-CONS-01 permutation proof). A TiebreakerLossKeepCurrent outcome makes NO durable change. Only validated candidate summaries (DC-NODE-35) reach select_best_chain; a raw followed_peer_tip never does.

Source

docs/planning/phase4-select-multicandidate-fork-choice-invariants.md (FC-1/FC-2) + docs/clusters/PHASE4-N-AO/cluster.md

Introduced in
PHASE4-N-AO

Enforcement trace

Tests 4

  • win_emits_switch_to_winning_peer_and_durable_anchor
  • tiebreaker_loss_keeps_current
  • exceeded_rollback_keeps_current
  • best_of_two_peers_wins_and_is_identified

Cross-references

Evidence notes

Declared at PHASE4-N-AO cluster-doc; enforced at S3 close (CE-AO-3) via ci_check_live_multi_candidate_dispatch.sh + the reused ci_check_chain_selection_arrival_order_independent.sh. Wires the NeedsForkChoice consequent PHASE4-N-AI left fail-closed (DC-NODE-24 intended Participant->select_best_chain dispatch). The production select_best_chain was byte-unchanged through N-AI (the fork_choice.rs touch was a cfg(test) arrival-order proof).