mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
#170 made the closure dispatcher auto-resume a `paused` parent before respawning its PM, but only `paused`. A parent that is `blocked` at closure (every descendant already terminal) is an errant/stale block — a child's i_am_blocked propagated, or a PM blocked it and never unblocked — the real dependency is already done. #170 left it as-is, so the respawned PM landed on a blocked parent it cannot submit_up / complete and had to manually `unblock` it first (needs journal:decision) — which models do not reliably do, wedging the whole closure chain forever (observed end-to-end this run: leaf stuck awaiting_pm_review, cell parent blocked, root paused, PMs cycling indefinitely). Add `_auto_recover_blocked_parent` (mirrors `_auto_resume_paused_parent`) and recover `blocked` symmetrically to `paused` in `_maybe_spawn_pm_closure`. `blocked -> in_progress` is lifecycle-valid — it is exactly what `unblock(restore=True)` performs. Scoped to the closure-spawn point (descendants terminal) so a live dependency block is never auto-cleared. Best-effort, like the paused path. 4 new tests mirror the #170 suite (recovered-before-spawn, mutual exclusivity with paused, patch shape, error-swallowing). make quality green.