agentleFS
beydemirfurkanbeydemirfurkan/appstore-release/skills/app-store-preflight/SKILL.md

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

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
  1. Very specific:

    No credentials, no network.

    line 37
  2. Very specific:

    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 …

    line 39

“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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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, signals

No 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:

PriorityWhatSeverity in the output
P0Certain rejection — fix before submittingblocker
P1Likely rejection — inferred from code or depswarning
P2Worth knowinginfo
P3Waived, with the reason on recordinfo, 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 idGuidelineFix
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-option4.8Add Sign in with Apple, or record the exemption that applies
app.account-deletion5.1.1(v)An in-app path that deletes the account, not only signs out
app.payments.external3.1.1Digital goods through In-App Purchase; physical goods and services may use other payment
app.subscription.restore3.1.2A Restore Purchases button
app.tracking.prompt5.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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.