From 051c801533a850436491b88400f5e0439fee23aa Mon Sep 17 00:00:00 2001 From: Shivakumar Date: Wed, 19 Aug 2026 09:40:53 +0530 Subject: [PATCH 1/2] fix: apply filtered PATH in run_in_lines_bounded; fix orphan-reconcile label/assignee ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run_in_lines_bounded was the one git-spawn site PR #537 missed when wiring apply_filtered_path through every other call site — it can still hit E2BIG on a daemon with a PATH bloated by repeated dispatches. restore_ready_for_work added the ready-for-work label before restoring assignee_agent via two non-transactional DB calls; a failure between them reproduces item #150's bug (labeled ready-for-work, no assignee_agent). Reordered so assignee_agent is restored first. Agentflare-Agent: claude-code_2-1-234_agent Agentflare-Branch: task/514-fix-apply-filtered-path-to-run-in-lines Agentflare-Item: 514 --- crates/flare-git-core/src/shell.rs | 1 + src/dashboard/orphan_reconcile.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/flare-git-core/src/shell.rs b/crates/flare-git-core/src/shell.rs index 92ecadb0..f8917629 100644 --- a/crates/flare-git-core/src/shell.rs +++ b/crates/flare-git-core/src/shell.rs @@ -267,6 +267,7 @@ pub fn run_in_lines_bounded( .stdout(Stdio::piped()) .stderr(Stdio::piped()); no_console_window(&mut cmd); + apply_filtered_path(&mut cmd); let mut child = cmd .spawn() .map_err(|e| BoundedLinesError::Git(format!("git not available: {e}")))?; diff --git a/src/dashboard/orphan_reconcile.rs b/src/dashboard/orphan_reconcile.rs index b438a21b..5d4d40a5 100644 --- a/src/dashboard/orphan_reconcile.rs +++ b/src/dashboard/orphan_reconcile.rs @@ -97,7 +97,6 @@ fn restore_ready_for_work(mcp: &crate::mcp_server::AgentflareMcp, item_id: &str, { let _ = agentflare_backend::item::remove_label(conn, item_id, &dispatched_id.id); } - agentflare_backend::item::add_label(conn, item_id, ready_id).ok()?; agentflare_backend::item::update( conn, item_id, @@ -107,6 +106,7 @@ fn restore_ready_for_work(mcp: &crate::mcp_server::AgentflareMcp, item_id: &str, }, ) .ok()?; + agentflare_backend::item::add_label(conn, item_id, ready_id).ok()?; Some(()) }); } From af180ce27bcbbe650f1276b8d3e3a7a791c8e8c8 Mon Sep 17 00:00:00 2001 From: Shivakumar Date: Wed, 19 Aug 2026 11:20:20 +0530 Subject: [PATCH 2/2] fix(dashboard): wrap restore_ready_for_work's label/assignee writes in one transaction CodeRabbit finding on PR #556: remove_label/update/add_label ran as three independent, non-atomic writes with errors discarded via .ok()? -- a failure partway through could leave the item in an inconsistent state (no scheduling label, or dispatched still attached) with no rollback. Wraps them in an explicit BEGIN/COMMIT/ROLLBACK. Agentflare-Agent: claude-code_2-1-235_agent Agentflare-Branch: task/514-fix-apply-filtered-path-to-run-in-lines Agentflare-Item: 514 --- src/dashboard/orphan_reconcile.rs | 44 +++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/dashboard/orphan_reconcile.rs b/src/dashboard/orphan_reconcile.rs index 5d4d40a5..24f219f9 100644 --- a/src/dashboard/orphan_reconcile.rs +++ b/src/dashboard/orphan_reconcile.rs @@ -91,23 +91,39 @@ fn restore_ready_for_work(mcp: &crate::mcp_server::AgentflareMcp, item_id: &str, .iter() .find(|l| l.name == crate::supervisor::READY_LABEL)? .id; - if let Some(dispatched_id) = labels + let dispatched_id = labels .iter() .find(|l| l.name == crate::supervisor::DISPATCHED_LABEL) - { - let _ = agentflare_backend::item::remove_label(conn, item_id, &dispatched_id.id); + .map(|l| l.id.clone()); + + // Single transaction: a failure partway through must not leave the + // item labeled ready-for-work with no assignee (item #150) or with + // `dispatched` still attached (item #99) -- `with_backend_db` gives + // no rollback of its own, so this crate does it explicitly instead + // of discarding a mid-sequence error via `.ok()?` and continuing. + conn.execute_batch("BEGIN").ok()?; + let result: agentflare_backend::error::Result<()> = (|| { + if let Some(dispatched_id) = &dispatched_id { + agentflare_backend::item::remove_label(conn, item_id, dispatched_id)?; + } + agentflare_backend::item::update( + conn, + item_id, + agentflare_backend::item::UpdateItem { + assignee_agent: Some(agent.to_string()), + ..Default::default() + }, + )?; + agentflare_backend::item::add_label(conn, item_id, ready_id)?; + Ok(()) + })(); + match result { + Ok(()) => conn.execute_batch("COMMIT").ok(), + Err(_) => { + let _ = conn.execute_batch("ROLLBACK"); + None + } } - agentflare_backend::item::update( - conn, - item_id, - agentflare_backend::item::UpdateItem { - assignee_agent: Some(agent.to_string()), - ..Default::default() - }, - ) - .ok()?; - agentflare_backend::item::add_label(conn, item_id, ready_id).ok()?; - Some(()) }); }