DC-MITHRIL-03
DC true enforcedThe native Mithril AUTHORITY TRANSITION assembles the COMPLETE authoritative seed (LedgerState +
PraosChainDepState + a NATIVE LiveConsensusInputsCanonical) from EXCLUSIVELY the verified manifest
binding + the S1a NativeSnapshotNonUtxoState + the Stage-2 tables UTxO + genesis constants -- with
NO cardano-cli, NO JSON consensus-input bundle, NO operator seed, and NO convenience fallback on this
path; the verified snapshot IS the source. (a) NATIVE ASSEMBLY (no operator bundle): every field has a
single declared source -- utxo_state <- Stage-2 UTxOState; cert_state + reserves + treasury +
block_production + the five Praos nonces + protocol_params (incl. MinUtxoRule::PerByte) <- S1a;
epoch_state.slot + network_magic + genesis_hash + source_tip + the anchor seed_point <- the manifest
point; epoch_no + epoch_nonce(eta0) + pool stake/VRF <- S1a; active_slots_coeff + max_lovelace_supply
<- genesis; the epoch window <- the era schedule + the S1a epoch; era = Conway; gov_state = None;
conway_deposit_params = None; track_utxo = false; snapshots = cold-start empty; epoch_fees = 0; op-cert
counters empty; last_* = None. The native LiveConsensusInputsCanonical carries a fixed native-source
marker (never a cardano-cli command or node version) and protocol_params_json = None; its fingerprint is
computed via the SOLE canonical-form authority (canonical_from_raw). (b) POINT COHERENCE is a TERMINAL
gate BEFORE any assembly or persist: the S1a era == Conway, the S1a point == the manifest certified
point (slot AND hash), the S1a network_id == the manifest-magic-derived id (mainnet 764824073 -> 1, any
other -> 0), the S1a epoch == the epoch the schedule resolves for the certified slot, and the assembled
anchor seed_point == the manifest point (the verify_mithril_binding leg inside the single closed
composition). ANY mismatch / missing input is a structured terminal MithrilNativeAssemblyError (no
authority assembled, NOTHING partial persisted). (c) PERSIST-BEFORE-VISIBILITY (atomic): the native
entry routes through the SAME single closed composition bootstrap_from_mithril_snapshot -- the sole
bootstrap_initial_state authority + the seed-epoch consensus sidecar + the recovered-anchor point
(put_recovered_anchor_point) + the WAL provenance append. The WAL append is the SOLE point at which the
anchor lineage becomes discoverable (warm-start recovery gates on the WAL provenance); an interrupted
import -- any write failing before the WAL commit -- leaves NO bootable partial authority state (a
warm-start recovers the store as 'not imported'), and the imported anchor point is explicitly evidenced
- recoverable via load_recovered_anchor_point. There is NO second storage-init path. SCOPE: assembly +
atomic persistence ONLY. NOT the Stage-2
tables-> UTxOState materialization (the native assembly CONSUMES a UTxOState; the materialization + its i64-MultiAsset release blocker is DC-LEDGER-VALUE-01 / the LEDGER-VALUE-CORRECTNESS cluster), NOT the Conway per-byte min-UTxO calculator (DC-LEDGER-PARAMS-01 release blocker), and NOT cold-restart / warm-start recovery / ChainSync / follow (S2, the release gate). The cardano-cli / JSON-seed importers STAY as RED diagnostic / oracle tooling, never bootstrap authority on this path.
- Source
docs/clusters/MITHRIL-VERIFIED-ANCHOR-INTEGRATION/SLICE-S1b-authority-transition.md; user directive 2026-06-23 (S1b = the native authority transition: assemble the complete seed from ONLY manifest/S1a/Stage-2/genesis, enforce point coherence, persist atomically before visibility, and remove the cardano-cli/JSON seed from the native bootstrap path; do NOT implement the Stage-2 UTxO materialization or the Conway per-byte min-UTxO calculator -- those are separate release blockers)
- Introduced in
- MITHRIL-VERIFIED-ANCHOR-INTEGRATION-S1b
Enforcement trace
Code
Tests 9
- native_assembled_seed_is_deterministic
- native_assembly_maps_each_field_from_its_source
- point_mismatch_is_terminal
- point_hash_mismatch_is_terminal
- wrong_era_is_terminal
- wrong_network_is_terminal
- epoch_mismatch_is_terminal
- native_bootstrap_persists_and_anchor_point_is_recoverable
- interrupted_persist_leaves_no_discoverable_anchor_lineage
Cross-references
Attack rationale
Three authority-bootstrap corruption classes are closed. (1) Operator-seed substitution: if the native bootstrap could fall back to the cardano-cli JSON seed or the operator consensus-inputs bundle, an operator could seed an attacker-chosen ledger / stake distribution divorced from the verified Mithril snapshot -- the very provenance the manifest binding exists to guarantee. Closed by construction: the native assembly's signature takes ONLY the manifest binding + S1a + the Stage-2 UTxO + genesis, references none of import_cardano_cli_json_utxo / import_live_consensus_inputs / require_forge_current_pparams / the --json-seed flag (the ci gate's negative-controlled grep over the cfg(test)-stripped production body fails on any such token), and offers no convenience fallback. (2) Incoherent-snapshot admission: a snapshot decoded at a different chain point, epoch, network, or era than the certificate attests would seed a ledger bound to the wrong chain context. Closed by the terminal point-coherence gate that runs BEFORE any LedgerState is assembled or any byte persisted -- a slot/hash/epoch/network/era disagreement is a structured MithrilNativeAssemblyError with no partial side effect, and the assembled anchor seed_point == the manifest point is re-checked by verify_mithril_binding inside the single closed composition. (3) Bootable partial authority after an interrupted import: if the durable artifacts became discoverable before the atomic commit, a crash mid-persist could leave a half-initialized authority a warm-start would boot. Closed by routing through the one bootstrap_initial_state authority + the shared lineage persist whose WAL provenance append is the SOLE discovery gate: the interrupted-import test injects a WAL-append failure and proves replay_from_anchor yields no provenance -> the lineage is not discoverable -> no bootable partial state. There is no second storage-init path the native entry could use to bypass the chokepoint.
Evidence notes
Introduced as MITHRIL-VERIFIED-ANCHOR-INTEGRATION S1b (2026-06-23), the authority transition after S1a's decoder (DC-LEDGER-PARAMS-01). The native assembly + atomic-persist FUNCTION is the deliverable; it consumes the S1a NativeSnapshotNonUtxoState (+ its commitment) + a Stage-2 UTxOState + the manifest binding + genesis constants. The CLI/JSON importers are physically absent from the FUNCTION-LEVEL native entrypoint (the function cannot reach them; the ci gate enforces it) -- this is a function-level claim ONLY, NOT a claim about the live --mode node path, which still uses them until node_lifecycle invokes the native entry. The existing single closed composition bootstrap_from_mithril_snapshot is REUSED unchanged (CN-MITHRIL-01 / ci_check_mithril_seed_point_independence.sh stay green -- that gate guards mithril_bootstrap.rs, which is untouched). The recovered-anchor point persistence (DC-NODE-31) was already wired into the shared lineage persist (put_recovered_anchor_point at seed_epoch_lineage.rs); S1b's native entry inherits it, and the anchor-point-recoverable test proves load_recovered_anchor_point returns the manifest point after a native bootstrap. Verified: cargo test -p ade_runtime --lib mithril_native_assembly green (9/9); cargo build --workspace clean; ci/ci_check_mithril_authority_transition.sh PASS (negative-controlled: it fails on an injected CLI-seed token in the production body). HONEST CLASSIFICATION -- DERIVED (proven, 9 tests): native snapshot components can assemble a coherent bootstrap authority and persist it atomically. NOT YET PROVEN: the live node can invoke that authority path from snapshot files. BLOCKED BY: the Stage-2 tables -> UTxOState promotion + the live FirstRun input contract. NOT WIRED LIVE: the --mode node FirstRun arm (first_run_mithril_bootstrap) still seeds from --json-seed-path + --consensus-inputs-path because the Stage-2 tables -> UTxOState materialization is unshipped (DC-LEDGER-VALUE-01 widened the OUTPUT value model; the tables MemPack TxOut -> ledger TxOut promotion + TxIn parse is a separate concern). Retiring that live arm to the native entry is the follow-on once Stage-2 UTxO materialization lands. NOT IMPLEMENTED HERE (explicit scope fences): the Stage-2 UTxO materialization, the Conway per-byte min-UTxO calculator (DC-LEDGER-PARAMS-01), cold-restart / warm-start recovery / ChainSync / follow (S2). Gated on targeted suites (NOT cargo test -p ade_testkit -- the pre-existing all_epoch_boundaries_fire hang).