← back to Ios Fleet Recording Qa
README.md
47 lines
# ios-fleet-recording-qa
Pre-submission QA gate for App Store **Guideline 2.1** device screen-recordings — the
`verify-recording` + `privacy-scan` + `readiness-probe` the TK-11155 approved memos assumed
existed (they didn't). Works for all 5 rejected apps: GovArbitrage, Homes on Spec,
Beverly Hills Videos, Celebrity Signatures, Unofficial 90210.
## Why
An Apple 2.1 reply must attach a **physical-device** recording of the app's core flow. Two ways
to get re-rejected: (a) a bad clip (too short / black / simulator), or (b) a clip with **PII on
screen** (a notification banner, a customer's name/address/email/phone in a demo). This gate
catches both before the clip ever reaches Apple.
## Use
```sh
./recording-qa.sh <clip.mov> [app-name] # run the gate, print verdict
./recording-qa.sh --json <clip.mov> # machine-readable verdict line
./recording-qa.sh --approve <clip.mov> # AFTER a human eyeball, bind the review to the exact bytes
```
## Verdicts
| code | meaning |
|---|---|
| `TECH_FAIL` | too short (<20s) / mostly black / unreadable |
| `REJECTED_NOT_DEVICE` | filename shows a simulator clip (Apple rejects those for 2.1) |
| `PRIVACY_FLAGGED` | OCR found an email / phone / street-address in a frame — **do not upload** |
| `TECH_PASS_PRIVACY_PENDING` | tech ok, OCR clean, but no human sign-off yet |
| `READY_TO_SEND` | tech ok + OCR clean + human sidecar present & matches current bytes |
## How it checks
- **Tech** (ffprobe/ffmpeg): duration ≥20s, portrait, non-black (`blackdetect`), playable.
- **Device**: reads `com.apple.quicktime.model` (real iOS captures carry it). ABSENCE is a
*warning only* — the tag is legitimately stripped by AirDrop / any re-encode — so a good clip
isn't falsely rejected. Only a positive simulator filename tell hard-rejects.
- **Privacy**: samples a frame every 2s, OCRs each (tesseract), flags email / phone / street-address
text. A human still eyeballs and runs `--approve`, which writes a `.privacy-reviewed.sha256`
sidecar binding the review to the exact bytes. A matching sidecar **cannot** rescue a
tech-fail or a PII-flagged clip (the gate re-checks every run; `--approve` refuses a failing clip).
## Requirements
`ffmpeg` / `ffprobe`, `tesseract`, `shasum` (all via Homebrew). No network, $0.
## Self-test
`./selftest.sh` builds synthetic fixtures and asserts the full verdict matrix.
Proven 2026-09-03: A→TECH_FAIL, B(email)→PRIVACY_FLAGGED, C→PENDING→(approve)→READY_TO_SEND,
E(sim name)→REJECTED_NOT_DEVICE, and `--approve` refuses a PII clip.