* fix(orchestrator): task-scoped oscillation breaker for escalate/unblock ping-pong
An escalation ping-pong oscillates a task between two agents (cell PM
escalate_up -> BLOCKED -> main PM unblock -> restored -> respawn ->
escalate again). The per-(agent, task) respawn gate never trips on it:
the restored side is dispatched by _dispatch_claimed_without_agent,
which consults no respawn counter at all, so one side of the round trip
always has fuel regardless of the other's strikes — and even a tripped
main-PM counter only stalls the task silently at blocked instead of
surfacing the oscillation.
- Strikes are counted task-scoped at the unblock() chokepoint
(agent-agnostic; legitimate needs_revision rework never calls
unblock, so it structurally cannot trip this), durable in the
existing orchestration_markers column — no migration.
- Progress between round-trips (commits / revision_count advancing)
resets the count: real forward motion is not an oscillation.
- On trip: the task is blocked with a HUMAN resolver (the budget-breach
posture), both dispatchers stop respawning onto it, further unblock()
refuses until an admin override clears the marker, and the CEO
notification names both agents and the cycle count.
- _notification_has_live_work now treats a HITL-blocked related task as
no live work, closing the same loop for the admin-route escalation
path.
* fix(orchestrator): wire the oscillation trip to the dispatchers and make recovery reachable
- TaskResponse serializes blocker_resolver_type: the dispatchers' HITL-blocked
skip and the notification-path live-work check now actually fire over the
wire instead of only against in-process rows.
- The oscillation marker clears on every human transition out of BLOCKED
(snapshot or not), and the human unblock route treats a tripped task as
the requested intervention: clears the marker and proceeds, while the
agent gateway verb keeps refusing.
- The progress fingerprint includes the terminal-children count, so a
coordination root whose children advanced between escalations resets
instead of accruing toward a false trip.
---------
Co-authored-by: Renn F <rennf93@users.noreply.github.com>