T-REC-04
T true enforcedThe WarmStart-recovered forge chain_dep.epoch_nonce (eta0) MUST come from the imported/recovered consensus
input, never from a snapshot placeholder and never from genesis. Authoritative recovered state is explicit,
persisted, replayable, and comparable: the seed-epoch eta0 is carried as an EXPLICIT field in the persisted
SeedEpochConsensusInputs sidecar and applied (overlaid) onto the recovered PraosChainDepState in the
single bootstrap_initial_state authority. A snapshot-seeded Nonce::ZERO must NEVER reach the
forge/self_accept path when a seed-epoch lineage exists. Fail-closed: an old sidecar that omits epoch_nonce
decodes as a version mismatch (UnknownVersion, schema v1 vs v2), never a default-to-zero eta0. Authority
split preserved: snapshot = ledger/chain skeleton; seed-epoch sidecar = the Praos consensus inputs incl. eta0.
- Source
docs/clusters/PHASE4-N-F-G-N/cluster.md
- Cluster
- PHASE4-N-F-G-N
- Introduced in
- PHASE4-N-F-G-N
Enforcement trace
Code
Tests 5
- warm_start_overlays_recovered_eta0_onto_chain_dep_g_n
- warm_start_restores_seed_epoch_consensus_inputs_byte_identical
- seed_cinput_decode_rejects_unknown_version
- seed_epoch_consensus_inputs_round_trips_byte_identical
- pinning_preseed_warmstart_roundtrip_faithful
Cross-references
Evidence notes
PHASE4-N-F-G-N S1 (2026-06-04). Proven bug: a forge instrument (since reverted) showed Ade forged its C1 block-0 header VRF over eta0 = Nonce::ZERO while the C1 follower verifies over the genesis nonce 953a4c34 -> VRFKeyBadProof. Root cause: SeedEpochConsensusInputs OMITTED epoch_nonce, so admission imported eta0 (LiveConsensusInputsCanonical.epoch_nonce) -> the merge DROPPED it -> WarmStart had no recoverable eta0 -> the snapshot's Nonce::ZERO (admission/bootstrap.rs:164) reached the forge. The admission/bootstrap.rs comment (198-200) predicted it; self-accept masked it (Ade's validator read the same recovered ZERO). FIX: added epoch_nonce to the sidecar (versioned CBOR, v1->v2, fail-closed via UnknownVersion -- never default-to-zero), the merge persists canonical.epoch_nonce, and bootstrap_initial_state overlays the recovered sidecar eta0 onto chain_dep (epoch_nonce + evolving_nonce). NOT a snapshot replacement, NO VRF crypto/variant change, NO genesis-derived nonce, NO C1-only branch. Regression warm_start_overlays_recovered_eta0_onto_chain_dep_g_n proves a snapshot eta0 != sidecar eta0 -> recovered chain_dep == sidecar eta0. ade_ledger seed-consensus (4) + ade_runtime bootstrap A3b (22, incl. the new regression) + merge/genesis/mithril + ade_testkit genesis_pinning (CE-G-A-1) + ade_node node_sync (43) + node_lifecycle (25) all pass. The C1 staged store must be regenerated (re-run admission) since its sidecar predates eta0; an old store fails closed at recovery. CE-G-N-2 (live C1: forge eta0 == 953a4c34, no VRFKeyBadProof) is operator-gated; no RO-LIVE flip.