ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-09-08Intermediate

Answering the age-rating questionnaire from a file in the repo, not from memory

The App Store age-rating questionnaire became mandatory in September 2026. Here is how I moved the answers into a declaration file in the repo and had a stdlib-only script argue back, with the real output.

app-store6ios38app-dev54ci5

Premium Article

In early September I was submitting a wallpaper app update and stopped partway through App Store Connect. There was a questionnaire I had never seen. Since September 2026, answering it is required when you submit a new app or an update, and when you file for notarization for alternative distribution. It drives the age rating and the Time Allowances behaviour on iOS 27, iPadOS 27 and macOS 27.

I tried to answer from memory. I stopped on the second question. Asked whether the app opens web content inside itself, I could not honestly say yes or no. Somewhere in the settings screen there was a link that opened a help page. I had put it there three years ago, and I no longer notice it when I look at the screen.

What I decided in that moment became the rule.

If a question makes you dig through your memory at submission time, the answer belongs in the repository.

As an indie developer shipping several apps, I fill in the same questionnaire many times a year, once per app. Reconstructing the answers each time guarantees they will eventually drift, and when they do, I will not know whether the declaration or the implementation is the one that moved. What follows is how I put the answers into a single declared file and made a check fail when the code disagrees.

The questionnaire asks what you are capable of, not what you usually do

This is where I was stuck. Questions of this kind are not asking what the app does day to day. They ask whether a user can reach a capability.

Advertising is the clearest example. Ads are a rating question in their own right, but separately, ad landing pages open in an in-app browser. Ship an ad SDK and your users can reach an arbitrary web page from inside the app, even if the string WKWebView never appears in your source.

The other case is leftovers. You can stop asking for tracking consent and delete the ATTrackingManager call, and still leave NSUserTrackingUsageDescription sitting in Info.plist. From the outside, an app that ships that key is an app that may ask.

Kind of entry pointWhere the evidence livesFindable by reading your own source?
A feature you wroteSwift / Kotlin sourceYes
A declaration you forgot to removeInfo.plistRarely
A path a dependency brings with itPodfile.lock / Package.resolvedNo

The answers worth protecting are the ones where you said "none." Nobody notices when those quietly stop being true.

Put the answers in one declared file

Start by writing the answers out per app. I use JSON so that the checker needs nothing but the standard library.

{
  "app": "WallpaperApp",
  "questionnaire_version": "2026-09",
  "answers": {
    "in_app_browser": "none",
    "advertising": "contextual",
    "user_generated_content": "none",
    "in_app_purchase": true,
    "location_sharing": false,
    "tracking": false
  }
}

questionnaire_version earns its place because the questionnaire itself gets revised. Without it, the next revision leaves you unable to say which set of questions these answers were given to, and you are back to digging through memory a year later.

The answers above do not have to be correct yet. They are exactly what I typed from memory. The machine is about to argue with them.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You can stop reconstructing questionnaire answers from memory and pull the same answer out of one declared file in the repo
You can find the questions where your declaration disagrees with your implementation on your own machine, before a reviewer finds them for you
You can account for the entry points that never appear anywhere in your own source, and explain what your app is capable of rather than what it usually does
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

App Dev2026-07-03
Catching Download Size Regressions Before Submission Day — A Weekly Agent Gate for AAB/IPA Size Budgets
Mediation SDKs and bundled assets quietly inflate download size. A design for size ledgers, budget gates, and agent-driven delta attribution using bundletool and App Thinning reports.
App Dev2026-06-28
Adding Mediation Partners Quietly Starved My iOS Attribution — Reconciling SKAdNetwork IDs Across Four Apps
I added mediation partners but iOS revenue barely moved — the cause was missing SKAdNetwork IDs in Info.plist. Here is how I reconciled SKAdNetworkItems across four apps, using an Antigravity agent as the matcher while keeping the revenue decisions by hand.
App Dev2026-06-25
When Xcode Cloud's Free 25 Hours Quietly Run Out at Month's End — Field Notes on Measuring and Defending Compute Time
Before Xcode Cloud's free compute allowance drains at month's end and your builds sit queued, measure where it goes. Practical field notes on pulling usage from the App Store Connect API, stopping wasteful builds early, and trimming test runs to keep CI inside budget.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links