app-store-preflight
Skill4 starsChanged 34 days agoMITView on GitHub
Check an iOS app for what App Review rejects before it is submitted — reads the project itself (Expo app.json, Info.plist, INFOPLIST_KEY_ build settings, PrivacyInfo.xcprivacy, source) offline and reports missing or generic permission texts, invalid required-reason codes, login without an equivalent private option, no in-app account deletion, external payments, no restore purchases, tracking without ATT, insecure HTTP, secrets in the bundle. Use when the user asks "will Apple reject my app", "check my app before I submit", "App Store review checklist", "preflight", "guideline 5.1.1 / 4.8 / 3.1.1 / 3.1.2", "privacy manifest", "ITMS-91053", "purpose string", or before a first submission.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- ilan-uzan/app-store-preflighttheir own version, first seen Nov 1, 2026
- quiet-build/skillstheir own version, first seen Sep 16, 2026
- moasq/ios-dev-agenttheir own version, first seen May 26, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- ilan-uzan/app-store-preflight★ 5same name
- moasq/ios-dev-agent★ 4same name
- quiet-build/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository9 other files it gives its agents.
- AGENTS.mdAGENTS.md
- app-store-age-ratingSkill
- app-store-customer-reviewsSkill
- app-store-rejectionSkill
- appstore-releaseSkill
- app-store-screenshot-uploadSkill
- app-store-subscriptionsSkill
- app-store-testflightSkill
- ios-code-signingSkill
The file
We split this skill into the rules it gives an agent
2 rules. 0 are common, 0 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 37
No credentials, no network.
- Very specific: line 39
Only use --expo-config when the project has a dynamic app.config.js/ts (preflight says so with app.expo-config.dynamic): it executes the …
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
App Store preflight
You say: "Will Apple reject my app?" · "Check my app before I submit."
It does: Reads the app's own project — config, Info.plist, privacy manifest, code — with no credentials, and lists what App Review is certain or likely to reject, each with the guideline, the file and line, and the fix. Then it lists what only a test on a device can prove.
App Store Connect only sees the listing. The most common rejections are in the app: a permission prompt with no reason, accounts that cannot be deleted, a paywall with no restore. This skill finds them before a review cycle is spent.
Running the CLI
node <skill-dir>/scripts/asc.mjs <command> [flags]<skill-dir> is the directory you loaded this SKILL.md from. Below, asc means that line. Run it from the app's directory, or point at it with --project-root.
1. Run it
asc preflight # the project next to the config, or the current directory
asc preflight --project-root ./app # somewhere else
asc preflight --expo-config # also evaluate app.config.js/ts (runs `npx expo config`)
asc preflight --json # one document: findings, notes, manualChecks, signalsNo credentials, no network. Exit 4 when something is certain to be rejected, 0 otherwise. The same findings appear first in asc check, under App.
Only use --expo-config when the project has a dynamic app.config.js/ts (preflight says so with app.expo-config.dynamic): it executes the project's config code.
2. Read it as a risk table
Present the result to the user in this order, one line each, with the evidence:
| Priority | What | Severity in the output |
| P0 | Certain rejection — fix before submitting | blocker |
| P1 | Likely rejection — inferred from code or deps | warning |
| P2 | Worth knowing | info |
| P3 | Waived, with the reason on record | info, Ignored: prefix |
Evidence is file:line or the Info.plist key and where it comes from. A warning is a text search or a dependency, not proof — say "found X, not found Y" rather than "your app has no account deletion". If you cannot point at evidence, label the item Unverified.
3. Fix, or waive with a reason
| Finding id | Guideline | Fix |
app.permission.missing.<Key> | 5.1.1(ii) | Add the key. Expo: the plugin option the finding names, in expo.plugins |
app.permission.default-text.<Key> | 5.1.1(ii) | Say what the app does with it and why it helps the user — not "Allow X to access your camera" |
app.privacy-manifest.invalid-reason.* | — | Use a valid reason code for the category; App Store Connect refuses the upload otherwise |
app.privacy-manifest.missing | — | Bare iOS: add PrivacyInfo.xcprivacy. Expo: only if your own code calls a required-reason API |
app.login.equivalent-option | 4.8 | Add Sign in with Apple, or record the exemption that applies |
app.account-deletion | 5.1.1(v) | An in-app path that deletes the account, not only signs out |
app.payments.external | 3.1.1 | Digital goods through In-App Purchase; physical goods and services may use other payment |
app.subscription.restore | 3.1.2 | A Restore Purchases button |
app.tracking.prompt | 5.1.2(i) | App Tracking Transparency before tracking, or configure the SDK not to track |
app.ats.insecure | — | https://, or an exception scoped to one domain |
app.secrets.* | — | Move the secret to a server and rotate it |
app.export-compliance | — | Expo: ios.config.usesNonExemptEncryption: false when the app only uses HTTPS and system crypto |
A finding that does not apply is waived in the config, with a reason — the reason is required and stays visible:
"preflight": {
"ignore": [{ "id": "app.account-deletion", "reason": "Accounts are created and deleted on our website; the app only signs in." }]
}An id waives itself and every id under it (app.permission.default-text covers every key). Ask the user before waiving anything; never waive a blocker to get past check.
Then run asc preflight again until nothing is P0.
4. Test what a static read cannot prove
The output ends with Test on a device: trigger every permission prompt and read it, create and delete an account, buy in the sandbox and restore, sign in with the demo account App Review will use. Give the user that list; a clean preflight does not mean these work.
5. Checklists by kind of app
Subscriptions, user-generated content, kids, health, AI features, sign-in: see references/checklists.md. Walk the one that matches the app with the user before the first submission.
Next
The listing side — metadata, screenshots, price, rating, submission — is the appstore-release skill. For the reviewer, asc review-info --draft-notes drafts the App Review notes from the config and what preflight read.
Checked against the App Store Review Guidelines of June 8, 2026.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

