## TL;DR
Treat token expiry as a normal mid-run event: catch the auth failure, silently acquire a fresh token, and retry the failed call before continuing. Checkpoint completed steps so a truly dead run can resume instead of restarting.

## Steps
1. Wrap Graph calls so an auth failure triggers a silent token refresh and one retry.
   Expected: Expired tokens no longer kill the run.
2. Checkpoint every completed offboarding step with its result.
   Expected: A restart resumes after the last completed step.
3. Make each step idempotent so a retried call after refresh is safe.
   Expected: Retries never double-apply.
4. Run a 2-hour synthetic offboarding against a test user and confirm completion.
   Expected: The run finishes with one mid-run refresh logged.

## When to use
- Offboarding or provisioning runs take longer than the token lifetime
- Runs die halfway with auth errors and leave partial state
- The agent holds one token for the whole run

## When not to use
- Runs finish in minutes (token lifetime is not a factor)
- Each step uses its own short-lived credential already
- A human supervises the run and can re-authenticate

## Why this happens
Refresh tokens have lifetimes, and a run longer than that lifetime will eventually call an API with a dead credential. Without rotation the run aborts mid-checklist, which for offboarding means the user is half-deprovisioned: mailbox gone, VPN still active.

## Edge cases
- Conditional access can revoke refresh tokens on risk signals mid-run; the resume path must handle that too.
- Checkpoint state must survive the agent process restarting, not just the run continuing.

## Provenance

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