tl;dr — Apple's rejection emails are written for humans, not for automation. After 14 distinct rejection causes across four apps in five months I built asc_diag.py , an open-source tool that maps every cause to one of 12 stable issue codes and emits a fix hint. This post explains the evolution from 8 to 12 classes, the auto-fix surface area, and a runnable end-to-end example. What "12 classes" actually means Apple's App Store Connect rejection emails read like: Guideline 2.1 - Information Needed (App Completeness) We were unable to review your app because <freeform reason>. Enter fullscreen mode Exit fullscreen mode The freeform reason is almost structured but not quite. Across four apps in five months I logged 14 distinct rejections and clustered them into 12 stable issue codes. Each code is one diagnostic check + one fix hint. The codes don't change between releases — adding new classes is additive only. # 12 stable issue codes — the diagnostic ranks every finding into exactly one.…