DC-LEDGER-PHASE2-01
DC derived enforcedOne authoritative UTxO effect per transaction, gated by phase-2 validity. The UTxO effect of a transaction is derived in exactly ONE place from the canonical block plus its invalid_transactions set. A phase-2-VALID tx spends its ordinary inputs (field 0) and produces its ordinary outputs (field 1) at indices 0..n. A phase-2-INVALID tx spends ONLY its COLLATERAL inputs (field 13) and produces ONLY its collateral return (field 16) at index len(ordinary outputs) -- its ordinary inputs SURVIVE and its ordinary outputs are NEVER created. Consumers are validity-blind: they apply the derived spends/produces and never receive the phase-2 flag, so they cannot branch on it and cannot drift apart. total_collateral (field 17) is NOT the source of truth for anything here -- per cardano-ledger it is a declared assertion the UTXO rule checks, never an input to the effect.
- Source
docs/clusters/PREPROD-LIVE-2-FORGE-READINESS/SLICE-BND-2a-phase2-invalid-utxo-effect.md (INV-BND-2a)
- Cluster
- PREPROD-LIVE-2-FORGE-READINESS
- Introduced in
- PREPROD-LIVE-2-BND-2a
- Authority surface
- BLUE per-tx UTxO transition feeding the reduced stake authority and the full UTxO tracker
Enforcement trace
Code
Tests 4
- real_preprod_block_130350133_produces_the_cardano_collateral_only_effect
- a_collateral_return_is_produced_at_len_ordinary_outputs_with_verbatim_bytes
- a_pre_alonzo_invalid_transaction_fails_closed
- a_block_with_no_invalid_transactions_is_unchanged
Cross-references
Evidence notes
The PRIMARY proof is a differential against the REAL preprod block 130,350,133 (fixture crates/ade_ledger/tests/fixtures/block_130350133.cbor, 15,252 bytes, hash 46905dcf...), whose single tx is phase-2 invalid with 2 zero-valued withdrawals, 1 collateral input and NO collateral return: spent == {0326ab20...#1}, produced == empty, and the ordinary inputs b9fede11...#1/#3 are asserted BY NAME to survive because 'these got spent' is the exact failure being pinned. The collateral-return case is constructed (the real block declares none) with TWO ordinary outputs specifically so a positional enumerate() would place the return at 0 while the rule places it at 2. NEGATIVE-TESTED: treating an invalid tx as valid fails both differential tests; indexing the collateral return positionally fails the constructed test AND the gate's structural check. The gate additionally forbids a consumer implementing the rule itself (regex for if invalid / collateral_inputs / collateral_return inside track_utxo and process_one_tx), forbids reading total_collateral in the derivation, requires STORE_SEMANTICS_VERSION >= 4, and asserts >=4 passing tests so it cannot pass vacuously. SCOPE: this rule fixes the SILENT authority. It does NOT unpin the epoch accumulator, which continues to fail closed on the same block (InvalidTxCarriesAuthorityEffect) -- deliberately, so the halting surface stays honest while the silent one becomes correct. The accumulator's collAdaBalance scalar is BND-2b and the guard retirement is BND-2c. ID CORRECTION (BND-2d): this rule was first recorded as DC-LEDGER-01, an id already held by a long-standing rule, which broke registry uniqueness (ci_check_registry_unique_ids.sh was red from that commit until BND-2d). The older holder keeps the id; this entry -- three commits old and referenced only by its own slice doc -- takes the fresh DC-LEDGER-PHASE2-01.
Evidence
Reference rule quoted verbatim from Cardano.Ledger.Babbage.Rules.Utxo (Phase2Invalid) + Babbage.Collateral (collOuts/collAdaBalance) -- docs/evidence/run-stores/preprod-live2c/bnd2-oracle-extraction.md.
Existing-code census: reduced_advance never mentioned
invalid; track_utxo took no invalid set; apply_block decoded invalid_tx_indices for REPORTING only -- docs/evidence/run-stores/preprod-live2c/bnd2-existing-code-authority-census.md.v3 store refused live by the v4 binary: StoreSemanticsVersionMismatch { artifact: ChainDb, found: Version(3), required: 4, action: RebootstrapRequired }, exit 1.