## TL;DR
The agent waits for an enrollment signal that never arrives in the form it expects. Define an explicit completion check, cap the iterations, and time out to a human queue with the state captured.

## The query
```text
mfa-reset agent looped on the qr enrollment step: missing exit condition
```

## Use this when
- the agent loops on the QR enrollment step
- enrollment actually succeeded but the agent did not notice
- the run never terminates

## Not for
- users unable to scan the QR code
- authenticator app problems
- admin-side MFA reset in the IdP

## Steps
1. Check whether the enrollment actually completed despite the loop; often it did. Expected output: the true enrollment state is known.
2. Define the completion signal explicitly: the new auth method appearing on the user record. Expected output: a checkable success condition.
3. Cap the loop at a small iteration count with a total timeout. Expected output: the run always terminates.
4. On timeout, capture the state and hand to a human instead of retrying forever. Expected output: a ticket with full context exists.
5. Add a post-step verification that the loop condition clears. Expected output: false loops are caught in testing.

## Applies to
MFA reset automation, Okta, Entra ID, Duo, agent orchestration frameworks.

## Variant phrasings
### Loop because the user never scans
Separate user-wait from agent-wait; the agent should park, not spin.

### Enrollment API is eventually consistent
Poll with backoff for the completion signal rather than checking once.

## Why it happens
Loops happen when the exit condition checks the wrong thing or nothing at all. Enrollment involves a human and an async backend, so the signal must be explicit and patient.

## Edge cases
- Never auto-retry enrollment indefinitely; each attempt can spam the user.
- Log the iteration count; a rising count is the early warning.
- Test with a user who abandons the flow to see the timeout path.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_HoLqKv0HXuTX28HHL-qSQw
