"""U-017: Org-level Loop closed loop (architecture doc §11 MVP acceptance criterion 4) -- ties U-015 (root-cause judgment) + U-016 (routing) + real Coder/Validator calls into one function: given a task sitting at 'validating' with a known bug, autonomously locate root cause, route to the right Org Agent, drive the fix, and re-validate back to 'done'. """ from src import bug_record, org_loop_route, org_node_trigger, root_cause_trace _ROUTE_FOR_CATEGORY = {"coder": "fast_lane", "planning": "full_replan"} def run_fix_loop(conn, task_id, target_folder_path, bug_description, context, fix_prompt, verify_prompt, timeout=300): """Returns {"root_cause_category", "route", "verified", "final_status", "verify_response"}. Raises root_cause_trace.InconclusiveEscalateError if the 3 perspectives don't reach 2/3 agreement (same as U-015 -- this function doesn't add its own fallback for that, matching 04-P's own "升级人工" answer to disagreement).""" perspective_fns = [ root_cause_trace.real_validator_perspective( name, bug_description, context, target_folder_path, trigger_fn=org_node_trigger.trigger_org_node, timeout=timeout, ) for name in ("correctness", "requirement_completeness", "skill_defect") ] judgment = root_cause_trace.judge_root_cause(perspective_fns) category = judgment["root_cause_category"] route = _ROUTE_FOR_CATEGORY.get(category, "full_replan") bug_record.create_bug_record( conn, task_id=task_id, description=bug_description, root_cause_category=category, root_cause_detail=judgment["root_cause_detail"], suggested_route=route, ) org_loop_route.route_org_loop(conn, task_id, route) fixer_node = "coder" if route == "fast_lane" else "planner" org_node_trigger.trigger_org_node(fixer_node, fix_prompt, target_folder_path, timeout=timeout) verify_response = org_node_trigger.trigger_org_node("validator", verify_prompt, target_folder_path, timeout=timeout) verified = "PASS" in verify_response.upper() if verified: # A real Work Graph would move coding/planning_brd_prd_sdd back to # 'validating' once the fixer's own Work Graph completes (U-011/012/013, # same mechanism U-014 uses) -- no separate controller exists for that # hop, so this mirrors it directly rather than inventing one just for # this Unit. conn.execute("UPDATE task SET status = 'validating' WHERE task_id = ?", (task_id,)) conn.commit() org_loop_route.close_task_done(conn, task_id) final_status = "done" else: final_status = conn.execute("SELECT status FROM task WHERE task_id = ?", (task_id,)).fetchone()[0] return { "root_cause_category": category, "route": route, "verified": verified, "final_status": final_status, "verify_response": verify_response, }