org_level_loop.py
3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""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).
**F (2026-08-06, docs/done/verifier-fan-out-jury-design.md)**: root
cause judgment now runs as a real Work Graph fan-out (each perspective
is its own Work Node with its own clean context) instead of three
sequential Python closures calling org_node_trigger.trigger_org_node --
see root_cause_trace.judge_root_cause_via_work_graph. The fixer/verify
calls below are unchanged flat trigger_org_node calls; only root-cause
judgment moved."""
judgment = root_cause_trace.judge_root_cause_via_work_graph(
conn, task_id, target_folder_path, bug_description, context, timeout=timeout,
)
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,
}