Parent: #431
Part of epic: "Compensate the branch a failed worker abandons"
Add CompensationKind.DELETE_BRANCH to tasks/saga.py and teach control/recovery.py to discharge it. Extend reconcile_stale_sagas() to accept a reap_branch(branch) callback and add DELETE_BRANCH to _HANDLED_COMPENSATION_KINDS so a saga carrying it is eligible for full compensation (not quarantine). Primary falsifiable acceptance: given a stale saga whose compensations include a DELETE_BRANCH targeting 'loop/42', reconcile invokes reap_branch('loop/42') exactly once and transitions the saga to COMPENSATED.
Customer story
As an operator who must not babysit orphan branches: when a stale worker's lease expires, recovery should delete the branch the saga created, not just its worktree.
Parent: #431
Part of epic: "Compensate the branch a failed worker abandons"
Add CompensationKind.DELETE_BRANCH to tasks/saga.py and teach control/recovery.py to discharge it. Extend reconcile_stale_sagas() to accept a reap_branch(branch) callback and add DELETE_BRANCH to _HANDLED_COMPENSATION_KINDS so a saga carrying it is eligible for full compensation (not quarantine). Primary falsifiable acceptance: given a stale saga whose compensations include a DELETE_BRANCH targeting 'loop/42', reconcile invokes reap_branch('loop/42') exactly once and transitions the saga to COMPENSATED.
Customer story
As an operator who must not babysit orphan branches: when a stale worker's lease expires, recovery should delete the branch the saga created, not just its worktree.