1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Lint policy: the style guide is authoritative.
//
// See `CODE_STYLE.md`, `docs/code-style/boundaries.md`,
// `docs/code-style/coding-patterns.md`, `docs/code-style/testing.md`, and
// `docs/tooling/dylint.md` when fixing violations.
//
// This library intentionally keeps boundary-sensitive policy in dylint so
// domain modules stay strict without blocking legitimate `io/`, `runtime/`,
// `ffi/`, and `boundary/` code.
//
// `unsafe_code` is not denied here because the library contains documented
// POSIX boundary code that requires small unsafe sections.
//
// `clippy::cargo` stays off because it reports ecosystem dependency conflicts
// rather than code-shape problems contributors can fix locally.
// `unwrap_used`, `expect_used`, and blanket panic bans are not enforced at this
// crate root because the relevant policy is boundary-sensitive. Fix ordinary code
// to use `Result`, `?`, and explicit state/value transformations; if the code is a
// real boundary concern, keep it in an explicit boundary module instead of weakening
// the lint.
//! Ralph workflow library for AI agent orchestration.
//!
//! This crate provides the core functionality for the `ralph` CLI binary,
//! implementing a reducer-based architecture for orchestrating AI coding agents
//! through development and review cycles.
//!
//! # Quick Start
//!
//! Ralph is primarily a CLI binary. For library use (integration testing):
//!
//! ```toml
//! [dev-dependencies]
//! ralph-workflow = { version = "0.6", features = ["test-utils"] }
//! ```
//!
//! # Architecture
//!
//! Ralph uses an **event-sourced reducer architecture**. The core state machine
//! follows the pattern:
//!
//! ```text
//! State → Orchestrator → Effect → Handler → Event → Reducer → State
//! ```
//!
//! | Component | Pure? | Role |
//! |-----------|-------|------|
//! | [`reducer::PipelineState`] | Yes | Immutable progress snapshot, doubles as checkpoint |
//! | [`reducer::reduce`] | Yes | `(State, Event) → State` |
//! | [`reducer::determine_next_effect`] | Yes | `State → Effect` |
//! | [`reducer::EffectHandler`] | No | Executes effects, produces events |
//!
//! Business logic lives in reducers (pure). I/O lives in handlers (impure).
//!
//! ## Two Effect Layers
//!
//! Ralph has two distinct effect types for different pipeline stages:
//!
//! | Layer | Module | When | Filesystem Access |
//! |-------|--------|------|-------------------|
//! | `AppEffect` | [`app`] | Before repo root known | `std::fs` directly |
//! | `Effect` | [`reducer`] | After repo root known | Via [`workspace::Workspace`] |
//!
//! These layers must never mix: `AppEffect` cannot use `Workspace`, and `Effect`
//! cannot use `std::fs` directly.
//!
//! # I/O Abstractions
//!
//! All I/O is abstracted through traits for testability:
//!
//! - [`workspace::Workspace`] - Filesystem operations
//! - Production: [`workspace::WorkspaceFs`]
//! - Tests: `MemoryWorkspace` (with `test-utils` feature)
//! - [`ProcessExecutor`] - Process spawning
//! - Production: [`RealProcessExecutor`]
//! - Tests: `MockProcessExecutor` (with `test-utils` feature)
//!
//! # Feature Flags
//!
//! - `monitoring` (default) - Enable streaming metrics and debugging APIs
//! - `test-utils` - Enable test utilities (`MockProcessExecutor`, `MemoryWorkspace`, etc.)
//! - `hardened-resume` (default) - Enable checkpoint file state capture for recovery
//!
//! # Key Modules
//!
//! **Core Architecture:**
//! - [`reducer`] - Core state machine with pure reducers and effect handlers
//! - [`app`] - CLI layer operating before repo root is known (`AppEffect`)
//! - [`phases`] - Pipeline phase implementations (planning, development, review, commit)
//!
//! **I/O Abstractions:**
//! - [`workspace`] - Filesystem abstraction (`WorkspaceFs` production, `MemoryWorkspace` testing)
//! - [`executor`] - Process execution abstraction for agent spawning
//!
//! **Agent Infrastructure:**
//! - [`agents`] - Agent configuration, registry, and CCS (Claude Code Switch) support
//! - [`json_parser`] - NDJSON streaming parsers for Claude, Codex, Gemini, `OpenCode`
//! - [`prompts`] - Template system for agent prompts
//!
//! **Supporting:**
//! - [`git_helpers`] - Git operations using libgit2 (no CLI dependency)
//! - [`checkpoint`] - Pipeline state persistence for `--resume` support
//! - [`config`] - Configuration loading and verbosity levels
//!
//! # Error Handling
//!
//! Most functions return `anyhow::Result` for flexible error handling with context.
//! Use `.context()` to add context to errors as they propagate.
// Benchmarks module - contains public baselines used by integration tests.
// Benchmark *tests* inside the module remain `#[cfg(test)]`.
// Re-export XML extraction and validation functions for use in integration tests.
// These functions parse and validate XML output from agent responses (plan, issues, fix results).
pub use extract_development_result_xml;
pub use extract_fix_result_xml;
pub use extract_issues_xml;
pub use validate_continuation_development_result_xml;
pub use validate_development_result_xml;
pub use validate_fix_result_xml;
pub use validate_issues_xml;
pub use validate_plan_xml;
pub use validate_xml_against_xsd;
// Re-export process executor types for dependency injection.
// See [`executor`] module for documentation.
pub use ;
/// Re-export mock executor for test-utils feature.
/// Use MockProcessExecutor to control process behavior in integration tests.
pub use ;
pub use Workspace;