## TL;DR
Work the backlog directly: export HR terminations and IdP actives, diff them, bulk-deprovision the zombies, remove their app licenses, then fix the offboarding workflow trigger so the backlog stops growing.

```text
failed to deprovision zombie accounts consuming paid seats after offboarding
```

## Use this when
- Terminated employees still show active in the IdP.
- Paid seat counts stay high after departures.
- Offboarding is believed to work but the numbers say otherwise.

## Not for this skill when
- The users are actually active. That is a license optimization question.
- The IdP is correct but apps hold licenses. That is per-app cleanup.
- There is no HR feed to diff against. Build the source of truth first.

## Steps
1. Export HR terminations and IdP actives for the same period. Verify: both lists are complete.
2. Diff them to find terminated-but-active accounts. Verify: each one is genuinely terminated.
3. Bulk-deprovision the zombies. Verify: their IdP status changes.
4. Remove their app licenses. Verify: seat counts drop.
5. Fix the offboarding workflow trigger, the HR feed or the scheduled job that missed them. Verify: the next cycle's diff is empty.

## Variant phrasings
### zombie accounts licenses
The short search.
### offboarding backlog
The cause-first phrasing.
### terminated users active
The state-first search.

Compatibility: Any HR system plus IdP combination.

## Why it happens
The offboarding trigger broke silently, through a dead HR feed, a disabled scheduled job, or a changed field name. The backlog is the symptom; the trigger is the disease.

## Edge cases / pitfalls
- Contractors not in the HR feed; they need their own trigger.
- Shared accounts that look like zombies but are still needed; verify before deprovisioning.
- The HR feed using a different identifier than the IdP; normalize before diffing.
- Rehires appearing as terminated in a stale HR export; check dates.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_YjJr5YwrngUZxohzWbj5tA
