App Ops Desk · Issue #4
Rollback discipline after a bad build
A bad TestFlight doesn’t have to become a lost week. Panic thrash does. Solo founders need a boring halt-and-return protocol.
One action this week: Write down your current last known good build:
marketing version, build number, git SHA, Xcode version, and why it was good.
Put it at the top of your release log before the next experiment.
Define “bad” quickly
- Launch crash / login broken / data loss risk
- Core action fails for more than a fluke device
- Paywall falsely charges or blocks access
- Privacy/permission prompt storm or obvious policy landmine
UI polish complaints are not automatic rollbacks. Broken trust paths are.
Halt rules
- Stop uploading. More builds won’t help until diagnosis exists.
- Mark the bad build in the release log with symptoms + devices.
- Point testers at last known good if one is still available in TF.
- Disable auto-submit fantasies. No “maybe the next archive fixes it” without a root cause note.
Diagnosis order (don’t skip)
- Is this reproducible on the archive build (not just debug)?
- Did toolchain/signing/version identity change? (Issue #0/#1)
- Did dependencies/privacy surface change? (Issue #2)
- What is the smallest git diff from last known good?
- Can you reproduce with a fresh install?
Return-to-good paths
Path A — revive last good for testers
- Keep last good available in TestFlight if possible
- Communicate build numbers explicitly (never “latest”)
Path B — rebuild last good SHA as a new build number
- Check out the known-good SHA
- Bump build number (never reuse)
- Archive on supported Xcode
- Smoke critical path before upload
Path C — forward fix only when root cause is known and smaller than a revert.
Communication template
Status: Build 221 paused Issue: [one sentence] Action for testers: use build 214 (1.5.0) until further notice Next update: [time window]
Copy/paste rollback checklist
- Last known good recorded before new work
- Bad build labeled with symptoms/devices
- Uploads halted
- Testers redirected with exact build numbers
- Root cause note written (even if “unknown — bisecting”)
- Next archive has new build number + smoke results
- Release log updated with outcome