CN-FOLLOW-01
CN true enforcedProducer / follow authority separation. (a) DETERMINISTIC SELECTION: the same candidate set yields the same selected canonical durable tip (the AO / select_best_chain law, arrival-order-independent). (b) FORGE-ONLY-ON-SELECTED-HEAD: a keyed producer forges if and only if it is leader on the AO-selected durable head (ChainDb::tip) -- never on a private or stale spine, never with a hidden authority, and never gated out by a per-tick exact-equality re-check the racing live frontier makes permanently unsatisfiable. Following a public multi-producer chain is PARTICIPANT behaviour; forging is PRODUCER behaviour; they are separate authorities. The block-producing node's follow authority IS the participant/AO chain-selection (run_participant_sync + fork-choice + store-based rewind), and the forge consumes its durable result -- the forge never re-selects, reorders, or prefers chains.
- Source
docs/clusters/PRODUCER-PARTICIPANT-FOLLOW/PRODUCER-PARTICIPANT-FOLLOW.md; docs/clusters/PRODUCER-PARTICIPANT-FOLLOW/CN-FOLLOW-01-participant-forge-on-ao-selected-head.md
- Introduced in
- CN-FOLLOW-01
Enforcement trace
Tests 8
- participant_venue_forges_on_ao_selected_head_when_leader
- participant_forge_base_is_ao_selected_chaindb_tip
- participant_forge_base_is_servable_before_forge
- participant_forge_refused_while_fork_choice_pending
- participant_venue_requires_forge_activation
- single_producer_forge_decision_unchanged
- orphaned_startup_holds_forge_fence_participant
- participant_forge_two_runs_byte_identical
Cross-references
Attack rationale
A keyed Participant producer that follows the AO-selected chain correctly but cannot produce on it (the verified 2026-06-19 gap: ~5h follow, 760 admits, AO routing, caught up, but 0 blocks -- 18052 no_tip_available + 988 not_leader, missed leader slot 115152430) is a liveness denial: the producer is a pure follower that never contributes a block. The cause was an authority split -- the producing decision (ExtendOwnSpine) was SingleProducer-only, so the Participant venue fell to the pure DC-NODE-15 exact-equality gate (durable_servable_tip == followed_peer_tip) that the racing live frontier makes true only ~5% of the time. The fix forges on the AO-selected durable head (ChainDb::tip) under the DC-NODE-28 fence, so production is gated only by leadership + a resolved fork-choice, never by an unsatisfiable per-tick race. Forging on a private/stale spine instead (the inverse failure) would split consensus; the forge-only-on-selected-head clause forbids it -- the base is the BLUE-selected servable tip a peer can FindIntersect (DC-CONS-24 / DC-NODE-14).
Evidence notes
Introduced at CN-FOLLOW-01 (2026-06-19). The follow half (--participant-venue -> AO, caught up, stable) was live-verified; this slice closes the forge half via a pure GREEN decision (participant_forge_decision) that mirrors the single-producer two-state forge mode (UseInitialCatchupGate -> ParticipantExtendOnSelectedHead) but fences on the AO/DC-NODE-28 pending-resolution state, not the single-producer observed-feed fence. 8 hermetic MAC tests + ci_check_participant_forge_on_selected_head.sh; single_producer_forge_decision behaviour byte-for-byte unchanged (single_producer_forge_decision_unchanged + the existing local_spine_* / caughtup_self_admit_enters_extend_directly_no_cert tests green). Tier kept un-flattened: the deterministic-selection + forge-only-on-selected-head clauses are true-tier project law; Cardano/Haskell fork-choice agreement is derived (CN-CONS-03 / DC-CONS-*); preview adoption (AddedToCurrentChain) is bounty. NO BA02 claim until cardano-node-preview logs AddedToCurrentChain for Ade's exact forged hash.