fix(lifecycle): let a PM recover its rejected coordination task from needs_revision

The in-path PR-review gate created a deadlock: when an assembled cell→root /
root→master PR fails the gate (pr_fail) — or qa_fail / ceo_reject fires — the
PM-owned coordination task lands in needs_revision, which was developer-claim-
only. So the task had no actor and no exit but cancel, and the cell PM escalated
in a loop (8KB of [ESCALATED] dev_notes on one task). Pre-gate, the PM simply
re-delegated from in_progress; the gate routed the failure through the PM's own
task instead.

Add NEEDS_REVISION to the CELL_PM / MAIN_PM claim rules so the PM re-claims via
i_will_plan, revises the plan, and re-delegates the fixes — pr_fail/qa_fail
already reassign the failed task to its owning PM and the revision dispatcher
re-spawns it; the claim rule was the only missing piece.

Scope is by give_me_work routing (offers only the caller's own assigned tasks),
the same mechanism that scopes a developer's leaf-revision — NOT a gateway-only
ownership gate, which would violate the spec=gateway parity invariant and can't
use task_type anyway (main-PM coordination roots can be code-typed). Regenerates
panel/lib/lifecycle.json.
This commit is contained in:
Renn F
2026-06-21 06:09:59 +02:00
parent 3ff6967b9d
commit 8463808616
5 changed files with 127 additions and 5 deletions
@@ -1067,6 +1067,11 @@ class Choreographer:
Per-role claim authority (CLAIM_RULES) is enforced inside
spec.can_invoke_action when action == "claim", called by
can_invoke_intent, so no separate spec.can_claim call is needed.
A PM recovering a NEEDS_REVISION coordination task is scoped by
give_me_work routing (it only ever offers an agent its OWN assigned
tasks), exactly as developer leaf-revisions are — not by a gateway-only
ownership gate, which would diverge from the spec (the parity invariant
requires gateway authorization == spec authorization).
"""
t, briefing, role_str = ctx.task, ctx.briefing, ctx.role_str
verb_name = ctx.verb_name