An AI agent built to do Ralph loops - plan mode for planning and ralph mode for implementing.

fix: address Phase 1c re-review — dry_run guard, clippy, fmt

- Move dry_run check BEFORE import_goal call to prevent database writes
- Remove redundant closures in session row-mapping (clippy)
- Remove unused imports from tests
- Run cargo fmt for consistent formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+34 -33
+2 -2
src/graph/session.rs
··· 124 124 )?; 125 125 126 126 let session: Option<Session> = stmt 127 - .query_row([&session_id_owned], |row| map_session_row(row)) 127 + .query_row([&session_id_owned], map_session_row) 128 128 .optional()?; 129 129 130 130 Ok(session) ··· 150 150 )?; 151 151 152 152 let session: Option<Session> = stmt 153 - .query_row([&goal_id_owned], |row| map_session_row(row)) 153 + .query_row([&goal_id_owned], map_session_row) 154 154 .optional()?; 155 155 156 156 Ok(session)
+24 -25
src/main.rs
··· 691 691 rustagent::graph::interchange::ImportStrategy::Merge 692 692 }; 693 693 694 - match rustagent::graph::interchange::import_goal( 695 - &graph_store, 696 - &content, 697 - strategy, 698 - ) 699 - .await 700 - { 701 - Ok(result) => { 702 - if !dry_run { 694 + if dry_run { 695 + // Parse the TOML and show what would be imported without writing 696 + match toml::from_str::<rustagent::graph::interchange::GoalFile>( 697 + &content, 698 + ) { 699 + Ok(goal_file) => { 700 + println!("[DRY RUN] Changes that would be applied:"); 701 + println!(" Nodes to process: {}", goal_file.nodes.len()); 702 + println!(" Edges to process: {}", goal_file.edges.len()); 703 + println!(" Import strategy: {:?}", strategy); 704 + } 705 + Err(e) => println!("Failed to parse TOML: {}", e), 706 + } 707 + } else { 708 + match rustagent::graph::interchange::import_goal( 709 + &graph_store, 710 + &content, 711 + strategy, 712 + ) 713 + .await 714 + { 715 + Ok(result) => { 703 716 println!(" Added nodes: {}", result.added_nodes); 704 717 println!(" Added edges: {}", result.added_edges); 705 718 println!(" Unchanged: {}", result.unchanged); ··· 709 722 if !result.skipped_edges.is_empty() { 710 723 println!(" Skipped edges: {}", result.skipped_edges.len()); 711 724 } 712 - } else { 713 - // Parse the TOML and show what would be imported 714 - match toml::from_str::<rustagent::graph::interchange::GoalFile>( 715 - &content, 716 - ) { 717 - Ok(goal_file) => { 718 - println!("[DRY RUN] Changes that would be applied:"); 719 - println!(" Nodes to process: {}", goal_file.nodes.len()); 720 - println!(" Edges to process: {}", goal_file.edges.len()); 721 - println!(" Import strategy: {:?}", strategy); 722 - } 723 - Err(e) => println!("Failed to parse TOML: {}", e), 724 - } 725 725 } 726 + Err(e) => println!("Import failed: {}", e), 726 727 } 727 - Err(e) => println!("Import failed: {}", e), 728 728 } 729 729 } 730 730 Err(e) => println!("Failed to read file: {}", e), 731 731 }, 732 732 GraphAction::Diff { path } => match std::fs::read_to_string(&path) { 733 733 Ok(content) => { 734 - match rustagent::graph::interchange::diff_goal(&graph_store, &content) 735 - .await 734 + match rustagent::graph::interchange::diff_goal(&graph_store, &content).await 736 735 { 737 736 Ok(result) => { 738 737 println!("Diff results for {}:", path);
+8 -6
tests/interchange_test.rs
··· 1 1 use anyhow::Result; 2 2 use chrono::Utc; 3 3 use rustagent::graph::interchange::{ImportStrategy, diff_goal, export_goal, import_goal}; 4 - use rustagent::graph::store::{GraphStore, SqliteGraphStore}; 4 + use rustagent::graph::store::GraphStore; 5 5 use rustagent::graph::*; 6 - use std::collections::HashMap; 7 - 8 6 mod common; 9 7 use common::*; 10 8 ··· 251 249 let toml_str = export_goal(&graph_store, "ra-test", "test-project").await?; 252 250 253 251 // Modify the TOML to add a new node that doesn't exist and an edge to it 254 - let mut toml_content = toml_str.clone(); 252 + let _toml_content = toml_str.clone(); 255 253 256 254 // Parse and modify 257 255 let mut parsed: toml::Value = toml::from_str(&toml_str)?; ··· 378 376 let parsed_export2: toml::Value = toml::from_str(&export2)?; 379 377 380 378 // Verify nodes are identical between exports (at minimum the counts should match) 381 - let nodes1 = parsed_export1["nodes"].as_table().expect("Export should have nodes"); 382 - let nodes2 = parsed_export2["nodes"].as_table().expect("Import export should have nodes"); 379 + let nodes1 = parsed_export1["nodes"] 380 + .as_table() 381 + .expect("Export should have nodes"); 382 + let nodes2 = parsed_export2["nodes"] 383 + .as_table() 384 + .expect("Import export should have nodes"); 383 385 384 386 // After round-trip, we should have at least the goal node and ideally all original nodes 385 387 // Verify goal exists in both