Evidence-backed example
Below is the complete, unedited output of Verto's deterministic internal QA checker (scripts/internal-preflight.mjs) run against the fixture at fixtures/expo-preflight-sample. It regenerates on every build, so what you read here is always what the alpha currently produces.
The decision is never a customer-facing ship-or-not certainty. It is one of critical risks, unresolved checks, or no deterministic blockers, and every result is separated into what the tool verified automatically, what a developer confirmed, and what still needs confirmation. That separation is the point: it keeps a developer's word distinct from proof, and it refuses to guess about anything it cannot see — like the state of your App Store Connect account.
1 deterministic blocker must be resolved before submission.
Checks the tool proved from your project and build.
External steps you confirmed. Your word, kept separate from what the tool verified.
Nobody has confirmed these yet. The report will not guess.
iOS app identity
iOS permission explanations
Expo package compatibility
App Store listing metadata
Subscription submission wiring
iOS build artifact (final Info.plist)
Developer-confirmed submission checklist
- Blocker
NSContactsUsageDescription has no matching package or plugin
purpose-strings-01- Where
fixtures/expo-preflight-sample/app.jsonexpo.ios.infoPlist.NSContactsUsageDescription- Found
Trailmark uses your contacts so you can invite friends to a shared hike.- Fix
- Delete the key if unused, or confirm the project actually includes one of: expo-contacts.
App Store Review Guideline 2.3
- Needs confirmation
Purchase SDK found but App Store subscription attachment cannot be verified
subscription-wiring-02- Where
fixtures/expo-preflight-sample/package.jsondependencies- Found
react-native-purchases- Confirm
- A repository cannot prove App Store Connect attachment state. Verify the products on the submitted version, or pass the internal attachment manifest explicitly.
- Needs confirmation
iOS build artifact was not supplied
ios-artifact-03- Found
(absent)- Confirm
- Pass --ios-artifact <path> pointing at the built .app directory or .ipa so the final Info.plist can be verified. Repository config alone does not prove what shipped.
Internal dogfood build. Repository findings are real; checks requiring App Store Connect are explicitly marked needs-input when no export is supplied.
Download raw JSONProvenance
A sample report is only worth anything if you can check it. Everything the report reads is committed in this repository:
fixtures/expo-preflight-sample/README.md— names the fixture's origin and lists every intentional mutation in a table mapped to the check that catches it.fixtures/expo-preflight-sample/app.jsonfixtures/expo-preflight-sample/package.jsonfixtures/expo-preflight-sample/store.config.jsonfixtures/expo-preflight-sample/checklist.jsonscripts/internal-preflight.mjs— the checker itself, with the version-pairing table and Apple limits written as constants you can read.
What the fixture is
It is synthetic. "Trailmark" is a fictional hiking app. No file was taken from a real, client, or third-party app, and nothing proprietary is in it. The shape of the config follows the public Expo documentation defaults; the failure categories are drawn from publicly documented App Review causes. The fixture ships a store config and a filled-in submission checklist but no built .ipa, so the sample legitimately shows every verification class.
What these checks are not
They read your committed files and, when supplied, your final build's Info.plist. They do not talk to App Store Connect, use any network, or run on device. Where the answer is not deterministically inferable — a subscription's attachment state, a reviewer step, an Expo SDK outside the pinned pairing table — the report marks it needs confirmation instead of guessing. A preflight that cries wolf gets ignored, and an ignored check is worse than no check.
Determinism
The same fixture bytes produce the same findings in the same order on every run. The report embeds a sha256:f972d384ac20f30d hash of its inputs so a report can always be tied back to the exact files that produced it.