# remediation agent broke tab order fix on modal close - how to fix it

## TL;DR

Restore focus on modal close as part of the patch: the agent's tab-order fix must include returning focus to the trigger element when the dialog closes, and the verification must test the close path, not just the open state. One line of why: a modal that traps focus correctly on open but drops it on close strands keyboard users.

## The error, verbatim

```text
RemediationAgentError: tab order regressed on modal close
    patch: focus trap installed (open path verified)
    close_path: focus dropped to body, trigger not restored

```

## Fix it step by step

### Step 1: Reproduce the close regression

```bash
node agent/remediate.js --rule focus-order | rg -i 'close|regress' | head -5
```

Expected: The patch verifies on open but breaks on close.

### Step 2: Confirm focus loss

```bash
node -e "console.log('after close: document.activeElement is body, trigger was #open-btn')"
```

Expected: Manual or scripted check shows focus dropped.

### Step 3: Add focus restoration

```bash
rg -n 'close|restore|focus' agent/patches/modal-focus.js | head -10
```

Expected: Extend the patch: store the trigger on open, restore focus to it on close.

### Step 4: Re-run remediation

```bash
node agent/remediate.js --rule focus-order | tail -4
```

Expected: Open traps focus, close restores it, verification covers both paths.

### Step 5: Add a regression probe

```bash
node agent/run-audit.js --smoke | tail -3
```

Expected: Smoke run passes; schedule it so the breakdown is caught if it ever regresses.

## When to use this skill

- You run an agent that scans UIs for accessibility and it hits this breakdown
- The agent's scan loop stalls, crashes, or loops on this exact failure
- You are hardening an audit agent's error handling for production scans

## When NOT to use this skill

- A human runs the scan manually and it works, this is agent-harness failure handling
- The scan completes and only reports violations, use the rule-specific skills

## Compatibility

Remediation agent with DOM patch primitives. Focus restoration is vanilla JS on dialog close. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### agent modal close focus lost

Same regression, same restoration fix.

### tab order broken after dialog close

Practitioner phrasing.

### the breakdown hits other routes too

Agent failure modes are systemic; apply the hardening to every route the agent covers, not just the one that failed.

## Why it happens

Modal focus patches focus on the open path (trap installation) and forget the close path. When the dialog closes, focus must return to the element that opened it; otherwise it drops to body and the keyboard user loses their place. Agents that verify only the open state report success on a half-fix. The patch is only complete when both transitions are handled, and verification must exercise open and close. Agent breakdowns are systemic: the same failure mode will hit every route, page, or run the agent touches. Harden the harness once (timeouts, loop detection, verification gates) instead of patching per page, and keep breakdown telemetry separate from violation counts.

## Edge cases

- Store the trigger element on open, query it fresh on close in case the DOM changed.
- If the trigger no longer exists on close, fall back to a sensible landmark, never leave focus on body.
- Native dialog with showModal handles return focus automatically, another reason to prefer it.
- Log breakdowns separately from violations in agent telemetry; mixing them hides whether the agent itself is getting more reliable.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_GXNBHRAbh1YFAq_-Uc-xHQ
