The material below is a bundle of source-file excerpts, with each original file and line range labeled.
SKILL.md is the entry point; the labeled ranges identify which excerpts are supplied.

--- BEGIN FILE "ios-fix/SKILL.md" (lines 357-426; entrypoint) ---
# Autonomous iOS bug fixer

## Iron Law

**NO FIX WITHOUT A REPRODUCING SNAPSHOT.** Before editing any Swift source,
the agent MUST capture a `GET /state/snapshot` that reproduces the bug.
That snapshot becomes a regression test fixture (`test/fixtures/ios-fix/`).
A fix that lands without a reproducing snapshot is a fix you'll be re-fixing
in three months.

## Phase 1: Reproduce the bug

1. Read the `/ios-qa` finding (bug description, screenshot, suspected
   accessibility-tree node).
2. Bring the device into the bug state via `POST /tap`, `/swipe`, `/type`,
   or `POST /state/<key>` (snapshot-eligible fields only).
3. Capture `GET /state/snapshot` → write to
   `test/fixtures/ios-fix/<bug-slug>-pre.json`.
4. Capture `GET /screenshot` → write to
   `test/fixtures/ios-fix/<bug-slug>-pre.png`.
5. Persist a one-line description of what's wrong + expected behavior.

## Phase 2: Locate root cause

Per `/investigate`'s Iron Law: no fix without root cause. The agent reads the
Swift source, traces from the buggy screen back to the view model, the data
flow, and the state mutation. Identify the smallest change that fixes the
behavior.

Use AskUserQuestion if there are multiple plausible root causes — let the
user pick the one to fix.

## Phase 3: Apply fix

1. Edit Swift source. Keep the diff minimal.
2. Rebuild: `xcodebuild -scheme <SchemeName>
   -destination 'platform=iOS,id=<UDID>' build install`.
3. Daemon detects the rebuild and reconnects the StateServer tunnel.
4. Re-deploy. The same boot-token rotation flow runs.

## Phase 4: Verify

1. `POST /state/restore` with the pre-bug snapshot → reproduces the state.
2. Take a fresh screenshot. Compare against
   `test/fixtures/ios-fix/<bug-slug>-pre.png`.
3. If the bug visibly persists, the fix didn't work — revert and try again
   (max 3 iterations before escalating to the user).
4. If the bug is gone, capture `<bug-slug>-post.png` for the regression test.

## Phase 5: Add regression test

Write a regression test with the project's own test runner and conventions
(the test command in CLAUDE.md; if it has none, ask the user and record the
answer there). The test:

1. Loads the pre-bug snapshot.
2. Restores it via `POST /state/restore`.
3. Asserts the post-fix behavior on a real device, skipped when no device is
   connected.

Commit the snapshot fixture + test file alongside the fix.

## Failure modes

| Symptom | Action |
|---|---|
| 3 iterations, bug still present | STOP, report to user with current best hypothesis |
| `409 schema_mismatch` on /state/restore after rebuild | Regenerate accessors with `/ios-sync` (`gstack-ios-qa-regen`), re-snapshot |
| Device disconnects mid-fix | Daemon auto-reconnects; resume from Phase 4 |
| Build fails | Revert Swift edits; investigate compile error before re-applying fix |

--- END FILE "ios-fix/SKILL.md" ---