DC-EPOCH-39
DC derived enforcedA stall's CAUSE is typed, and only a real epoch transition may enter boundary machinery. Advancing the durable accumulator over one block yields exactly one of: Advanced, AlreadyApplied, BoundaryMarkRequired (the block's epoch is STRICTLY ahead of the accumulator's -- a crossing is genuinely due), or ApplyFailed (carrying the ledger's own LedgerTransitionError by value, never a rendered string). The boundary decision is POSITIVE and taken BEFORE the apply, from the block's epoch against the accumulator's own -- never inferred from an error variant or message. A within-epoch apply failure MUST NOT cause a reduced- checkpoint rewind, a boundary-mark capture, or a boundary cross to be attempted.
- Source
docs/clusters/PREPROD-LIVE-2-FORGE-READINESS/SLICE-BND-1-typed-accumulator-stall-cause.md (INV-BND-1)
- Cluster
- PREPROD-LIVE-2-FORGE-READINESS
- Introduced in
- PREPROD-LIVE-2-BND-1
- Authority surface
- GREEN accumulator-advance classification over the BLUE apply contract (observe-only; never a consensus verdict)
Enforcement trace
Code
Tests 4
- a_within_epoch_apply_failure_is_apply_failed_not_a_boundary
- a_crossing_is_classified_from_the_epochs_even_when_the_apply_would_fail
- boundary_crossing_block_stalls_observe_only
- over_chaindb_stops_at_boundary_observe_only
Cross-references
Evidence notes
The gate asserts STRUCTURE, not merely that tests exist: the flattened Stalled/StalledAt variants cannot return to either enum (scoped to those two enum bodies -- AccumulatorBoundaryOutcome::Stalled is a different type and is legitimately untouched), the epoch predicate must textually PRECEDE the apply call, the typed error must not be re-rendered inside the advancer, and the apply-failure arm must call none of position_reduced_checkpoint_at_boundary / sum_base_credential_stake / cross_accumulator_over_boundary_block / bind_boundary_mark. Both halves were negative-tested: mutating the predicate from > to >= fails a_within_epoch_apply_failure_is_apply_failed_not_a_boundary plus 5 pre-existing tests, and re-introducing sum_base_credential_stake into the apply-failure arm is caught by the gate. The gate also asserts a NONZERO passing-test count so it cannot pass vacuously. SCOPE: this rule separates the two failure classes; it does NOT let the accumulator cross 130,350,133 -- that is BND-2 (phase-2-invalid tx body-effect semantics + the undeclared-collateral input gap), which is gated on reference-semantics extraction and deliberately unimplemented here.
Evidence
BND census 2026-08-09 (941f98a2): stall_slot=130350133 stall_block_epoch=305 cursor_epoch=305 detected_transition=false -- the block that pinned the accumulator is ordinary within-epoch traffic, yet consumed the full boundary path.
BND-1 live proof 2026-08-11: same store, same block, same typed error, same pinned cursor 130350114/5024325/c16626fe -- boundary_arm_ms 84,783 -> 0, checkpoint_forward_ms 23,389 -> 0, accumulator_loop_ms 84,978 -> 269, zero REWOUND/cross lines.