diff --git a/orchestrator/main.py b/orchestrator/main.py index df7e55b..d3a9eb4 100644 --- a/orchestrator/main.py +++ b/orchestrator/main.py @@ -678,7 +678,13 @@ async def refresh_swarm_run_status(run): await swarm_runtime.save_run(run) return - next_status = "failed" if any(task.status == TaskStatus.FAILED for task in tasks) else "completed" + # Failure isolation (SC-12): a single failed task must NOT sink the whole run (e.g. one task + # tripped a transient LLM-gateway 404). Declare the run failed ONLY when there is no completed + # work to deliver; otherwise take the completed path and let the Queen / convergence judge + # acceptability (the failure is still surfaced in convergence termination_reason). + failed_tasks = [t for t in tasks if t.status == TaskStatus.FAILED] + completed_tasks = [t for t in tasks if t.status == TaskStatus.COMPLETED] + next_status = "failed" if (failed_tasks and not completed_tasks) else "completed" # Master review-and-iterate gate: before declaring success, optionally run the critic and # send rejected work back to the specialists. Off unless ENABLE_REVIEW_LOOP is set, so the