diff --git a/Cargo.toml b/Cargo.toml index 116d6883a..1ab3e532d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,7 +71,7 @@ slatedb = "0.11.2" object_store = "0.12.5" [workspace.lints.rust] -unsafe_code = "warn" +unsafe_code = "deny" unreachable_pub = "warn" [workspace.lints.clippy] diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs b/lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs index 9424508d6..25dd749a6 100644 --- a/lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs +++ b/lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_code)] + use std::os::unix::process::CommandExt; use std::process::{Child, Command}; use tracing::{debug, warn}; diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs b/lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs index 419887dec..e9c00c46f 100644 --- a/lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs +++ b/lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_code)] + use core_foundation::base::TCFType; use tracing::{debug, warn}; diff --git a/lib/crates/fabro-workflow/src/handler/llm/cli.rs b/lib/crates/fabro-workflow/src/handler/llm/cli.rs index 7b43ab6b6..271084765 100644 --- a/lib/crates/fabro-workflow/src/handler/llm/cli.rs +++ b/lib/crates/fabro-workflow/src/handler/llm/cli.rs @@ -851,20 +851,16 @@ mod tests { /// Mock sandbox that returns pre-configured ExecResults in FIFO order. struct CliMockSandbox { results: Mutex>, - commands: Mutex>, + commands: Arc>>, } impl CliMockSandbox { - fn new(results: Vec) -> Self { + fn new(results: Vec, commands: Arc>>) -> Self { Self { results: Mutex::new(results.into()), - commands: Mutex::new(Vec::new()), + commands, } } - - fn commands(&self) -> Vec { - self.commands.lock().unwrap().clone() - } } #[async_trait] @@ -966,45 +962,53 @@ mod tests { } #[tokio::test] - #[allow(unsafe_code)] async fn ensure_cli_skips_install_when_present() { - let sandbox: Arc = Arc::new(CliMockSandbox::new(vec![ok_result()])); + let commands = Arc::new(Mutex::new(Vec::new())); + let sandbox: Arc = Arc::new(CliMockSandbox::new( + vec![ok_result()], + Arc::clone(&commands), + )); let emitter = Arc::new(EventEmitter::default()); let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await; assert!(result.is_ok()); - let mock = sandbox.as_ref() as *const dyn Sandbox as *const CliMockSandbox; - let commands = unsafe { &*mock }.commands(); + let commands = commands.lock().unwrap(); assert_eq!(commands.len(), 1); assert!(commands[0].contains("claude --version")); } #[tokio::test] - #[allow(unsafe_code)] async fn ensure_cli_installs_when_missing() { + let commands = Arc::new(Mutex::new(Vec::new())); // version check fails, combined install succeeds - let sandbox: Arc = Arc::new(CliMockSandbox::new(vec![ - fail_result(127), // claude --version - ok_result(), // combined node + npm install - ])); + let sandbox: Arc = Arc::new(CliMockSandbox::new( + vec![ + fail_result(127), // claude --version + ok_result(), // combined node + npm install + ], + Arc::clone(&commands), + )); let emitter = Arc::new(EventEmitter::default()); let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await; assert!(result.is_ok()); - let mock = sandbox.as_ref() as *const dyn Sandbox as *const CliMockSandbox; - let commands = unsafe { &*mock }.commands(); + let commands = commands.lock().unwrap(); assert_eq!(commands.len(), 2); assert!(commands[1].contains("npm install -g @anthropic-ai/claude-code")); } #[tokio::test] async fn ensure_cli_fails_on_install_failure() { - let sandbox: Arc = Arc::new(CliMockSandbox::new(vec![ - fail_result(127), // claude --version - fail_result(1), // combined install fails - ])); + let commands = Arc::new(Mutex::new(Vec::new())); + let sandbox: Arc = Arc::new(CliMockSandbox::new( + vec![ + fail_result(127), // claude --version + fail_result(1), // combined install fails + ], + Arc::clone(&commands), + )); let emitter = Arc::new(EventEmitter::default()); let result = ensure_cli(AgentCli::Claude, Provider::Anthropic, &sandbox, &emitter).await;