@mmerterden/multi-agent-pipeline 20.36.0 → 20.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/docs/facts.json +2 -2
  3. package/docs/features.md +1 -1
  4. package/docs/recovery-guide.md +1 -1
  5. package/install/catalog-history.json +1 -1
  6. package/manifest.json +225 -148
  7. package/package.json +1 -1
  8. package/pipeline/commands/multi-agent/SKILL.md +33 -154
  9. package/pipeline/commands/multi-agent/analysis/SKILL.md +14 -68
  10. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +5 -8
  11. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +38 -109
  12. package/pipeline/commands/multi-agent/channels/SKILL.md +38 -167
  13. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +37 -144
  14. package/pipeline/commands/multi-agent/design-check/SKILL.md +27 -131
  15. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +22 -48
  16. package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +37 -180
  17. package/pipeline/commands/multi-agent/jira/SKILL.md +16 -46
  18. package/pipeline/commands/multi-agent/manual-test/SKILL.md +12 -7
  19. package/pipeline/commands/multi-agent/refactor/SKILL.md +23 -184
  20. package/pipeline/commands/multi-agent/resume/SKILL.md +30 -136
  21. package/pipeline/commands/multi-agent/review/SKILL.md +24 -199
  22. package/pipeline/commands/multi-agent/setup/SKILL.md +25 -181
  23. package/pipeline/commands/multi-agent/stack/SKILL.md +9 -53
  24. package/pipeline/commands/multi-agent/status/SKILL.md +13 -2
  25. package/pipeline/commands/multi-agent/store-ready/SKILL.md +27 -226
  26. package/pipeline/commands/multi-agent/sync/SKILL.md +35 -164
  27. package/pipeline/commands/multi-agent/test-gen/SKILL.md +2 -4
  28. package/pipeline/commands/multi-agent/update/SKILL.md +18 -60
  29. package/pipeline/contract/CHANGELOG.md +9 -0
  30. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  31. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  32. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  33. package/pipeline/contract/fixtures/runs-awaiting-question.json +1 -1
  34. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  35. package/pipeline/contract/fixtures/runs-failed.json +1 -1
  36. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
  37. package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
  38. package/pipeline/contract/fixtures/runs-running.json +1 -1
  39. package/pipeline/contract/manifest.json +5 -5
  40. package/pipeline/contract/types/index.d.ts +3 -2
  41. package/pipeline/multi-agent-refs/audit-guide.md +20 -0
  42. package/pipeline/multi-agent-refs/autopilot-on/details.md +148 -0
  43. package/pipeline/multi-agent-refs/channels/generator.md +14 -0
  44. package/pipeline/multi-agent-refs/channels/preview.md +13 -0
  45. package/pipeline/multi-agent-refs/channels/reference.md +46 -0
  46. package/pipeline/multi-agent-refs/complaint-analysis/phases.md +159 -0
  47. package/pipeline/multi-agent-refs/design-check/export.md +1 -0
  48. package/pipeline/multi-agent-refs/design-check/init-inventory.md +1 -1
  49. package/pipeline/multi-agent-refs/design-check/scope-and-ledger.md +64 -0
  50. package/pipeline/multi-agent-refs/features/analysis-command-notes.md +53 -0
  51. package/pipeline/multi-agent-refs/features/commit-multi-repo.md +63 -0
  52. package/pipeline/multi-agent-refs/features/dev-multi-repo.md +51 -0
  53. package/pipeline/multi-agent-refs/features/test-gap.md +40 -0
  54. package/pipeline/multi-agent-refs/features/worktree-finalize.md +1 -1
  55. package/pipeline/multi-agent-refs/garbage-collect/phases.md +60 -0
  56. package/pipeline/multi-agent-refs/ios-coding-standard/plan.md +71 -0
  57. package/pipeline/multi-agent-refs/ios-coding-standard/resolve-and-scan.md +135 -0
  58. package/pipeline/multi-agent-refs/jira/picker-detail.md +71 -0
  59. package/pipeline/multi-agent-refs/orchestrator/copilot-pipeline.md +88 -0
  60. package/pipeline/multi-agent-refs/orchestrator/dispatcher.md +96 -1
  61. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +12 -9
  62. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +4 -4
  63. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +8 -47
  64. package/pipeline/multi-agent-refs/phases/phase-3-review.md +21 -65
  65. package/pipeline/multi-agent-refs/phases/phase-4-commit.md +9 -59
  66. package/pipeline/multi-agent-refs/phases/phase-5-report.md +0 -31
  67. package/pipeline/multi-agent-refs/refactor/sweep.md +190 -0
  68. package/pipeline/multi-agent-refs/resume/details.md +115 -2
  69. package/pipeline/multi-agent-refs/review/inputs.md +33 -1
  70. package/pipeline/multi-agent-refs/review/module-guides.md +9 -1
  71. package/pipeline/multi-agent-refs/review/panel.md +75 -0
  72. package/pipeline/multi-agent-refs/review/valven.md +5 -1
  73. package/pipeline/multi-agent-refs/rules.md +1 -1
  74. package/pipeline/multi-agent-refs/setup/hooks-and-plugins.md +4 -0
  75. package/pipeline/multi-agent-refs/setup/token-save-flow.md +13 -0
  76. package/pipeline/multi-agent-refs/stack/background.md +72 -0
  77. package/pipeline/multi-agent-refs/store-ready/gates.md +139 -0
  78. package/pipeline/multi-agent-refs/store-ready/report.md +40 -2
  79. package/pipeline/multi-agent-refs/sync/office.md +10 -0
  80. package/pipeline/multi-agent-refs/sync/overview.md +61 -0
  81. package/pipeline/multi-agent-refs/sync/repo.md +91 -0
  82. package/pipeline/multi-agent-refs/update/details.md +83 -0
  83. package/pipeline/office/index.html +6 -3
  84. package/pipeline/office/toolkit.json +1 -1
  85. package/pipeline/rules/figma-pipeline.md +6 -3
  86. package/pipeline/schemas/prefs.schema.json +1 -1
  87. package/pipeline/schemas/runs-index.schema.json +2 -1
  88. package/pipeline/scripts/_memory-policy.mjs +27 -5
  89. package/pipeline/scripts/checkpoint-fold.sh +59 -0
  90. package/pipeline/scripts/contract-server.mjs +1 -1
  91. package/pipeline/scripts/gate-ledger.mjs +1 -1
  92. package/pipeline/scripts/office-control.mjs +41 -15
  93. package/pipeline/scripts/offload-ref.sh +1 -1
  94. package/pipeline/scripts/rework-rulings.mjs +5 -3
  95. package/pipeline/scripts/runs-index.mjs +34 -7
  96. package/pipeline/scripts/scope-check-gate.mjs +15 -2
  97. package/pipeline/scripts/status-overview.mjs +401 -0
  98. package/pipeline/scripts/user-test-handoff.sh +203 -0
  99. package/pipeline/scripts/validate-planning.mjs +5 -3
  100. package/pipeline/scripts/validate-triage.mjs +2 -1
  101. package/pipeline/scripts/write-state.mjs +13 -4
  102. package/pipeline/skills/.skill-manifest.json +64 -64
  103. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +7 -70
  104. package/pipeline/skills/shared/core/apple-archive-compliance/references/examples.md +67 -0
  105. package/pipeline/skills/shared/core/apple-archive-compliance/references/version-history.md +8 -0
  106. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +10 -72
  107. package/pipeline/skills/shared/core/google-play-compliance/references/examples.md +69 -0
  108. package/pipeline/skills/shared/core/google-play-compliance/references/notes.md +7 -0
  109. package/pipeline/skills/shared/core/google-play-compliance/references/version-history.md +5 -0
  110. package/pipeline/skills/shared/core/multi-agent/SKILL.md +39 -262
  111. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +35 -73
  112. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +37 -337
  113. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +27 -122
  114. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +8 -340
  115. package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +37 -180
  116. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +12 -7
  117. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +23 -184
  118. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +14 -82
  119. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +25 -277
  120. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +13 -2
  121. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +73 -217
  122. package/pipeline/skills/shared/external/alarmkit/SKILL.md +11 -162
  123. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-code.md +257 -0
  124. package/pipeline/skills/shared/external/android-architecture/SKILL.md +7 -58
  125. package/pipeline/skills/shared/external/android-architecture/references/code-examples.md +68 -0
  126. package/pipeline/skills/shared/external/app-intents/SKILL.md +3 -45
  127. package/pipeline/skills/shared/external/app-intents/references/code-examples.md +54 -0
  128. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +5 -81
  129. package/pipeline/skills/shared/external/app-store-optimization/references/engagement-and-localization.md +96 -0
  130. package/pipeline/skills/shared/external/app-store-review/SKILL.md +6 -112
  131. package/pipeline/skills/shared/external/app-store-review/references/monetization-and-submission.md +138 -0
  132. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +10 -117
  133. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models-code.md +186 -0
  134. package/pipeline/skills/shared/external/authentication/SKILL.md +3 -50
  135. package/pipeline/skills/shared/external/authentication/references/code-examples.md +59 -0
  136. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +3 -84
  137. package/pipeline/skills/shared/external/callkit-voip/references/code-examples.md +93 -0
  138. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +7 -263
  139. package/pipeline/skills/shared/external/ci-cd-pipelines/references/pipeline-examples.md +281 -0
  140. package/pipeline/skills/shared/external/clean-code/SKILL.md +8 -41
  141. package/pipeline/skills/shared/external/clean-code/references/code-examples.md +56 -0
  142. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +8 -146
  143. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-code.md +214 -0
  144. package/pipeline/skills/shared/external/compose-components/SKILL.md +6 -80
  145. package/pipeline/skills/shared/external/compose-components/references/code-examples.md +89 -0
  146. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +5 -64
  147. package/pipeline/skills/shared/external/compose-navigation/references/code-examples.md +70 -0
  148. package/pipeline/skills/shared/external/core-data/SKILL.md +9 -157
  149. package/pipeline/skills/shared/external/core-data/references/core-data-code.md +221 -0
  150. package/pipeline/skills/shared/external/core-nfc/SKILL.md +3 -89
  151. package/pipeline/skills/shared/external/core-nfc/references/code-examples.md +98 -0
  152. package/pipeline/skills/shared/external/coreml/SKILL.md +17 -133
  153. package/pipeline/skills/shared/external/coreml/references/coreml-code.md +208 -0
  154. package/pipeline/skills/shared/external/css-modern/SKILL.md +8 -131
  155. package/pipeline/skills/shared/external/css-modern/references/code-examples.md +142 -0
  156. package/pipeline/skills/shared/external/database-patterns/SKILL.md +6 -103
  157. package/pipeline/skills/shared/external/database-patterns/references/orm-examples.md +112 -0
  158. package/pipeline/skills/shared/external/html-semantic/SKILL.md +7 -48
  159. package/pipeline/skills/shared/external/html-semantic/references/code-examples.md +54 -0
  160. package/pipeline/skills/shared/external/humanizer/SKILL.md +6 -19
  161. package/pipeline/skills/shared/external/humanizer/references/voice.md +24 -0
  162. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +13 -170
  163. package/pipeline/skills/shared/external/ios-accessibility/references/assistive-tech-review.md +224 -0
  164. package/pipeline/skills/shared/external/ios-localization/SKILL.md +2 -24
  165. package/pipeline/skills/shared/external/ios-localization/references/code-examples.md +30 -0
  166. package/pipeline/skills/shared/external/ios-networking/SKILL.md +3 -58
  167. package/pipeline/skills/shared/external/ios-networking/references/code-examples.md +67 -0
  168. package/pipeline/skills/shared/external/ios-security/SKILL.md +4 -64
  169. package/pipeline/skills/shared/external/ios-security/references/code-examples.md +74 -0
  170. package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -90
  171. package/pipeline/skills/shared/external/live-activities/references/code-examples.md +108 -0
  172. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +9 -23
  173. package/pipeline/skills/shared/external/localization-reuse-map/references/project-settings.md +22 -0
  174. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +5 -95
  175. package/pipeline/skills/shared/external/mapkit-location/references/code-examples.md +117 -0
  176. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +7 -106
  177. package/pipeline/skills/shared/external/nextjs-app-router/references/app-router-examples.md +124 -0
  178. package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -31
  179. package/pipeline/skills/shared/external/permissionkit/references/code-examples.md +37 -0
  180. package/pipeline/skills/shared/external/play-store-review/SKILL.md +6 -74
  181. package/pipeline/skills/shared/external/play-store-review/references/signing-and-policies.md +83 -0
  182. package/pipeline/skills/shared/external/push-notifications/SKILL.md +8 -125
  183. package/pipeline/skills/shared/external/push-notifications/references/notification-code.md +176 -0
  184. package/pipeline/skills/shared/external/python-patterns/SKILL.md +7 -158
  185. package/pipeline/skills/shared/external/python-patterns/references/python-examples.md +176 -0
  186. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +7 -157
  187. package/pipeline/skills/shared/external/rest-api-design/references/api-examples.md +175 -0
  188. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +11 -230
  189. package/pipeline/skills/shared/external/swift-architecture/references/pattern-examples.md +295 -0
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +17 -149
  191. package/pipeline/skills/shared/external/swift-codable/references/codable-recipes.md +207 -0
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +12 -99
  193. package/pipeline/skills/shared/external/swift-concurrency/references/code-examples.md +100 -0
  194. package/pipeline/skills/shared/external/swift-concurrency/references/swift-6-2-additions.md +18 -0
  195. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +9 -78
  196. package/pipeline/skills/shared/external/swift-formatstyle/references/formatstyle-examples.md +113 -0
  197. package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -56
  198. package/pipeline/skills/shared/external/swift-language/references/code-examples.md +65 -0
  199. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +1 -0
  200. package/pipeline/skills/shared/external/swiftdata/SKILL.md +6 -122
  201. package/pipeline/skills/shared/external/swiftdata/references/code-examples.md +140 -0
  202. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +12 -139
  203. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/interop-code.md +198 -0
  204. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +9 -81
  205. package/pipeline/skills/shared/external/tailwind-css/references/code-examples.md +91 -0
  206. package/pipeline/skills/shared/external/testing-backend/SKILL.md +7 -207
  207. package/pipeline/skills/shared/external/testing-backend/references/testing-examples.md +225 -0
  208. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +8 -89
  209. package/pipeline/skills/shared/external/typescript-patterns/references/code-examples.md +100 -0
  210. package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -20
  211. package/pipeline/skills/shared/external/vision-framework/references/code-examples.md +26 -0
  212. package/pipeline/skills/shared/external/vue-composition/SKILL.md +7 -169
  213. package/pipeline/skills/shared/external/vue-composition/references/vue-examples.md +187 -0
  214. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +7 -174
  215. package/pipeline/skills/shared/external/web-accessibility/references/a11y-examples.md +192 -0
  216. package/pipeline/skills/shared/external/web-performance/SKILL.md +8 -66
  217. package/pipeline/skills/shared/external/web-performance/references/code-examples.md +77 -0
  218. package/pipeline/skills/shared/external/web-testing/SKILL.md +11 -186
  219. package/pipeline/skills/shared/external/web-testing/references/testing-examples.md +213 -0
  220. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/format-and-output.md +0 -0
  221. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/publish-and-snapshot.md +0 -0
  222. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/sources-and-recipes.md +0 -0
