From 80c20afcddba30f30a5018ca13f4f31a5cf74a29 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Sat, 12 Sep 2026 16:01:42 -0600 Subject: [PATCH] test(TASK-018): cover parse_fault.py fault normalization --- src/config/request_context.rs | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/config/request_context.rs b/src/config/request_context.rs index a91cce7..cdaa788 100644 --- a/src/config/request_context.rs +++ b/src/config/request_context.rs @@ -8950,6 +8950,59 @@ mod tests { ); } + #[test] + fn gauntlet_parse_fault_records_fault_in_signals_error() { + if !cmd_available("python3") { + eprintln!("skipping: python3 not available"); + return; + } + let out = run_gauntlet_script( + "parse_fault.py", + &json!({"parse_failure": "LLM node 'parse' failed: provider exploded"}), + ); + let fault = out["signals_error"].as_str().unwrap(); + assert!( + fault.contains("PIPELINE-FAULT: parse failed"), + "a dead parse stage must surface as a PIPELINE-FAULT: {fault}" + ); + assert!( + fault.contains("provider exploded"), + "the failure detail must be carried into the fault: {fault}" + ); + } + + #[test] + fn gauntlet_parse_fault_blocks_verdict_gate() { + if !cmd_available("python3") { + eprintln!("skipping: python3 not available"); + return; + } + // End-to-end over the fallback route: parse_fault's emitted + // signals_error must make the gate BLOCK even with every lane empty. + let fault = run_gauntlet_script( + "parse_fault.py", + &json!({"parse_failure": "LLM node 'parse' failed: provider exploded"}), + ); + let state = json!({ + "code_review_results": [], + "adversary_results": [], + "security_results": [], + "probe_results": [], + "signals_error": fault["signals_error"] + }); + let out = run_gauntlet_script("verdict_gate.py", &state); + assert_eq!(out["gauntlet_verdict"], "BLOCKED"); + let report = out["gauntlet_report"].as_str().unwrap(); + assert!( + report.contains("## Blockers\n- pipeline: PIPELINE-FAULT: parse failed"), + "the parse fault must appear in the Blockers section: {report}" + ); + assert!( + report.contains("provider exploded"), + "the failure detail must survive into the report: {report}" + ); + } + #[test] fn gauntlet_default_lanes_is_deterministic() { if !cmd_available("python3") {