Skip to main content

Module reducer

Module reducer 

Source
Expand description

Reducer-based pipeline architecture.

This module implements the event-sourced reducer architecture. It provides:

  • Pure state reduction with explicit event transitions
  • Immutable pipeline state that doubles as checkpoint
  • Event log for debugging and replay
  • Effect handlers for side effects (git operations, agent execution)

§Single Source of Truth

The reducer state is the single source of truth for all pipeline decisions:

  • Phase transitions: Only happen via reducer events, never via file checks
  • Agent selection: Determined by state.agent_chain, not config lookups
  • Agent fallback: Triggered by reducer events (AgentFallbackTriggered, AgentInvocationFailed)
  • XSD retry: Tracked in ContinuationState.xsd_retry_count / ContinuationState.xsd_retry_pending, not hidden logic
  • Pipeline completion: Determined by state.phase == Complete, not file existence

Invariant: No phase module or effect handler makes control-flow decisions. All decisions happen via events processed by reduce, which returns new state.

All effects are determined by determine_next_effect, a pure function of state. No external file checks or configuration lookups influence effect determination.

§Key Types

See also: CODE_STYLE.md for the architecture overview.

§Architecture

┌──────────────────────────────────────────────────┐
│                     Pipeline State                        │
│  (immutable: phase, iteration, agent_chain, history)     │
└──────────────────────────────────────────────────┘
                          │
                          ▼
┌──────────────────────────────────────────────────┐
│                        Reducer                            │
│       fn reduce(state: State, event: Event) -> State     │
│                   [Pure, no side effects]                │
└──────────────────────────────────────────────────┘
                          ▲
                          │
┌──────────────────────────────────────────────────┐
│                        Events                             │
│  DevelopmentIterationCompleted | AgentFailed |           │
│  ReviewPassCompleted | RebaseSucceeded | ...             │
└──────────────────────────────────────────────────┘
                          ▲
                          │
┌──────────────────────────────────────────────────┐
│                   Effect Handlers                         │
│  (Agent execution, file I/O, git operations)             │
│       [Side effects isolated here]                       │
└──────────────────────────────────────────────────┘

§Quick Start

Run pipeline with reducer:

use ralph_workflow::reducer::{run_event_loop, PipelineState};

let state = PipelineState::initial(developer_iters, reviewer_reviews);
let result = run_event_loop(&mut phase_ctx, Some(state), Default::default())?;

§State Inspection

Inspect pipeline state at any point:

println!("Current phase: {}", state.phase);
println!("Iteration: {}/{}", state.iteration, state.total_iterations);
println!("Current agent: {:?}", state.agent_chain.current_agent());

§Event Replay

Replay events from log:

let final_state = events.into_iter()
    .fold(initial_state, |s, e| reduce(s, e));

§Testing Strategy

The reducer architecture is designed for extensive testability:

§Unit Tests

  • Pure reducer: reduce() function has no side effects, 100% testable
  • State transitions: Each event → state transition tested in state_reduction.rs tests
  • Agent chain: Fallback logic tested via AgentChainState methods
  • Error classification: All error kinds tested in fault_tolerant_executor.rs

§Integration Tests

  • State machine: Real pipeline execution verifies correct phase transitions
  • Event replay: Event logs can reproduce final state deterministically

§Testing Reducer Purity

Reducer is easy to test - pure function with no side effects:

#[test]
fn test_agent_fallback() {
    let state = create_test_state();
    let event = PipelineEvent::AgentInvocationFailed { ... };
    let new_state = reduce(state, event);
    assert_eq!(new_state.agent_chain.current_agent_index, 1);
}

§Running Tests

# Unit tests only
cargo test -p ralph-workflow --lib --all-features

# Integration tests
cargo test -p ralph-workflow-tests --all-targets

# With coverage
cargo test -p ralph-workflow --lib --all-features -- --nocapture

Re-exports§

pub use effect::EffectHandler;
pub use effect::EffectResult;
pub use event::PipelineEvent;
pub use handler::MainEffectHandler;
pub use orchestration::compute_effect_fingerprint;
pub use orchestration::determine_next_effect;
pub use state::PipelineState;
pub use state_reduction::reduce;
pub use ui_event::UIEvent;
pub use event::CheckpointTrigger;
pub use event::AgentEvent;
pub use event::CommitEvent;
pub use event::DevelopmentEvent;
pub use event::LifecycleEvent;
pub use event::PlanningEvent;
pub use event::RebaseEvent;
pub use event::ReviewEvent;

Modules§

effect
Effect types and handlers for side effects.
event
Pipeline event types for reducer architecture.
fault_tolerant_executor
Fault-tolerant agent executor.
handler
orchestration
Orchestration logic for determining next effect.
prompt_inputs
state
Pipeline state types for reducer architecture.
state_reduction
Reducer function for state transitions.
ui_event
UI events for user-facing display.