Fix planner deadlock when triage goes stale mid-cycle#413
Fix planner deadlock when triage goes stale mid-cycle#413imetandy wants to merge 1 commit intopeteromallet:mainfrom
Conversation
peteromallet
left a comment
There was a problem hiding this comment.
Review
The core logic is sound — the four-part condition correctly identifies the deadlock state and the fix breaks the cycle in the right way (objective resolves proceed, review resolves stay blocked).
Looks good
- The
pending_behind_objective_backlogdetection at guardrails.py:55-59 is the right set of conditions - Lifecycle copy change ("Triage is pending behind...") is clearer than the old "Cannot start triage" framing
- Test coverage hits the main cases (status marking, messaging, objective allowed, review blocked)
Minor suggestions
-
Duplicated condition logic — the four-part pending check appears in both
guardrails.py:55-59andplan_triage.py:83-87. If the definition changes, both need updating. Worth a cross-referencing comment at minimum, since the banner function can't depend on the app-layer guardrails. -
_REVIEW_DETECTORSis a subset ofNON_OBJECTIVE_DETECTORS— intentional, but a comment explaining why would help (it only needs direct review work, not all non-objective detectors). Easy to miss when a new review-like detector gets added later. -
Missing test paths — no test for
require_triage_current_or_exitwithpatterns=None(falls through to CommandError at line 149), and no test for mixed patterns that include both objective and review issues (currently the whole batch gets blocked, which is correct but undocumented). -
cmd.py:77— theplan=plan_access.plan if isinstance(plan_access.plan, dict) and not plan_access.degraded else Noneline is quite long. A local variable would clean it up.
Overall this is a solid fix for a real deadlock. Approval-worthy with the minor suggestions above.
Summary
I ran into a planner deadlock after a trusted review import landed mid-cycle. New review issues made triage stale, but I still had open objective work in the queue. In that state,
desloppify plan resolve ... --confirmwas blocked because triage was stale, whiledesloppify plan triage --run-stages --runner codexwas also blocked because objective backlog was still open.This change makes that state consistent instead of deadlocking it. When triage is stale but still deferred behind objective backlog, objective resolves can continue, direct review resolves stay blocked, and the CLI now says
TRIAGE PENDINGinstead of nudging me toward a triage command that cannot run yet.What I changed
fixedresolves to proceed in that pending stateTRIAGE PENDINGTesting