Skip to main content

ralph_workflow/reducer/event/
review.rs

1// NOTE: split from reducer/event.rs to keep the main file under line limits.
2use serde::{Deserialize, Serialize};
3
4/// Review phase events.
5///
6/// Events related to code review passes and fix attempts. The review phase
7/// runs reviewer agents to identify issues and (by default) the same reviewer
8/// agent chain to apply any required fixes.
9///
10/// # State Transitions
11///
12/// - `PhaseStarted`: Sets phase to Review, resets pass counter
13/// - `PassStarted`: Resets agent chain for the pass
14/// - `Completed(issues_found=false)`: Advances to next pass or CommitMessage
15/// - `Completed(issues_found=true)`: Triggers fix attempt
16/// - `FixAttemptCompleted`: Transitions to CommitMessage
17/// - `PhaseCompleted`: Transitions to CommitMessage
18#[derive(Clone, Serialize, Deserialize, Debug)]
19pub enum ReviewEvent {
20    /// Review phase has started.
21    PhaseStarted,
22    /// A review pass has started.
23    PassStarted {
24        /// The pass number starting.
25        pass: u32,
26    },
27
28    /// Review context prepared for a pass.
29    ///
30    /// Emitted after `Effect::PrepareReviewContext` completes.
31    ContextPrepared {
32        /// The pass number the context was prepared for.
33        pass: u32,
34    },
35
36    /// Review prompt prepared for a pass.
37    ///
38    /// Emitted after `Effect::PrepareReviewPrompt` completes.
39    PromptPrepared {
40        pass: u32,
41    },
42
43    /// Reviewer agent was invoked for a pass.
44    ///
45    /// Emitted after `Effect::InvokeReviewAgent` completes.
46    AgentInvoked {
47        pass: u32,
48    },
49
50    /// Review issues XML exists and was read successfully for the pass.
51    ///
52    /// Emitted after `Effect::ExtractReviewIssuesXml` completes.
53    IssuesXmlExtracted {
54        pass: u32,
55    },
56    /// Review issues XML missing for the pass.
57    ///
58    /// Emitted after `Effect::ExtractReviewIssuesXml` when the XML was absent.
59    IssuesXmlMissing {
60        pass: u32,
61        /// The invalid output attempt count.
62        attempt: u32,
63        /// Error detail if file read failed for a reason other than NotFound.
64        error_detail: Option<String>,
65    },
66
67    /// Review issues XML validated for a pass.
68    ///
69    /// This event is an observation: the XML was valid and the handler determined
70    /// whether issues were found and whether this was an explicit clean-no-issues output.
71    IssuesXmlValidated {
72        pass: u32,
73        issues_found: bool,
74        clean_no_issues: bool,
75        issues: Vec<String>,
76        no_issues_found: Option<String>,
77    },
78
79    /// ISSUES.md was written for a pass.
80    IssuesMarkdownWritten {
81        pass: u32,
82    },
83
84    /// Review issue snippets were extracted for a pass.
85    IssueSnippetsExtracted {
86        pass: u32,
87    },
88
89    /// Review issues XML archived for a pass.
90    IssuesXmlArchived {
91        pass: u32,
92    },
93
94    /// Review issues XML cleaned before invoking the reviewer agent.
95    IssuesXmlCleaned {
96        pass: u32,
97    },
98
99    /// Fix prompt prepared for a review pass.
100    FixPromptPrepared {
101        pass: u32,
102    },
103
104    /// Fix agent was invoked for a review pass.
105    FixAgentInvoked {
106        pass: u32,
107    },
108
109    /// Fix result XML exists and was read successfully for the pass.
110    FixResultXmlExtracted {
111        pass: u32,
112    },
113    /// Fix result XML missing for the pass.
114    FixResultXmlMissing {
115        pass: u32,
116        /// The invalid output attempt count.
117        attempt: u32,
118        /// Detailed error message from file read failure (if not NotFound).
119        ///
120        /// This field is populated when the file exists but cannot be read
121        /// (e.g., permission denied, I/O error). It's None for simple NotFound.
122        error_detail: Option<String>,
123    },
124
125    /// Fix result XML validated for a pass.
126    FixResultXmlValidated {
127        pass: u32,
128        status: crate::reducer::state::FixStatus,
129        summary: Option<String>,
130    },
131
132    /// Fix result XML cleaned before invoking the fix agent.
133    FixResultXmlCleaned {
134        pass: u32,
135    },
136
137    /// Fix outcome applied for a pass.
138    FixOutcomeApplied {
139        pass: u32,
140    },
141
142    FixResultXmlArchived {
143        pass: u32,
144    },
145    /// A review pass completed with results.
146    Completed {
147        /// The pass number that completed.
148        pass: u32,
149        /// Whether issues were found requiring fixes.
150        issues_found: bool,
151    },
152    /// A fix attempt for issues has started.
153    FixAttemptStarted {
154        /// The pass number this fix is for.
155        pass: u32,
156    },
157    /// A fix attempt completed.
158    FixAttemptCompleted {
159        /// The pass number this fix was for.
160        pass: u32,
161        /// Whether changes were made.
162        changes_made: bool,
163    },
164    /// Review phase completed, all passes done.
165    PhaseCompleted {
166        /// Whether the phase exited early (before all passes).
167        early_exit: bool,
168    },
169    /// Review pass found no issues - clean exit.
170    ///
171    /// Emitted when a review pass completes with no issues found.
172    /// This is distinct from `Completed { issues_found: false }` in that
173    /// it explicitly signals a clean pass for UI/logging purposes.
174    PassCompletedClean {
175        /// The pass number that completed.
176        pass: u32,
177    },
178    /// Review output validation failed (XSD/XML parsing error).
179    ///
180    /// Emitted when review output cannot be parsed. Reducer decides
181    /// whether to retry or switch agents.
182    ///
183    /// The `error_detail` field contains the formatted validation error that will
184    /// be shown to the agent in the XSD retry prompt. This error should be
185    /// actionable and guide the agent toward producing valid XML.
186    OutputValidationFailed {
187        /// The pass number.
188        pass: u32,
189        /// Current invalid output attempt number.
190        attempt: u32,
191        /// Detailed error message from XSD validation, formatted for AI retry.
192        ///
193        /// This is the output of `XsdValidationError::format_for_ai_retry()` and
194        /// includes:
195        /// - Error type and location
196        /// - What was expected vs. what was found
197        /// - Actionable suggestions for fixing
198        /// - Examples of correct format
199        error_detail: Option<String>,
200    },
201
202    /// Fix attempt completed with incomplete status, needs continuation.
203    ///
204    /// Emitted when fix output is valid XML but indicates work is not complete
205    /// (status is "issues_remain"). Triggers a continuation with new session.
206    FixContinuationTriggered {
207        /// The pass number this fix was for.
208        pass: u32,
209        /// Status from the agent (typically IssuesRemain).
210        status: crate::reducer::state::FixStatus,
211        /// Summary of what was accomplished.
212        summary: Option<String>,
213    },
214
215    /// Fix continuation succeeded after multiple attempts.
216    ///
217    /// Emitted when a fix continuation finally reaches a complete state
218    /// (all_issues_addressed or no_issues_found).
219    FixContinuationSucceeded {
220        /// The pass number this fix was for.
221        pass: u32,
222        /// Total number of continuation attempts it took.
223        ///
224        /// Note: This field is not used by the reducer for state transitions, but
225        /// is kept for observability (event logs, checkpoint serialization, debugging).
226        total_attempts: u32,
227    },
228
229    /// Fix continuation budget exhausted.
230    ///
231    /// Emitted when fix continuations have been exhausted without reaching
232    /// a complete state. Policy decides whether to proceed to commit or abort.
233    FixContinuationBudgetExhausted {
234        /// The pass number this fix was for.
235        pass: u32,
236        /// Total number of continuation attempts made.
237        total_attempts: u32,
238        /// The last status received (typically IssuesRemain).
239        last_status: crate::reducer::state::FixStatus,
240    },
241
242    /// Fix output validation failed (XSD/XML parsing error).
243    ///
244    /// Emitted when fix output cannot be parsed. Reducer decides
245    /// whether to retry or switch agents.
246    FixOutputValidationFailed {
247        /// The pass number this fix was for.
248        pass: u32,
249        /// Current invalid output attempt number.
250        attempt: u32,
251        /// Detailed error message from XSD validation, formatted for AI retry.
252        ///
253        /// This is the output of `XsdValidationError::format_for_ai_retry()` and includes:
254        /// - Error type and location
255        /// - What was expected vs. what was found
256        /// - Actionable suggestions for fixing
257        /// - Examples of correct format
258        error_detail: Option<String>,
259    },
260}