Invariants / CN-NODE-01

CN-NODE-01

CN release enforced

Single bootstrap authority: exactly one pub fn in ade_runtime::bootstrap returns the initial (LedgerState, PraosChainDepState, ChainDb tip) at node startup. Cold-start (genesis-only) and warm-start (snapshot-resume + replay-forward) are two branches of the same function — never parallel paths. Type-level + CI grep enforcement, mirroring CN-STORE-07 / CN-STORE-08.

Source

docs/planning/phase4-n-k-orchestrator-binary-invariants.md §1 (I-2)

Enforcement trace

Tests 5

  • crates/ade_runtime/src/bootstrap.rs::tests::bootstrap_cold_start_returns_genesis_when_empty
  • crates/ade_runtime/src/bootstrap.rs::tests::bootstrap_cold_start_without_genesis_errors
  • crates/ade_runtime/src/bootstrap.rs::tests::bootstrap_warm_start_materializes_from_persistent_snapshot
  • crates/ade_runtime/src/bootstrap.rs::tests::bootstrap_warm_start_equals_direct_materialize
  • crates/ade_runtime/src/bootstrap.rs::tests::bootstrap_two_runs_produce_byte_identical_state

Cross-references

Strengthened in

Attack rationale

A parallel bootstrap path can produce an initial state that disagrees with the canonical materialize+decode authority chain — opening a startup-time chain-divergence vector.

Evidence notes

PHASE4-N-K S1 (2026-05-26) shipped ade_runtime::bootstrap::bootstrap_initial_state as the SOLE pub fn returning the initial (LedgerState, PraosChainDepState, Option) triple. Cold-start vs warm-start is a single in-function branch. ci/ci_check_bootstrap_closure.sh enforces the single-pub-fn + materialize-authority-call positive grep. ade_node binary (S7) calls the function exactly once (ci/ci_check_node_binary_uses_single_bootstrap.sh). PHASE4-N-M-B (2026-05-26) strengthened by adding admission-mode dispatch closure: ci/ci_check_node_mode_closure.sh enforces Mode is closed {WireOnly, Admission}, main.rs match has no wildcard arm, and dispatch_admission is the sole admission-mode entry. PHASE4-N-F-C (2026-05-31) strengthened on two fronts: (1) the new --mode node lifecycle owner is the single owner threading first-run-vs-warm-start (a pure function of on-disk state) → bootstrap_initial_state → produce, with NO second bootstrap/recovery/storage-init authority; ci/ci_check_node_mode_closure.sh now pins the closed set {WireOnly, Admission, KeyGenKes, Produce, Node} (no wildcard arm). (2) new gate ci/ci_check_lifecycle_owner_uses_bootstrap_initial_state.sh enforces that the owner obtains initial state SOLELY via bootstrap_initial_state and contains the RequiredFromRecoveredProvenance constructor to owner+authority, fencing out genesis/bundle/cold/recover_node_state fallbacks.