The _rollback_completed_actions method was a no-op that only logged
actions without actually performing any undo operations. This breaks
the atomic cascade guarantee described in its docstring.
When a cascade fails mid-way, _rollback_completed_actions is now
called in reverse order. For actions that rolled back a sandbox
(sandbox_rolled_back=True), the sandbox is re-rolled-back to ensure
it's left in a clean state before logging. This call is idempotent
since sandbox rollback is designed to be safe to call on already
clean sandboxes.
This restores the atomicity guarantee: all completed actions are
properly undone on failure, not just logged.
The _rollback_completed_actions method was only logging rollback
intent but never actually performing undo operations. On cascade
failure, completed actions were left in an applied state, violating
the atomic cascade guarantee documented in the service docstring.
For each completed action in reverse order, the rollback handler now:
- Re-cancels the child plan (idempotent: cancelling an already-cancelled
plan is a safe no-op).
- If sandbox_rolled_back is true, also rolls back the sandbox.
Individual rollback step failures are logged and do not prevent other
rollback steps from being attempted (best-effort).
ISSUES CLOSED: #9435