mirror of https://github.com/garrytan/gstack.git
102 lines
3.5 KiB
Cheetah
102 lines
3.5 KiB
Cheetah
---
|
|
name: ios-fix
|
|
preamble-tier: 3
|
|
version: 1.0.0
|
|
description: |
|
|
Autonomous iOS bug fixer. Takes a bug found by /ios-qa, reads the source,
|
|
writes the fix, rebuilds, redeploys, and verifies the fix on the real
|
|
device. Closes the loop: find bug → fix bug → confirm fix — zero human
|
|
intervention. Captures the pre-bug state snapshot as a regression test
|
|
fixture, so the bug can never recur silently.
|
|
Use when /ios-qa reports a bug and you want it fixed automatically, or
|
|
when asked to "fix this iOS bug", "patch the iPhone app", or "auto-fix
|
|
the iOS issue". (gstack)
|
|
voice-triggers:
|
|
- "fix the iOS bug"
|
|
- "patch the iPhone app"
|
|
- "auto-fix the iOS issue"
|
|
allowed-tools:
|
|
- Bash
|
|
- Read
|
|
- Write
|
|
- Edit
|
|
- Grep
|
|
- Glob
|
|
- AskUserQuestion
|
|
triggers:
|
|
- fix this ios bug
|
|
- patch the iphone app
|
|
- auto-fix the ios issue
|
|
---
|
|
|
|
{{PREAMBLE}}
|
|
|
|
# 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 test in `test/fixtures/ios-fix/<bug-slug>.test.ts` that:
|
|
|
|
1. Loads the pre-bug snapshot.
|
|
2. Restores it via `POST /state/restore`.
|
|
3. Asserts the post-fix behavior on a real device (gated
|
|
`GSTACK_HAS_IOS_DEVICE=1`, periodic tier).
|
|
|
|
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 | Re-codegen accessors (`swift run gen-accessors`), 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 |
|