From d61d06356e43b45b92f97749d3d7a86d4cbfd67c Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 9 Mar 2026 17:39:35 -0400 Subject: [PATCH] Add `retro` setting to project config to disable retros project-wide Users can now set `[arc] retro = false` in arc.toml instead of passing `--no-retro` on every `arc run` invocation. Co-Authored-By: Claude Opus 4.6 --- .../arc-workflows/src/cli/project_config.rs | 26 +++++++++++++++++++ lib/crates/arc-workflows/src/cli/run.rs | 4 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/crates/arc-workflows/src/cli/project_config.rs b/lib/crates/arc-workflows/src/cli/project_config.rs index cbb5d5b9a..41c1c3fdc 100644 --- a/lib/crates/arc-workflows/src/cli/project_config.rs +++ b/lib/crates/arc-workflows/src/cli/project_config.rs @@ -18,16 +18,23 @@ pub struct ProjectConfig { pub struct ProjectArcConfig { #[serde(default = "default_root")] pub root: String, + #[serde(default = "default_retro")] + pub retro: bool, } fn default_root() -> String { ".".to_string() } +fn default_retro() -> bool { + true +} + impl Default for ProjectArcConfig { fn default() -> Self { Self { root: default_root(), + retro: default_retro(), } } } @@ -112,6 +119,16 @@ fn resolve_workflow_arg_from(arg: &Path, start_dir: &Path) -> PathBuf { } } +/// Check whether retros are enabled in the project config. +/// Returns `true` (the default) if no config is found or on error. +pub fn is_retro_enabled() -> bool { + let start = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); + match discover_project_config(&start) { + Ok(Some((_path, config))) => config.arc.retro, + _ => true, + } +} + /// Resolve the arc root directory from a config file path and its config. /// The returned path is the directory containing `arc.toml` joined with the `root` value. pub fn resolve_arc_root(config_path: &Path, config: &ProjectConfig) -> PathBuf { @@ -136,6 +153,7 @@ mod tests { version: 1, arc: ProjectArcConfig { root: ".".to_string(), + retro: true, }, } ); @@ -147,6 +165,12 @@ mod tests { assert_eq!(config.arc.root, "arc/"); } + #[test] + fn parse_retro_false() { + let config = parse_project_config("version = 1\n[arc]\nretro = false\n").unwrap(); + assert!(!config.arc.retro); + } + #[test] fn parse_version_mismatch() { let err = parse_project_config("version = 2\n").unwrap_err(); @@ -199,6 +223,7 @@ mod tests { version: 1, arc: ProjectArcConfig { root: "arc/".to_string(), + ..Default::default() }, }; assert_eq!( @@ -214,6 +239,7 @@ mod tests { version: 1, arc: ProjectArcConfig { root: ".".to_string(), + ..Default::default() }, }; assert_eq!(resolve_arc_root(config_path, &config), Path::new("/repo/.")); diff --git a/lib/crates/arc-workflows/src/cli/run.rs b/lib/crates/arc-workflows/src/cli/run.rs index 3d214c93e..127d5d674 100644 --- a/lib/crates/arc-workflows/src/cli/run.rs +++ b/lib/crates/arc-workflows/src/cli/run.rs @@ -1004,7 +1004,7 @@ pub async fn run_command( progress_ui.lock().expect("progress lock poisoned").finish(); // Auto-derive retro (always, cheap) and optionally run retro agent - if !args.no_retro { + if !args.no_retro && super::project_config::is_retro_enabled() { let (failed, failure_reason) = match &engine_result { Ok(o) => ( o.status == StageStatus::Fail, @@ -1547,7 +1547,7 @@ async fn run_from_branch( let _ = sandbox.cleanup().await; // Auto-derive retro - if !args.no_retro { + if !args.no_retro && super::project_config::is_retro_enabled() { let (failed, failure_reason) = match &engine_result { Ok(o) => ( o.status == StageStatus::Fail,