ralph_workflow/app/
finalization.rs

1//! Pipeline finalization and cleanup.
2//!
3//! This module handles the final phase of the pipeline including cleanup,
4//! final summary, and checkpoint clearing.
5
6use crate::banner::{print_final_summary, PipelineSummary};
7use crate::checkpoint::clear_checkpoint;
8use crate::config::Config;
9use crate::files::make_prompt_writable;
10use crate::files::protection::monitoring::PromptMonitor;
11use crate::logger::Colors;
12use crate::logger::Logger;
13use crate::pipeline::Timer;
14use crate::pipeline::{AgentPhaseGuard, Stats};
15
16/// Finalizes the pipeline: cleans up and prints summary.
17///
18/// Commits now happen per-iteration during development and per-cycle during review,
19/// so this function only handles cleanup and final summary.
20pub fn finalize_pipeline(
21    agent_phase_guard: &mut AgentPhaseGuard,
22    logger: &Logger,
23    colors: Colors,
24    config: &Config,
25    timer: &Timer,
26    stats: &Stats,
27    prompt_monitor: Option<PromptMonitor>,
28) {
29    // Stop the PROMPT.md monitor if it was started
30    if let Some(monitor) = prompt_monitor {
31        monitor.stop();
32    }
33
34    // End agent phase and clean up
35    crate::git_helpers::end_agent_phase();
36    crate::git_helpers::disable_git_wrapper(agent_phase_guard.git_helpers);
37    if let Err(err) = crate::git_helpers::uninstall_hooks(logger) {
38        logger.warn(&format!("Failed to uninstall Ralph hooks: {err}"));
39    }
40
41    // Note: Individual commits were created per-iteration during development
42    // and per-cycle during review. The final commit phase has been removed.
43
44    // Final summary
45    let summary = PipelineSummary {
46        total_time: timer.elapsed_formatted(),
47        dev_runs_completed: stats.developer_runs_completed as usize,
48        dev_runs_total: config.developer_iters as usize,
49        review_runs: stats.reviewer_runs_completed as usize,
50        changes_detected: stats.changes_detected as usize,
51        isolation_mode: config.isolation_mode,
52        verbose: config.verbosity.is_verbose(),
53        review_summary: None,
54    };
55    print_final_summary(colors, &summary, logger);
56
57    if config.features.checkpoint_enabled {
58        if let Err(err) = clear_checkpoint() {
59            logger.warn(&format!("Failed to clear checkpoint: {err}"));
60        }
61    }
62
63    // Restore PROMPT.md write permissions so users can edit it normally
64    // This is important to ensure users can edit PROMPT.md after pipeline completion
65    if let Some(warning) = make_prompt_writable() {
66        // Make this visible even if stdout is redirected or logger filtering is enabled.
67        eprintln!("{warning}");
68        eprintln!("If PROMPT.md is still read-only, run: chmod u+w PROMPT.md");
69        logger.warn(&warning);
70    }
71
72    agent_phase_guard.disarm();
73}