From 7dc950a09274dd600f231e12bd81efd0789fb327 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Sat, 12 Sep 2026 14:50:40 -0600 Subject: [PATCH] test(TASK-016): assert the fallback warn names the node id and fallback target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The adversary conformance review flagged that the fallback warn! at outcome_from (src/graph/agent.rs:71) was never asserted — only the retry warn had captured-text coverage. Adds one test installing the shared warn collector, filtered by the unique node id 'fallback_warn_capture' for parallel safety, asserting the warn names both the node and the fallback target and carries the error chain. --- src/graph/agent.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/graph/agent.rs b/src/graph/agent.rs index 751bae7..23a94f4 100644 --- a/src/graph/agent.rs +++ b/src/graph/agent.rs @@ -796,6 +796,44 @@ mod tests { assert!(failure.contains("no JSON object found"), "{failure}"); } + #[test] + fn outcome_from_fallback_warn_names_the_node_and_the_fallback_target() { + install_warn_collector(); + let mut node = node_with("hi", None); + node.fallback = Some("recover".into()); + let mut state = manager_with(&[]); + + let outcome = outcome_from( + "fallback_warn_capture", + &node, + &mut state, + Err(extraction_error()), + ) + .unwrap(); + + assert_eq!(outcome, AgentExecutionOutcome::FellBack("recover".into())); + let warns: Vec = warn_messages() + .lock() + .unwrap() + .iter() + .filter(|m| m.contains("'fallback_warn_capture'")) + .cloned() + .collect(); + assert_eq!(warns.len(), 1, "exactly one fallback warn: {warns:?}"); + assert!( + warns[0].contains( + "agent node 'fallback_warn_capture' failed, routing to fallback 'recover'" + ), + "{}", + warns[0] + ); + assert!( + warns[0].contains("Agent 'test_agent' output failed structured-output extraction"), + "warn must carry the error chain: {}", + warns[0] + ); + } + #[test] fn outcome_from_failure_without_fallback_propagates_the_error_unchanged() { let node = node_with("hi", Some(failure_capture_updates()));