End-to-end validation surfaced that auto-dispatch parked every task at "empty declared_scope": dispatch_node required plan["scope"], but the planner emits only summary+phases (never a scope) and config.allowed_scope defaults to None, so no node ever populated it. (The earlier dispatch test was operator-initiated with an explicit scope; the auto planner->build->dispatch path was never exercised until box-side App dispatch went live.) Fix: when no planner-/operator-declared scope is present, dispatch_node derives declared_scope from the candidate diff's own touched paths (ci_gate.diff_touched_paths). This supplies the missing scope without relaxing any CI trust control — the apply/verify workflow still INDEPENDENTLY re-checks the materialized diff against the denylist + '..'-escape + this scope + the diff-hash binding, and the agent-apply environment's required reviewer remains the human gate. A non-empty diff that parses to zero touched paths still parks (fail closed). Tests: the three old park-on-missing-scope cases now assert scope-from-diff dispatch; added a park case for a diff with no parseable paths. 1527 pass. |
||
|---|---|---|
| .. | ||
| 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 | ||
| github_app.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 | ||