Discovered while smoke-testing the #60 builder fix on the R720: a task that reaches the human plan-gate and is APPROVED never built. The gate's GATE_APPROVE_ROUTE was hard-wired to END in build_graph, so plan_gate_node set phase=BUILD/status=ACTIVE and the graph terminated WITHOUT entering the build subgraph — the task wedged at phase=build with no build, no error. Only the reviewer's auto-approve path (review -> build_node) reached the builder; every human-gate-approved plan silently dead-ended. The P3 splice only repoints the REVIEW node's build route to BUILD_NODE; the plan_gate edges are independent and were never updated, so even with P3 fully wired the gate approve went to END. _apply_plan_decision's 'settle exactly as an auto-approved plan' intent was broken by the edge map. - graph.py: when build_verify (P3) is wired, point GATE_APPROVE_ROUTE at BUILD_NODE (mirroring REVIEW's BUILD_ROUTE: BUILD_NODE); keep END when P3 is inert (P2 approved-plan terminus). LangGraph resolves the forward reference to BUILD_NODE at compile(). - tests: gate-approve with P3 wired traverses BUILD -> VERIFY -> DONE on an authenticated CI pass, and parks at VERIFY (never fabricates a pass) when the CI fetcher is inert. Existing P2 gate-approve -> END behavior unchanged. |
||
|---|---|---|
| .. | ||
| db | ||
| nodes | ||
| transport | ||
| __init__.py | ||
| api.py | ||
| billing.py | ||
| ci_fetcher.py | ||
| ci_gate.py | ||
| ci_watcher.py | ||
| coordinator.py | ||
| dashboard.py | ||
| deadline_timer.py | ||
| decisions.py | ||
| dispatcher.py | ||
| draft_pr_monitor.py | ||
| graph.py | ||
| invoker.py | ||
| invoker_multi.py | ||
| ledger.py | ||
| operator_cli.py | ||
| recovery.py | ||
| responder.py | ||
| resume_worker.py | ||
| state_store.py | ||
| status_page.py | ||
| task_model.py | ||
| topology.py | ||