@@ -0,0 +1,96 @@
1
+ # Reviews, events and localized metadata
2
+
3
+ In-app review prompts, In-App Events, ratings and review management, and localized metadata. SKILL.md keeps metadata fields, screenshots, custom pages, product page tests and the review checklist.
4
+
5
+ ## Asking for reviews in the app
6
+
7
+ Use the SwiftUI environment value `RequestReviewAction` or, from UIKit,
8
+ `AppStore.requestReview(in:)`. The full StoreKit surface is covered in
9
+ `storekit`.
10
+
11
+ ```swift
12
+ import StoreKit
13
+ import SwiftUI
14
+
15
+ struct TripSummaryView: View {
16
+ @Environment(\.requestReview) private var requestReview
17
+ let completedTrips: Int
18
+
19
+ var body: some View {
20
+ TripSummaryContent()
21
+ .onAppear {
22
+ if completedTrips == 5 { requestReview() }
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ - The system shows the prompt at most three times in 365 days per device for
29
+ someone who has not rated the app.
30
+ - Calling the API is a request; StoreKit decides whether anything appears.
31
+ - Development builds always show it; TestFlight builds never do.
32
+ - Good moments: a meaningful task just finished, a milestone or streak, a
33
+ visible success, several active sessions.
34
+ - Bad moments: the very first launch, the onboarding flow, any error or crash,
35
+ a purchase that failed, or directly after a button tap.
36
+ - Do not put a "Do you like this app?" dialog in front of the system prompt.
37
+ Apple discourages intercepting it and may reject apps that do.
38
+
39
+ For a permanent "Write a review" row in settings, open
40
+ `https://apps.apple.com/app/id{APP_ID}?action=write-review`. It goes straight
41
+ to the review sheet and does not count against the three-per-year limit.
42
+
43
+ ## In-App Events
44
+
45
+ Events are shown in search, on Today and in recommendations tailored to
46
+ each user. They raise visibility while they run and can bring lapsed
47
+ users back.
48
+
49
+ - Badges (seven): Challenge, Competition, Live Event, Major Update, New
50
+ Season, Premiere, Special Event. Pick the one that matches what actually happens in
51
+ the app, and never create an event without real time-bound content.
52
+ - Text limits in characters: 30 for the name, 50 for the short description,
53
+ 120 for the long one.
54
+ - Media: an event card image or video at 16:9 (1920 x 1080) and an event
55
+ details page image or video at 9:16 (1080 x 1920).
56
+ - Time them with feature releases, seasonal moments and content drops.
57
+ - Write the name and short description for someone scanning search results;
58
+ they appear on the event cards in Search and Today.
59
+ - The card is shown on the product page as well, and a well-timed card lifts
60
+ tap-through.
61
+ - Line events up so a new one starts as the previous one ends, keeping a card
62
+ in search at all times.
63
+
64
+ ## Ratings and reviews
65
+
66
+ Star ratings and written reviews are visible on the product page and in
67
+ search, and they move both ranking and conversion.
68
+
69
+ - Earn more recent positive reviews: prompt after successes and answer
70
+ complaints constructively.
71
+ - Answer critical reviews from App Store Connect. A calm, specific reply
72
+ improves how the app looks even when the rating does not change: acknowledge
73
+ the problem, say what is fixed or in progress, keep the tone neutral.
74
+ - Read reviews as research into what users want, what frustrates them and the
75
+ words they use, then feed that into metadata and captions.
76
+ - Submitting a new version offers the option of resetting the summary rating. Do it only
77
+ when the shown rating is far below current quality after major fixes. Keep a
78
+ good rating that reflects the app fairly, skip the reset for routine fixes, and after
79
+ a risky redesign wait until it has settled.
80
+
81
+ ## Localized Metadata Optimization
82
+
83
+ A localized listing is a separate job from translating the app's screens.
84
+ Keywords, descriptions and captions are researched and written per market.
85
+
86
+ - Research keywords in each market. The term people use to find a photo editor
87
+ in Japanese is not a word-for-word translation of the English one.
88
+ - Rewrite the description per locale, adapting opening lines, features, proof
89
+ and close to local expectations.
90
+ - Localize every surface (description, keywords, previews, screenshots), and do
91
+ not count on literal translations or on one locale's keywords being indexed
92
+ elsewhere.
93
+ - Caption screenshots in the market's language; native captions convert better
94
+ than English ones.
95
+ - Localizing strings inside the app (String Catalogs, `FormatStyle`,
96
+ right-to-left layout) is covered by `ios-localization`.
@@ -177,42 +177,7 @@ Codes, plist layout and SDK rules: [privacy manifest reference](references/priva
177
177
 
178
178
  ## 3.1.1 Paying for digital things
179
179
 
180
- When the app unlocks digital content, a feature, a subscription or a digital
181
- service, the sale normally runs through Apple IAP, unless a guideline exception, a regional rule or
182
- an approved entitlement says otherwise.
183
-
184
- | Needs IAP | Does not need IAP |
185
- |---|---|
186
- | Unlocking premium features | Physical goods |
187
- | Subscriptions to app functionality | Real-world services such as rides or food delivery |
188
- | Virtual currency | Person-to-person services, for example a live tutor or consultant |
189
- | Removing ads | Business apps for organizations, distributed as custom apps via Apple Business Manager |
190
- | Digital tips to creators | Donations to approved nonprofits (see 3.2.1 and 3.2.2) |
191
-
192
- Rules around the purchase:
193
-
194
- - Before a subscription is bought, the paywall states what it costs, how long a
195
- period lasts and that it renews on its own.
196
- - For a free trial, show the trial length, the price after it, how often billing
197
- happens, that it renews automatically, and how to cancel, all before purchase.
198
- - Strip any route to an outside checkout for digital goods, whether a link, a
199
- button or a nudge in copy, unless the storefront's current rule or a granted
200
- entitlement permits it. A StoreKit External Purchase Link entitlement or,
201
- where permitted, a Music Streaming Services entitlement allows a link to a
202
- permitted destination; the US storefront needs no entitlement. These rules differ by region and have changed recently; read the
203
- current 3.1.1(a) and 3.1.3 text for the target storefront.
204
- - Reader apps may link out to account sign-up with the matching entitlement, but
205
- may not offer a way around IAP for in-app purchases.
206
-
207
- StoreKit checks:
208
-
209
- - Products are typed correctly in App Store Connect (consumable, non-consumable,
210
- subscription).
211
- - A Restore Purchases control exists and works.
212
- - Entitlements are verified with StoreKit 2 `Transaction.currentEntitlements` or
213
- on the server.
214
- - A purchase that is interrupted, or deferred while a parent approves it through
215
- Ask to Buy, leaves the UI in a sane state.
180
+ Unlocking digital content, features, subscriptions, virtual currency or ad removal goes through IAP unless a guideline exception, regional rule or entitlement says otherwise; physical goods and real-world services do not. The paywall must disclose price, period, renewal and trial terms before purchase, and outside checkout links need a storefront rule or entitlement. Tables, StoreKit checks and regional notes: [Monetization, submission, metadata and appeals](references/monetization-and-submission.md).
216
181
 
217
182
  ## HIG items App Review looks at
218
183
 
@@ -272,91 +237,19 @@ behind another system permission alert.
272
237
 
273
238
  ## Entitlements and usage strings
274
239
 
275
- Every entitlement needs a reason App Review can see in the product.
276
-
277
- | Capability | What review expects |
278
- |---|---|
279
- | Camera | a clear `NSCameraUsageDescription` |
280
- | Location (Always) | a visible reason the user benefits from background location |
281
- | Push notifications | no marketing pushes without the user's opt-in |
282
- | HealthKit | health data used in a meaningful feature |
283
- | Background Modes | every declared mode (audio, location, VoIP, fetch) has a feature that uses it |
284
- | App Groups | the shared data is explained |
285
- | Associated Domains | universal links resolve and open the app |
286
-
287
- A usage string names the data and the user-facing reason:
288
-
289
- | Verdict | String |
290
- |---|---|
291
- | Approved | "We use where you are to place the closest charging stations on the map." |
292
- | Approved | "The camera scans a book's barcode so you can add it to your shelf." |
293
- | Rejected | "This app requires camera access." |
294
- | Rejected | "We use your photo library to improve your experience." |
295
- | Fixed | "Pick a photo from your library to use as your profile picture. Only the photo you choose is uploaded." |
296
-
297
- The second rejected string names a data type but gives no concrete purpose;
298
- "improve your experience" is the phrase review flags. The fixed version says
299
- which feature uses the data and what leaves the device.
240
+ Every entitlement needs a reason review can see in the product, and every usage string names the data and the user-facing reason ("improve your experience" is rejected). Capability table and approved versus rejected strings: [Monetization, submission, metadata and appeals](references/monetization-and-submission.md).
300
241
 
301
242
  ## Submission workflow
302
243
 
303
- 1. Archive: Product > Archive with a Distribution signing identity, from a clean
304
- Release build. Aim for zero warnings; it is good hygiene, not a review rule.
305
- 2. Upload: in Organizer choose Distribute App, then App Store Connect; or run
306
- `xcodebuild -exportArchive`. `altool` and Transporter also work.
307
- 3. Internal TestFlight: internal testers see the build minutes after processing.
308
- Try every flow on two or more screen sizes.
309
- 4. External TestFlight: the first build sent to an external group goes through
310
- Beta App Review.
311
- 5. Submit: pick the build, complete metadata, attach screenshots, press Submit
312
- for Review. Review time varies, so keep slack before a deadline.
313
-
314
- Expedited review is for a critical fix for existing users, a date-bound event
315
- (a holiday launch, a legal deadline) or a security patch. Ask through Contact
316
- Us > App Review > Expedite Request with a specific, factual reason. It is not for
317
- first launches or new features.
318
-
319
- Phased release for automatic updates: day 1 1%, day 2 2%, day 3 5%, day 4 10%,
320
- day 5 20%, day 6 50%, day 7 100%. Users who check for updates by hand get the
321
- build immediately. The rollout can be paused, resumed or finished early at any
322
- time.
244
+ Archive a clean Release build, upload, test on internal then external TestFlight, then submit. Expedited review is only for critical fixes, date-bound events or security patches. Steps and the phased-release schedule: [Monetization, submission, metadata and appeals](references/monetization-and-submission.md).
323
245
 
324
246
  ## Metadata rules
325
247
 
326
- - Name and subtitle: 30 characters each. The subtitle is a short value statement.
327
- A bare category word such as "Photo Editor" is likely rejected; so are
328
- competitor or trademarked terms and prices. The name must be unique.
329
- - Screenshots: 1 to 10 per required platform and localization. The
330
- 6.9-inch iPhone set is the primary one; the 6.5-inch set is required only
331
- when there is no 6.9-inch set, and smaller iPhones get scaled images. Apps that
332
- run on iPad need 13-inch iPad screenshots; smaller iPads are scaled.
333
- - Screenshot content: the real UI; never show a feature the build lacks. Captions and
334
- frames are fine if they neither hide nor misstate the UI. Localized sets show
335
- the localized UI.
336
- - Keywords: 100 characters, comma-separated with no spaces. Words already in the
337
- name or subtitle are indexed, so do not repeat them. Use singular or plural,
338
- not both. No competitor, trademark or unrelated terms.
339
- - App previews: up to 30 seconds, up to 3 per localization, captured from the app
340
- on a device with the app's own audio (narration or music optional). No
341
- misleading framing and no footage of hands holding a device. The first frame
342
- is the poster frame.
248
+ Name and subtitle 30 characters each, keywords 100 characters, screenshots and previews show the real UI. Screenshot sets, keyword and preview limits: [Monetization, submission, metadata and appeals](references/monetization-and-submission.md).
343
249
 
344
250
  ## Rejections and appeals
345
251
 
346
- - A rejection arrives in the Resolution Center with the guideline number.
347
- - Reply in that thread with facts. If you fixed the issue, say what changed and
348
- upload a new binary. If you disagree, show how the app complies, quoting the
349
- guideline.
350
- - Keep it professional, specific and short. Attach demo credentials, screenshots
351
- or a screen recording. No emotional language, no threats.
352
- - For a formal appeal, go to the App Review Board through the Resolution Center or
353
- Contact Us > App Review > Appeal. A separate team reads the whole history. The
354
- ruling is final for that build; a changed build can still be submitted.
355
-
356
- What tends to work: a video walkthrough of the flagged feature, a point-by-point
357
- answer against the guideline text, fresh demo credentials (the usual 2.1 cause),
358
- a polite reference to comparable approved behaviour, and offering an alternative
359
- implementation.
252
+ Reply in the Resolution Center thread with facts: what changed, or how the app complies with the quoted guideline, plus demo credentials or a recording. Formal appeals go to the App Review Board. Full steps and what tends to work: [Monetization, submission, metadata and appeals](references/monetization-and-submission.md).
360
253
 
361
254
  ## Common mistakes
362
255
 
@@ -396,6 +289,7 @@ Full lists: [review checklists](references/review-checklists.md).
396
289
 
397
290
  ## References
398
291
 
292
+ - [Monetization, submission, metadata and appeals](references/monetization-and-submission.md): IAP versus external purchase rules, entitlement and usage-string expectations, the archive-to-release workflow (expedited review, phased release), and name, screenshot, keyword and preview limits. Also replying to a rejection and filing an appeal.
399
293
  - Guidelines text: https://developer.apple.com/app-store/review/guidelines/
400
294
  - SDK and Xcode deadlines: https://developer.apple.com/news/upcoming-requirements/
401
295
  - Screenshot sizes: https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications/
@@ -0,0 +1,138 @@
1
+ # Monetization, submission, metadata and appeals
2
+
3
+ <!-- toc -->
4
+ - [3.1.1 Paying for digital things](#311-paying-for-digital-things)
5
+ - [Entitlements and usage strings](#entitlements-and-usage-strings)
6
+ - [Submission workflow](#submission-workflow)
7
+ - [Metadata rules](#metadata-rules)
8
+ - [Rejections and appeals](#rejections-and-appeals)
9
+ <!-- /toc -->
10
+
11
+ The 3.1.1 purchase rules, entitlement and usage-string expectations, the submission workflow, metadata limits, and handling rejections and appeals. SKILL.md keeps triage, the guidelines that cause most rejections and the review checklist.
12
+
13
+ ## 3.1.1 Paying for digital things
14
+
15
+ When the app unlocks digital content, a feature, a subscription or a digital
16
+ service, the sale normally runs through Apple IAP, unless a guideline exception, a regional rule or
17
+ an approved entitlement says otherwise.
18
+
19
+ | Needs IAP | Does not need IAP |
20
+ |---|---|
21
+ | Unlocking premium features | Physical goods |
22
+ | Subscriptions to app functionality | Real-world services such as rides or food delivery |
23
+ | Virtual currency | Person-to-person services, for example a live tutor or consultant |
24
+ | Removing ads | Business apps for organizations, distributed as custom apps via Apple Business Manager |
25
+ | Digital tips to creators | Donations to approved nonprofits (see 3.2.1 and 3.2.2) |
26
+
27
+ Rules around the purchase:
28
+
29
+ - Before a subscription is bought, the paywall states what it costs, how long a
30
+ period lasts and that it renews on its own.
31
+ - For a free trial, show the trial length, the price after it, how often billing
32
+ happens, that it renews automatically, and how to cancel, all before purchase.
33
+ - Strip any route to an outside checkout for digital goods, whether a link, a
34
+ button or a nudge in copy, unless the storefront's current rule or a granted
35
+ entitlement permits it. A StoreKit External Purchase Link entitlement or,
36
+ where permitted, a Music Streaming Services entitlement allows a link to a
37
+ permitted destination; the US storefront needs no entitlement. These rules differ by region and have changed recently; read the
38
+ current 3.1.1(a) and 3.1.3 text for the target storefront.
39
+ - Reader apps may link out to account sign-up with the matching entitlement, but
40
+ may not offer a way around IAP for in-app purchases.
41
+
42
+ StoreKit checks:
43
+
44
+ - Products are typed correctly in App Store Connect (consumable, non-consumable,
45
+ subscription).
46
+ - A Restore Purchases control exists and works.
47
+ - Entitlements are verified with StoreKit 2 `Transaction.currentEntitlements` or
48
+ on the server.
49
+ - A purchase that is interrupted, or deferred while a parent approves it through
50
+ Ask to Buy, leaves the UI in a sane state.
51
+
52
+ ## Entitlements and usage strings
53
+
54
+ Every entitlement needs a reason App Review can see in the product.
55
+
56
+ | Capability | What review expects |
57
+ |---|---|
58
+ | Camera | a clear `NSCameraUsageDescription` |
59
+ | Location (Always) | a visible reason the user benefits from background location |
60
+ | Push notifications | no marketing pushes without the user's opt-in |
61
+ | HealthKit | health data used in a meaningful feature |
62
+ | Background Modes | every declared mode (audio, location, VoIP, fetch) has a feature that uses it |
63
+ | App Groups | the shared data is explained |
64
+ | Associated Domains | universal links resolve and open the app |
65
+
66
+ A usage string names the data and the user-facing reason:
67
+
68
+ | Verdict | String |
69
+ |---|---|
70
+ | Approved | "We use where you are to place the closest charging stations on the map." |
71
+ | Approved | "The camera scans a book's barcode so you can add it to your shelf." |
72
+ | Rejected | "This app requires camera access." |
73
+ | Rejected | "We use your photo library to improve your experience." |
74
+ | Fixed | "Pick a photo from your library to use as your profile picture. Only the photo you choose is uploaded." |
75
+
76
+ The second rejected string names a data type but gives no concrete purpose;
77
+ "improve your experience" is the phrase review flags. The fixed version says
78
+ which feature uses the data and what leaves the device.
79
+
80
+ ## Submission workflow
81
+
82
+ 1. Archive: Product > Archive with a Distribution signing identity, from a clean
83
+ Release build. Aim for zero warnings; it is good hygiene, not a review rule.
84
+ 2. Upload: in Organizer choose Distribute App, then App Store Connect; or run
85
+ `xcodebuild -exportArchive`. `altool` and Transporter also work.
86
+ 3. Internal TestFlight: internal testers see the build minutes after processing.
87
+ Try every flow on two or more screen sizes.
88
+ 4. External TestFlight: the first build sent to an external group goes through
89
+ Beta App Review.
90
+ 5. Submit: pick the build, complete metadata, attach screenshots, press Submit
91
+ for Review. Review time varies, so keep slack before a deadline.
92
+
93
+ Expedited review is for a critical fix for existing users, a date-bound event
94
+ (a holiday launch, a legal deadline) or a security patch. Ask through Contact
95
+ Us > App Review > Expedite Request with a specific, factual reason. It is not for
96
+ first launches or new features.
97
+
98
+ Phased release for automatic updates: day 1 1%, day 2 2%, day 3 5%, day 4 10%,
99
+ day 5 20%, day 6 50%, day 7 100%. Users who check for updates by hand get the
100
+ build immediately. The rollout can be paused, resumed or finished early at any
101
+ time.
102
+
103
+ ## Metadata rules
104
+
105
+ - Name and subtitle: 30 characters each. The subtitle is a short value statement.
106
+ A bare category word such as "Photo Editor" is likely rejected; so are
107
+ competitor or trademarked terms and prices. The name must be unique.
108
+ - Screenshots: 1 to 10 per required platform and localization. The
109
+ 6.9-inch iPhone set is the primary one; the 6.5-inch set is required only
110
+ when there is no 6.9-inch set, and smaller iPhones get scaled images. Apps that
111
+ run on iPad need 13-inch iPad screenshots; smaller iPads are scaled.
112
+ - Screenshot content: the real UI; never show a feature the build lacks. Captions and
113
+ frames are fine if they neither hide nor misstate the UI. Localized sets show
114
+ the localized UI.
115
+ - Keywords: 100 characters, comma-separated with no spaces. Words already in the
116
+ name or subtitle are indexed, so do not repeat them. Use singular or plural,
117
+ not both. No competitor, trademark or unrelated terms.
118
+ - App previews: up to 30 seconds, up to 3 per localization, captured from the app
119
+ on a device with the app's own audio (narration or music optional). No
120
+ misleading framing and no footage of hands holding a device. The first frame
121
+ is the poster frame.
122
+
123
+ ## Rejections and appeals
124
+
125
+ - A rejection arrives in the Resolution Center with the guideline number.
126
+ - Reply in that thread with facts. If you fixed the issue, say what changed and
127
+ upload a new binary. If you disagree, show how the app complies, quoting the
128
+ guideline.
129
+ - Keep it professional, specific and short. Attach demo credentials, screenshots
130
+ or a screen recording. No emotional language, no threats.
131
+ - For a formal appeal, go to the App Review Board through the Resolution Center or
132
+ Contact Us > App Review > Appeal. A separate team reads the whole history. The
133
+ ruling is final for that build; a changed build can still be submitted.
134
+
135
+ What tends to work: a video walkthrough of the flagged feature, a point-by-point
136
+ answer against the guideline text, fresh demo credentials (the usual 2.1 cause),
137
+ a polite reference to comparable approved behaviour, and offering an alternative
138
+ implementation.
@@ -89,32 +89,7 @@ Facts that shape every design:
89
89
 
90
90
  Every entry point checks availability and falls back without crashing.
91
91
 
92
- ```swift
93
- import Foundation
94
- import FoundationModels
95
- import os
96
-
97
- private let aiLog = Logger(subsystem: "StudyApp", category: "AI")
98
-
99
- enum SummaryState { case ready, openSettings, downloading, unsupported }
100
-
101
- func summaryState() -> SummaryState {
102
- let model = SystemLanguageModel.default
103
- switch model.availability {
104
- case .available:
105
- return model.supportsLocale(Locale.current) ? .ready : .unsupported
106
- case .unavailable(.appleIntelligenceNotEnabled):
107
- return .openSettings // point the user to Settings
108
- case .unavailable(.modelNotReady):
109
- return .downloading // assets still arriving; show progress
110
- case .unavailable(.deviceNotEligible):
111
- return .unsupported // hardware cannot run it; use a fallback
112
- case .unavailable(let other):
113
- aiLog.notice("Model unavailable: \(String(describing: other))")
114
- return .unsupported
115
- }
116
- }
117
- ```
92
+ Code for this section: [Foundation Models and multi-backend code](references/foundation-models-code.md).
118
93
 
119
94
  ### Sessions
120
95
 
@@ -144,22 +119,6 @@ let resumed = LanguageModelSession(model: .default, tools: [], transcript: saved
144
119
  `@Generable` builds the output schema at compile time, and the response comes
145
120
  back as your type.
146
121
 
147
- ```swift
148
- @Generable
149
- struct StudyCard {
150
- @Guide(description: "The term being studied, two to four words")
151
- var term: String
152
- @Guide(description: "Plain-language definitions", .count(2))
153
- var definitions: [String]
154
- @Guide(.range(1...5))
155
- var difficulty: Int
156
- }
157
-
158
- let reply = try await tutor.respond(to: "Make a card for osmosis",
159
- generating: StudyCard.self)
160
- let card = reply.content
161
- ```
162
-
163
122
  `@Guide` options:
164
123
 
165
124
  | Guide | Effect |
@@ -178,38 +137,12 @@ Fields are generated in declaration order. Put the fields that others depend on
178
137
  first.
179
138
 
180
139
  Streaming gives partial values as they form; each property of
181
- `StudyCard.PartiallyGenerated` is optional:
140
+ `StudyCard.PartiallyGenerated` is optional.
182
141
 
183
- ```swift
184
- let cardStream = tutor.streamResponse(to: "Card for diffusion", generating: StudyCard.self)
185
- for try await partial in cardStream {
186
- draft.term = partial.content.term ?? draft.term
187
- draft.definitions = partial.content.definitions ?? draft.definitions
188
- }
189
- ```
142
+ Code for this section: [Foundation Models and multi-backend code](references/foundation-models-code.md).
190
143
 
191
144
  ### Tools
192
145
 
193
- ```swift
194
- struct GlossaryTool: Tool {
195
- let name = "lookUpTerm"
196
- let description = "Returns the course glossary entry for a biology term."
197
-
198
- @Generable
199
- struct Arguments {
200
- @Guide(description: "Singular form of the term to look up")
201
- var term: String
202
- @Guide(.range(1...3))
203
- var gradeLevel: Int
204
- }
205
-
206
- func call(arguments: Arguments) async throws -> String {
207
- await Glossary.shared.entry(for: arguments.term, level: arguments.gradeLevel)
208
- ?? "No entry found."
209
- }
210
- }
211
- ```
212
-
213
146
  - Register tools when creating the session, and only the ones the task needs.
214
147
  - `Tool` is `Sendable`; captured state must be safe to share.
215
148
  - Tool names, descriptions and argument schemas, like `@Generable` schemas,
@@ -218,27 +151,11 @@ struct GlossaryTool: Tool {
218
151
  should be fetched beforehand and put in the prompt; keep tools for lookups
219
152
  that depend on the conversation.
220
153
 
154
+ Code for this section: [Foundation Models and multi-backend code](references/foundation-models-code.md).
155
+
221
156
  ### Errors
222
157
 
223
- ```swift
224
- do {
225
- let answer = try await tutor.respond(to: question)
226
- show(answer.content)
227
- } catch let failure as LanguageModelSession.GenerationError {
228
- switch failure {
229
- case .exceededContextWindowSize: restartWithSummary() // too many tokens
230
- case .guardrailViolation: showRephraseHint() // safety filter hit
231
- case .concurrentRequests: queueUntilIdle() // session already busy
232
- case .unsupportedLanguageOrLocale: showLanguageNotice()
233
- case .unsupportedGuide: logSchemaProblem() // a @Guide the model cannot honour
234
- case .assetsUnavailable: showDownloadingState()
235
- case .refusal(let refusal, _): explain(refusal) // stream refusal.explanation
236
- case .rateLimited: retryLater() // back off
237
- case .decodingFailure: logSchemaProblem() // output did not fit the type
238
- default: showGenericFailure()
239
- }
240
- }
241
- ```
158
+ Code for this section: [Foundation Models and multi-backend code](references/foundation-models-code.md).
242
159
 
243
160
  ### Generation options
244
161
 
@@ -374,46 +291,21 @@ MLX lifecycle, llama.cpp and GGUF: [the MLX and llama.cpp guide](references/mlx-
374
291
  ## Running several backends
375
292
 
376
293
  Try the system model first, then a local open model, and fail clearly when
377
- neither is there:
378
-
379
- ```swift
380
- func pickBackend() async throws -> Backend {
381
- let systemModel = SystemLanguageModel.default
382
- if systemModel.isAvailable { return .foundationModels }
383
- if await mlxModelCanLoad() { return .mlx }
384
- throw AIError.noBackendAvailable
385
- }
386
- ```
294
+ neither is there.
387
295
 
388
296
  Send every model call through one actor so requests never compete for the same
389
297
  hardware. Actors are reentrant: a method that awaits lets the next caller in,
390
298
  so an actor that only forwards the call does not serialise anything. Chain the
391
299
  work instead:
392
300
 
393
- ```swift
394
- actor InferenceGate {
395
- private var last: Task<Void, Never>?
396
-
397
- func exclusive<Value: Sendable>(
398
- _ work: @escaping @Sendable () async throws -> Value
399
- ) async throws -> Value {
400
- let previous = last
401
- let current = Task { () async throws -> Value in
402
- await previous?.value
403
- return try await work()
404
- }
405
- last = Task { _ = try? await current.value }
406
- return try await current.value
407
- }
408
- }
409
- ```
410
-
411
301
  - For a custom Core ML model, this skill stops at conversion and
412
302
  optimisation. Swift integration, loading, Vision hookup and running
413
303
  predictions are for `coreml`.
414
304
  - Private material such as journals or health notes stays on the device unless
415
305
  the product has deliberately chosen a non-local fallback.
416
306
 
307
+ Code for this section: [Foundation Models and multi-backend code](references/foundation-models-code.md).
308
+
417
309
  ## Performance habits
418
310
 
419
311
  1. Benchmark without the debugger: in the scheme's Run action (Cmd-Opt-R),
@@ -457,6 +349,7 @@ actor InferenceGate {
457
349
 
458
350
  ## Reference files
459
351
 
352
+ - [Foundation Models and multi-backend code](references/foundation-models-code.md): open for the code behind availability checks, `@Generable` output, tools, error handling and backend routing.
460
353
  - [Foundation Models reference](references/foundation-models.md): the full API,
461
354
  long conversations, feedback.
462
355
  - [Conversion guide](references/coreml-conversion.md): coremltools from each