//! Phase 121: StepTree → Normalized shadow lowering (dev-only) //! //! ## Purpose //! //! Establish minimal route from StepTree (structure SSOT) to Normalized form, //! verifying parity with existing router for if-only patterns. //! //! ## Scope //! //! - **if-only**: Support if statements without loops //! - **loop rejection**: Reject loops via capability guard //! //! ## Design Rules //! //! **Input SSOT**: //! - `StepTree` + `StepTreeContract` (no facts re-analysis) //! - Lowering decisions based only on contract information //! //! **Output**: //! - `JoinModule` (Normalized dialect) //! - Or "Normalized-equivalent intermediate" expressed in existing JoinIR types //! //! **Execution conditions**: //! - dev-only: Only runs when `joinir_dev_enabled()` returns true //! - strict: Only fail-fast on mismatch when `joinir_strict_enabled()` returns true //! //! **Prohibitions**: //! - No fallback: Shadow conversion failure logs reason in dev-only, fail-fast in strict //! - No direct env reads (must go through `src/config/env/*`) //! - No hardcoding (no branching on fixture names or variable names) pub mod builder; pub mod contracts; pub mod normalized_verifier; pub mod env_layout; pub mod if_as_last_join_k; pub mod loop_true_break_once; // Phase 131: loop(true) break-once pub mod post_if_post_k; // Phase 129-C: post-if with post_k continuation pub mod legacy; pub mod dev_pipeline; pub mod parity_contract; pub mod available_inputs_collector; // Phase 126: available_inputs SSOT pub mod exit_reconnector; // Phase 131 P1.5: Direct variable_map reconnection (Option B) pub use builder::StepTreeNormalizedShadowLowererBox; pub use contracts::{CapabilityCheckResult, UnsupportedCapability}; pub use parity_contract::{MismatchKind, ShadowParityResult}; pub use env_layout::EnvLayout; pub use exit_reconnector::ExitReconnectorBox; // Phase 131 P1.5