Repository navigation
Inbox mobile: TestFlight and App Review preparation (M8) - #1798
Merged
Merged
Conversation
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The story
The iPhone app gets what App Store Connect needs before the first upload: a privacy manifest truthful to the code, the notes App Review reads, and a release runbook the owner runs himself. Nothing in the app's behaviour changes: the manifest is a resource, and the only project change is XcodeGen adding it. The Workspaces build setting this step names already exists on M7's branch (
WORKSPACES_ORIGIN), so this PR references it and does not add a second one.What changed
apps/ios/Plannotator/PrivacyInfo.xcprivacy(new): no tracking, no tracking domains, no collected data types, one required-reason API:NSPrivacyAccessedAPICategoryUserDefaultswithCA92.1(app-only defaults: the paired sources, appearance, haptics, Send's idempotency keys).apps/ios/Plannotator.xcodeproj/project.pbxproj:xcodegen generateadds the manifest to the app's Resources (4 lines).apps/ios/APP-REVIEW.md(new): what the app is (local-only App Store build; Workspaces in TestFlight builds only); Guideline 2.5.2 (the bundled surface is the app's own code, agent HTML is sandboxed content with no network, by CSP and content rule list); the reviewer's path without a computer (what exists today: none in the app; what the owner provides: a device screen recording, optionally a demo Inbox shared over Tailscale) with the notes text to paste; account deletion (5.1.1(v)): none needed for the account-less App Store build,DELETE /v1/merequired before any Workspaces build leaves internal TestFlight, OWNER-ITEMS item 30; Sign in with Apple (4.8, item 31, TestFlight builds only); export compliance (CryptoKit only, Apple's "limited to that within the Apple operating system" row, his declaration); App Privacy answers for both builds.apps/ios/RELEASE.md(new): the owner's runbook: Team ID and Xcode account, the Team ID for the staging association file, two APNs keys into the relay's and Workspaces' secret stores, the App Store Connect record underai.plannotator.app, the internal TestFlight group, the TestFlight archive withWORKSPACES_ORIGINset and exportedtestFlightInternalTestingOnly, the App Store archive with it empty, the privacy report, export compliance, the listing and the submission. Each step one line with its exact command or screen.apps/ios/README.md: "What you need to run it" and "Release and App Review" pointing at the three documents.AGENTS.md: theapps/iosstructure line names the three documents.Record sections it makes real
PLAN.md step M8 (privacy manifest, review notes with bundled code and sandboxed agent HTML, account deletion, the release runbook; upload and submission are the owner's). OWNER-ITEMS 1, 3, 4, 7, 8, 9, 10, 30, 31 are each placed in the runbook or the notes as the owner's step. No screen of the iPhone record changes.
Proofs and the commands that run them
xcodebuild -project apps/ios/Plannotator.xcodeproj -scheme Plannotator -configuration Release -destination 'generic/platform=iOS Simulator' -derivedDataPath /tmp/mobile-m8/derived CODE_SIGNING_ALLOWED=NO build(BUILD SUCCEEDED;Plannotator.app/PrivacyInfo.xcprivacypresent and byte-identical to the source).plutil -lint apps/ios/Plannotator/PrivacyInfo.xcprivacy(OK), and a check of every key and reason code against the lists in Apple's current "Describing use of required reason API" andNSPrivacyAccessedAPITypedocumentation (read from developer.apple.com on 2026-10-08).mainand on every in-flight app branch (M2, M3, M4, M5, M7, P2): onlyUserDefaults; no file timestamp, boot time, disk space or active keyboard API.xcodebuild -list(schemePlannotator, configurations Debug and Release) andxcodebuild -showBuildSettings -scheme Plannotator -configuration Release -destination 'generic/platform=iOS' DEVELOPMENT_TEAM=...(bundle idai.plannotator.app, the team override taken); on M7's branch the same withWORKSPACES_ORIGIN=https://staging.workspaces.plannotator.aishows the origin, and without it Release leaves it empty. The export options keys (method app-store-connect,destination upload,signingStyle,testFlightInternalTestingOnly) checked againstxcodebuild -helpon Xcode 26.6.Gates
bun run typecheck(green),bun run check:release-version(green),gitleaks git . --log-opts="<merge-base>..HEAD"(no leaks). No TypeScript, server or UI file changes, so no bun or DOM suites.What it leaves out, and what M8's rebase must add
1C8F.1(App Group defaults,Notifications.swift), andPlannotatorNotifications/PrivacyInfo.xcprivacyis added with the same entry, because Apple wants a manifest in every bundle whose executable uses a required-reason API.applinks:andwebcredentials:for the staging origin) on M7's branch. A signed build'sASWebAuthenticationSessionhttps callback cannot return without it. RELEASE.md names it as a precondition; it belongs in M7 or a follow-up, beside M5's entitlements file.ITSAppUsesNonExemptEncryptionkey: the export answer is the owner's declaration. RELEASE.md 6.2 offers the one-line PR once he gives it.Deviations
APPLE_TEAM_IDinapps/rooms/wrangler.api.jsonc(valueTEAMIDTODO), since Apple publishes the Team ID in every association file. RELEASE.md 1.4 says so. The Team ID itself is never committed here (plannotator-ops: no account ids in the repo); the runbook uses<TEAM_ID>.Limits
None added.