fix(TASK-019): carry PIPELINE-FAULT prefix through verdict.py's crash guard

render.py's empty-diff stub bypass is anchored on the 'PIPELINE-FAULT:'
prefix in reason/attention, but verdict.py's crash guard emitted
'verdict computation error: …' / 'verdict script error: …' without it —
on an empty diff a crashed verdict gate collapsed into the
'No changes to review.' stub and the fail-closed NEEDS-HUMAN verdict
never reached the final report.

- prefix the crash-guard reason and attention entry with PIPELINE-FAULT:
- strengthen the existing crash test to assert the prefix on both fields
- add R5 chained test: empty diff + crash-inducing state piped
  verdict.py -> render.py must render the fault, never the stub
- add crash-guard symmetry tests for parse_fault.py / aux_fault.py
  (raw non-JSON GRAPH_STATE keeps the fault marker) and a test that a
  fault survives the attention[:5] cap alongside 6 user flags
This commit is contained in:
Dark-Alex-17 committed 2026-09-14 10:50:33 -06:00
1 parent 4e72c6f5e6
commit a8496aa50e
2 files changed
+136 -4

No files matched your search

@@ -196,9 +196,13 @@ except Exception as e: # noqa: BLE001 — never crash into a silent verdict
{
"verdict_out": {
"verdict": "NEEDS-HUMAN",
"reason": f"verdict computation error: {e} — treat as needing human review",
# PIPELINE-FAULT prefix is load-bearing: render.py's
# empty-diff stub bypass anchors on it — without it a
# crashed gate on an empty diff collapses into the
# "No changes to review." stub.
"reason": f"PIPELINE-FAULT: verdict computation error: {e} — human review required",
"counts": {}, "deferred_count": 0, "dropped_count": 0,
"dropped_titles": [], "attention": [f"verdict script error: {e}"],
"dropped_titles": [], "attention": [f"PIPELINE-FAULT: verdict script error: {e}"],
"findings_final": [],
}
}