@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.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 (284) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +285 -285
  5. package/package.json +3 -3
  6. package/pipeline/lib/redact.mjs +3 -2
  7. package/pipeline/scripts/_notices.mjs +1 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +13 -1
  9. package/pipeline/scripts/pre-commit-check.sh +4 -0
  10. package/pipeline/skills/.skill-manifest.json +69 -69
  11. package/pipeline/skills/shared/README.md +70 -70
  12. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  13. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  14. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  15. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  16. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  17. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  18. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  19. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  20. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  21. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  22. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  23. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +345 -277
  24. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  25. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +107 -121
  26. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +145 -165
  27. package/pipeline/skills/shared/external/app-store-review/SKILL.md +306 -326
  28. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  29. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  30. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  31. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +335 -360
  32. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  34. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  35. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  37. package/pipeline/skills/shared/external/authentication/SKILL.md +277 -381
  38. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  39. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +135 -178
  40. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  41. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  42. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  43. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  44. package/pipeline/skills/shared/external/background-processing/SKILL.md +274 -384
  45. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  46. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +173 -321
  47. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  48. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  49. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  50. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  51. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  52. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  53. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  54. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  55. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  56. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +228 -376
  57. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  58. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  59. package/pipeline/skills/shared/external/core-data/SKILL.md +302 -368
  60. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  61. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  62. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  63. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  64. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  65. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  66. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  67. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  68. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  69. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  70. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  71. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  72. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  73. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  74. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  75. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  76. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  77. package/pipeline/skills/shared/external/device-integrity/SKILL.md +236 -353
  78. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  79. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  80. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  81. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  82. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  83. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  84. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  85. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  86. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  87. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  88. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  89. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  90. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  91. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  92. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  93. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  94. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  95. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  96. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  97. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  98. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  99. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  100. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  101. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  102. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  103. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  104. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  105. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  106. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  107. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  108. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  109. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  111. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  112. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  113. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  114. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +3 -3
  115. package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +1 -1
  116. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +8 -7
  117. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +2 -2
  118. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +5 -2
  119. package/pipeline/skills/shared/external/localization-reuse-map/scripts/_shared.py +100 -0
  120. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +45 -26
  121. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +14 -16
  122. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +12 -5
  123. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +2 -1
  124. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +6 -5
  125. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +44 -18
  126. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +5 -2
  127. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +10 -11
  128. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +4 -33
  129. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +12 -59
  130. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +297 -267
  131. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  132. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  133. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  134. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  135. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  136. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  137. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  138. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  139. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  140. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  141. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  142. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  143. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  144. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  145. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  146. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  147. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  148. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  149. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  150. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  151. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  152. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  153. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  154. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  155. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  156. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  157. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  158. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  159. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  160. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  161. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  162. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  163. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  164. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  165. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  166. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  167. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  168. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  169. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  170. package/pipeline/skills/shared/external/skill-creator/template.md +7 -1
  171. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  172. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  173. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  174. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  175. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  176. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  177. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +302 -241
  178. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  179. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  180. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  181. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  182. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  183. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  184. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  185. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  186. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  187. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  188. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  189. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  191. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +304 -351
  193. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  194. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  195. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  196. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  197. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  198. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  199. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  200. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  201. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  202. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  203. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  204. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  205. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  206. package/pipeline/skills/shared/external/swift-security/SKILL.md +183 -162
  207. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  208. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  209. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +411 -476
  210. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  211. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  212. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  213. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  214. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  215. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  216. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +375 -491
  217. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  218. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  219. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  220. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +397 -457
  221. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  222. package/pipeline/skills/shared/external/swift-testing/SKILL.md +191 -175
  223. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  224. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +81 -84
  225. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  226. package/pipeline/skills/shared/external/swiftdata/SKILL.md +394 -256
  227. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  228. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  229. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  230. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  231. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  232. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  233. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  234. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  235. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  236. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  237. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  238. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  239. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  240. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  241. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  242. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  243. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  244. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  245. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  246. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  247. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  248. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  249. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  250. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  251. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +201 -168
  252. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  253. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +134 -133
  254. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  255. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +111 -138
  256. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  257. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  258. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  259. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  260. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  261. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  262. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  263. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  264. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  265. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  266. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  267. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  268. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  269. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  270. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  271. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  272. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  273. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  274. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  275. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  276. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  277. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  278. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  279. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  280. package/pipeline/skills/shared/external/weatherkit/SKILL.md +160 -315
  281. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  282. package/pipeline/skills/shared/external/widgetkit/SKILL.md +224 -288
  283. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +416 -719
  284. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -4,41 +4,45 @@
4
4
  {
5
5
  "id": 0,
6
6
  "name": "app-attest-attestation-verifier",
7
- "prompt": "We're adding server-side App Attest verification for an iOS app. The client sends keyId, attestationObject, and the original one-time challenge. What exact checks should the verifier perform before storing anything?",
8
- "expected_output": "A source-grounded App Attest attestation verification checklist that covers CBOR/certificate validation, nonce composition, App ID and environment checks, credential ID/keyId checks, and storing verified public key plus receipt.",
7
+ "prompt": "Our backend team is writing the endpoint that receives App Attest attestation objects from the iOS client. List what the verifier has to check and what it should persist afterwards.",
8
+ "expected_output": "Walks through CBOR decoding, certificate chain validation against the App Attest root CA, nonce = SHA256(authData || SHA256(challenge)) matched against the certificate value under OID 1.2.840.113635.100.8.2, public key hash equal to keyId, RP ID hash equal to SHA256(teamID.bundleID), counter 0, aaguid for the expected environment, credentialId equal to keyId, then storing the public key and receipt and consuming the challenge only after success.",
9
9
  "files": [],
10
10
  "expectations": [
11
- "Computes `clientDataHash = SHA256(challenge)`, then verifies the certificate nonce against `SHA256(authData || clientDataHash)` rather than `SHA256(challenge)` alone.",
12
- "Names the credential certificate extension OID `1.2.840.113635.100.8.2` as the source of the nonce value to compare.",
13
- "Verifies the App ID/RP ID hash, environment `aaguid`, initial counter, `credentialId`, and keyId/public-key hash relationship.",
14
- "Stores the verified public key and receipt for future assertion and fraud-risk use instead of treating the raw attestation object as the trusted durable record."
11
+ "Composes the nonce from authData and the hashed challenge, SHA256(authData || SHA256(challenge)), rather than hashing the challenge alone",
12
+ "Compares the nonce with the certificate extension at 1.2.840.113635.100.8.2",
13
+ "Checks the RP ID or App ID hash against team ID plus bundle ID",
14
+ "Checks aaguid for the expected environment and an initial counter of 0",
15
+ "Requires credentialId and the public key hash to match keyId",
16
+ "Keeps the public key and receipt after verification, not the raw attestation object"
15
17
  ]
16
18
  },
17
19
  {
18
20
  "id": 1,
19
- "name": "app-attest-sensitive-request-assertion",
20
- "prompt": "Design the App Attest assertion contract for a premium-content download endpoint. The app already has an attested key. What should the client sign and what should the server verify on every sensitive request?",
21
- "expected_output": "A replay-safe assertion design that signs client data containing a server challenge and request context, then verifies assertion CBOR, signature, RP ID, counter, challenge, and request binding server-side.",
21
+ "name": "gift-card-assertion-flow",
22
+ "prompt": "We want to protect our 'redeem gift card' POST endpoint with App Attest assertions. Show the client side and explain what the server verifies.",
23
+ "expected_output": "Fetches a fresh one-time challenge per request, builds client data with the challenge plus method, path and a body digest, hashes it, calls generateAssertion, sends assertion and client data in headers; server checks that the stored key signed SHA256(authenticatorData || SHA256(clientData)), RP ID, a strictly increasing counter, and that the challenge and request context match.",
22
24
  "files": [],
23
25
  "expectations": [
24
- "Requires a fresh one-time server challenge for the assertion flow and embeds it in the client data.",
25
- "Includes request context or a request-body hash in the signed client data so the assertion is bound to the sensitive request.",
26
- "Verifies the assertion signature over `SHA256(authenticatorData || SHA256(clientData))` using the public key stored from attestation.",
27
- "Checks the RP ID hash, monotonically increasing counter, and embedded challenge before accepting the request."
26
+ "Uses a fresh server-issued one-time challenge inside the client data",
27
+ "Binds request context or a body hash into the signed client data",
28
+ "Describes the signature as covering SHA256(authenticatorData || SHA256(clientData))",
29
+ "Server checks the RP ID hash and that the counter increases",
30
+ "Server confirms the challenge was issued and not yet consumed"
28
31
  ]
29
32
  },
30
33
  {
31
34
  "id": 2,
32
- "name": "device-integrity-boundary-and-errors",
33
- "prompt": "Review this plan: cache a DCDevice token for the whole install, use one App Attest key for all users, retry any attestKey failure with a new key immediately, treat invalidKey as an OS update problem, and add OAuth/session-token/certificate-pinning advice to the same device-integrity checklist. What should be corrected?",
34
- "expected_output": "A boundary-aware correction list that fixes DeviceCheck token reuse, App Attest key scope, retry/error handling, environment behavior, and routes unrelated authentication/network security work to sibling guidance.",
35
+ "name": "integrity-plan-review",
36
+ "prompt": "Review our plan: cache the DeviceCheck token for a day, generate a new App Attest key each launch, retry every DCError with a new key, and use App Attest instead of OAuth sessions and certificate pinning. What would you change?",
37
+ "expected_output": "Makes DCDevice tokens single-use, keeps one key per account per device and warns that extra keys affect risk metrics, retries serverUnavailable reusing its keyId and clientDataHash while discarding the key for other attestation errors, explains invalidKey causes (already attested, not attested, rejected) without inventing causes such as system updates or enclave resets, and routes OAuth, sessions and pinning to the authentication and swift-security skills.",
35
38
  "files": [],
36
39
  "expectations": [
37
- "States that `DCDevice.generateToken()` tokens are single-use and should not be cached for the whole install.",
38
- "Requires App Attest keys to be unique per user account on each device and warns against unnecessary key generation because it affects risk metrics.",
39
- "For `serverUnavailable`, retries attestation later with the same key and same `clientDataHash`; for other attestation errors, discards the key identifier before a new-key retry.",
40
- "Describes `invalidKey` using Apple-documented causes: already-attested key, unattested assertion key, or service rejection, without attributing it to OS updates or Secure Enclave resets.",
41
- "Keeps OAuth/session-token design, certificate pinning, and broad networking security out of the device-integrity checklist except as sibling-skill handoffs."
40
+ "Says DCDevice tokens are single-use and must not be cached",
41
+ "Keeps one key per account per device and mentions the key-count risk metric",
42
+ "On serverUnavailable, retries later reusing the identical keyId and clientDataHash",
43
+ "Discards the key and generates a new one for other attestation errors",
44
+ "Gives the three real invalidKey causes and does not invent others such as system updates or enclave resets",
45
+ "Routes OAuth, sessions and pinning to sibling skills instead of App Attest"
42
46
  ]
43
47
  }
44
48
  ]
@@ -1,223 +1,187 @@
1
- # Device Integrity Extended Patterns
2
-
3
- Overflow reference for the `device-integrity` skill. Contains server verification details, advanced error handling, and integration patterns.
4
-
5
- ## Contents
6
-
7
- - [Server-Side Attestation Verification](#server-side-attestation-verification)
8
- - [Server-Side Assertion Verification](#server-side-assertion-verification)
9
- - [Server Architecture](#server-architecture)
10
- - [Error Handling](#error-handling)
11
- - [Retry Strategy](#retry-strategy)
12
- - [Handling Rejected Keys](#handling-rejected-keys)
13
- - [Full Integration Manager](#full-integration-manager)
14
- - [Gradual Rollout](#gradual-rollout)
15
- - [Environment Entitlement](#environment-entitlement)
16
-
17
- ## Server-Side Attestation Verification
18
-
19
- Your server must:
20
- 1. Verify the attestation object is a valid CBOR-encoded structure.
21
- 2. Extract the certificate chain and validate it against Apple's App Attest root CA.
22
- 3. Compute `clientDataHash = SHA256(challenge)`, append it to the decoded
23
- `authData`, then compute `nonce = SHA256(authData || clientDataHash)`.
24
- 4. Extract the credential certificate extension with OID
25
- `1.2.840.113635.100.8.2` and verify its octet string equals `nonce`.
26
- 5. Verify the public-key hash matches the app-provided `keyId`.
27
- 6. Verify the `RP ID` hash matches `SHA256(teamID + "." + bundleID)`.
28
- 7. Verify the initial counter is `0`, the `aaguid` matches the expected
29
- development or production environment, and `credentialId` equals `keyId`.
30
- 8. Store the verified public key and receipt for future assertion verification.
31
- 9. Mark the challenge consumed only after every verification step succeeds,
32
- ideally in the same transaction that stores the key state.
33
-
34
- See [Validating apps that connect to your server](https://sosumi.ai/documentation/devicecheck/validating-apps-that-connect-to-your-server) for the full server verification algorithm.
35
-
36
- ## Server-Side Assertion Verification
37
-
38
- Your server must:
39
- 1. Decode the assertion (CBOR).
40
- 2. Recompute `clientDataHash = SHA256(clientData)`, where `clientData`
41
- includes a one-time server challenge and request context.
42
- 3. Verify the signature using the stored public key over
1
+ # Device Integrity Patterns
2
+
3
+ Server verification, backend layout, error recovery and rollout for DeviceCheck
4
+ and App Attest. The client basics are in the [skill overview](../SKILL.md).
5
+
6
+ ## Verifying an attestation on the server
7
+
8
+ Run every step; reject on the first failure.
9
+
10
+ 1. Decode the attestation object and confirm the CBOR structure is well formed.
11
+ 2. Extract the certificates and confirm they chain up to Apple's App Attest root.
12
+ 3. Hash the challenge you issued (`clientDataHash = SHA256(challenge)`), concatenate
13
+ `authData` and that hash, then hash again: `nonce = SHA256(authData || clientDataHash)`.
14
+ 4. The leaf certificate carries an extension, OID `1.2.840.113635.100.8.2`,
15
+ whose octet string has to be byte-for-byte equal to `nonce`.
16
+ 5. Hash the credential certificate's public key. It must match the `keyId` the app sent.
17
+ 6. The RP ID hash in `authData` must equal `SHA256(teamID + "." + bundleID)`.
18
+ 7. The counter must be `0`, `aaguid` must name the environment you expect
19
+ (development or production), and `credentialId` must equal `keyId`.
20
+ 8. Persist the public key you just verified plus the receipt. Keep those, not the raw attestation object.
21
+ 9. Burn the challenge only once steps 1 to 8 all pass, ideally in the same
22
+ database transaction that writes the key record.
23
+
24
+ ## Verifying an assertion on the server
25
+
26
+ 1. Decode the CBOR assertion into `authenticatorData` and `signature`.
27
+ 2. Compute `clientDataHash = SHA256(clientData)`. The client data carries the
28
+ one-time challenge and the request context.
29
+ 3. Verify `signature` with the stored public key over
43
30
  `SHA256(authenticatorData || clientDataHash)`.
44
- 4. Verify the `RP ID` hash and the counter (greater than the stored counter, or
45
- greater than `0` for the first assertion).
46
- 5. Confirm the embedded challenge matches the issued challenge and the request
47
- context binds the assertion to the received request.
48
- 6. Mark the challenge consumed and update the stored counter only after every
49
- verification step succeeds, ideally atomically.
50
-
51
- ## Server Architecture
52
-
53
- ### Attestation vs. Assertion
54
-
55
- | Phase | When | What It Proves | Frequency |
56
- |-------|------|---------------|-----------|
57
- | **Attestation** | After key generation | The key lives on a genuine Apple device running a legitimate instance of your app | Once per key |
58
- | **Assertion** | With each sensitive request | The request came from the attested app instance | Per request |
59
-
60
- ### Recommended Server Architecture
61
-
62
- 1. **Challenge endpoint** -- generate a random nonce with at least 16 bytes of entropy, store it server-side with a short TTL (e.g., 5 minutes), purpose, and expected request/key context.
63
- 2. **Attestation verification endpoint** -- validate the attestation object, store the public key and receipt keyed by `keyId`.
64
- 3. **Assertion verification middleware** -- verify assertions on sensitive endpoints (purchases, account changes).
65
-
66
- Reject expired, missing, mismatched, or already-consumed challenges. Consume a
67
- challenge only after the corresponding attestation or assertion is fully
68
- verified; consuming on receipt can block safe retries after transient failures.
69
-
70
- ### Risk Assessment
71
-
72
- Combine App Attest with [fraud risk assessment](https://sosumi.ai/documentation/devicecheck/assessing-fraud-risk) for defense in depth. App Attest alone does not guarantee the user is not abusing the app -- it confirms the app is genuine.
73
-
74
- App Attest is not a user authentication, session, entitlement, TLS, certificate
75
- pinning, or subscription validation system. Keep those controls in the
76
- appropriate authentication, networking, or broader security layer, and require
77
- them in addition to App Attest on protected endpoints.
78
-
79
- ## Error Handling
80
-
81
- ### DCError Codes
31
+ 4. Check the RP ID hash, and require the counter to be greater than the stored
32
+ counter; on a key's first assertion anything above zero passes.
33
+ 5. Confirm the embedded challenge is the one you issued and that the request
34
+ context (method, path, body digest) matches the request that arrived.
35
+ 6. Consume the challenge and store the new counter only after everything passes,
36
+ preferably atomically.
37
+
38
+ ## Server architecture
39
+
40
+ ### Attestation versus assertion
41
+
42
+ | | Attestation | Assertion |
43
+ |---|---|---|
44
+ | When | Right after key generation | On every sensitive request |
45
+ | Proves | Real hardware, real app, holds this key | This request came from that attested instance |
46
+ | Frequency | Once per key | Once per request |
47
+
48
+ ### Suggested services
49
+
50
+ - **Challenge endpoint** - hands out random nonces (16 or more bytes of
51
+ entropy). Store it with a short time to live (about five minutes), its purpose,
52
+ and the key or request it is meant for.
53
+ - **Attestation endpoint** - runs the attestation steps and stores the public
54
+ key and receipt indexed by `keyId`.
55
+ - **Assertion middleware** - sits in front of purchases, account changes and
56
+ other sensitive routes and runs the assertion steps.
57
+
58
+ Reject a challenge that is missing, expired, already used, or issued for a
59
+ different context. Consume it only after full verification; burning it the
60
+ moment it arrives turns a transient failure into a lost challenge and blocks a
61
+ safe retry.
62
+
63
+ ### Risk assessment
64
+
65
+ Pair App Attest with Apple's fraud risk assessment for defense in depth. App
66
+ Attest confirms the binary is genuine; it cannot tell you whether the person
67
+ using it is abusing your service. It is also not user authentication, session
68
+ management, entitlement or subscription validation, TLS or pinning. Protected
69
+ endpoints still require all of those. Route sign-in work to `authentication`,
70
+ transport security to `ios-networking`, and Keychain or pinning policy to
71
+ `swift-security`.
72
+
73
+ ## Handling `DCError`
82
74
 
83
75
  ```swift
84
76
  import DeviceCheck
85
77
 
86
- func handleAttestError(_ error: Error) {
87
- if let dcError = error as? DCError {
88
- switch dcError.code {
89
- case .unknownSystemFailure:
90
- // Transient system error -- retry with exponential backoff
91
- break
92
- case .featureUnsupported:
93
- // Device or OS does not support this feature
94
- // Fall back to alternative verification
95
- break
96
- case .invalidKey:
97
- // Already-attested key, unattested assertion key, or service rejection
98
- // Inspect local/server state; discard and regenerate only when bad
99
- break
100
- case .invalidInput:
101
- // The clientDataHash or keyId was malformed
102
- break
103
- case .serverUnavailable:
104
- // Retry attestation later with the same keyId and clientDataHash
105
- break
106
- @unknown default:
107
- break
108
- }
78
+ enum AttestRecovery {
79
+ case retryLater, useDeviceCheck, inspectKeyState, fixInput, giveUp
80
+ }
81
+
82
+ func recovery(for error: DCError) -> AttestRecovery {
83
+ switch error.code {
84
+ case .unknownSystemFailure:
85
+ return .retryLater // transient system problem, back off
86
+ case .featureUnsupported:
87
+ return .useDeviceCheck // no App Attest on this device or OS
88
+ case .invalidKey:
89
+ return .inspectKeyState // regenerate only if the key is confirmed bad
90
+ case .invalidInput:
91
+ return .fixInput // malformed clientDataHash or keyId
92
+ case .serverUnavailable:
93
+ return .retryLater // same keyId and same hash on retry
94
+ @unknown default:
95
+ return .giveUp
109
96
  }
110
97
  }
111
98
  ```
112
99
 
113
- ## Retry Strategy
100
+ ## Retry strategy
114
101
 
115
102
  ```swift
116
- import CryptoKit
117
-
118
- extension AppAttestManager {
119
- func attestKeyWithRetry(challenge: Data, maxAttempts: Int = 3) async throws -> Data {
120
- guard let keyId else {
121
- throw DeviceIntegrityError.keyNotGenerated
122
- }
123
-
124
- let clientDataHash = Data(SHA256.hash(data: challenge))
125
- var lastError: Error?
126
-
127
- for attempt in 0..<maxAttempts {
128
- do {
129
- return try await service.attestKey(keyId, clientDataHash: clientDataHash)
130
- } catch let error as DCError where error.code == .serverUnavailable {
131
- lastError = error
132
- if attempt < maxAttempts - 1 {
133
- try await Task.sleep(for: .seconds(pow(2.0, Double(attempt + 1))))
134
- }
135
- } catch {
136
- throw error // Non-retryable errors propagate immediately
137
- }
103
+ func withAttestRetry<T>(
104
+ maxAttempts: Int = 3,
105
+ _ operation: () async throws -> T
106
+ ) async throws -> T {
107
+ var lastError: Error?
108
+ for attempt in 0..<maxAttempts {
109
+ do {
110
+ return try await operation()
111
+ } catch let failure as DCError {
112
+ guard failure.code == .serverUnavailable else { throw failure }
113
+ lastError = failure
114
+ let backoff = Duration.seconds(1 << (attempt + 1))
115
+ try await Task.sleep(for: backoff)
138
116
  }
139
-
140
- throw lastError ?? DeviceIntegrityError.attestationFailed
141
117
  }
118
+ throw lastError ?? IntegrityError.attestationFailed
142
119
  }
143
120
  ```
144
121
 
145
- Use the same `challenge`, `keyId`, and `clientDataHash` for each retry after
146
- `.serverUnavailable`. Do not fetch a fresh challenge for that retry loop unless
147
- you are also starting over with a new attestation attempt.
122
+ Only `.serverUnavailable` loops; every other error leaves immediately. Across
123
+ those retries nothing changes: one challenge, one `keyId`, one `clientDataHash`. Ask for a
124
+ new challenge only when you begin a brand-new attestation attempt.
148
125
 
149
- ## Handling Rejected Keys
126
+ ## Rejected keys
150
127
 
151
- `DCError.invalidKey` means the app called `attestKey` for an already-attested
152
- key, called `generateAssertion` with an unattested key, or the App Attest service
153
- rejected the key. If local/server state confirms the key cannot be used, delete
154
- the stored `keyId` and generate a new key:
128
+ `invalidKey` has three causes: `attestKey` on a key that is already attested,
129
+ `generateAssertion` with a key that was never attested, or the service
130
+ rejecting the key. Check local and server state first. When it confirms the key
131
+ is unusable, remove it from the Keychain with the **same account-scoped query
132
+ used to save it**, clear the cached value, and enroll again:
155
133
 
156
134
  ```swift
157
- extension AppAttestManager {
158
- func handleRejectedKey() async throws -> String {
159
- deleteKeyIdFromKeychain()
160
- keyId = nil
135
+ extension AttestKeyStore {
136
+ func discardKeyAndReenroll() async throws -> String {
137
+ let status = SecItemDelete(baseQuery as CFDictionary)
138
+ if status != errSecSuccess && status != errSecItemNotFound {
139
+ throw IntegrityError.keyNotGenerated
140
+ }
141
+ keyID = nil
161
142
  return try await generateKeyIfNeeded()
162
143
  }
163
-
164
- private func deleteKeyIdFromKeychain() {
165
- let query: [String: Any] = [
166
- kSecClass as String: kSecClassGenericPassword,
167
- kSecAttrAccount as String: "app-attest-key-id",
168
- kSecAttrService as String: Bundle.main.bundleIdentifier ?? ""
169
- ]
170
- SecItemDelete(query as CFDictionary)
171
- }
172
144
  }
173
145
  ```
174
146
 
175
- ## Full Integration Manager
176
-
177
- Combine the patterns above into a single `actor` that manages the full lifecycle:
178
- 1. Check `isSupported` and fall back to `DCDevice` tokens on unsupported devices.
179
- 2. Call `generateKeyIfNeeded()` for each user account on each device, reuse the
180
- account/device-scoped `keyId`, and limit new key generation to new
181
- account/device/install enrollment or confirmed bad-key recovery.
182
- 3. Attest once per key; if `.serverUnavailable` occurs, retry with the same
183
- challenge, key, and `clientDataHash`.
184
- 4. For each sensitive request, obtain a one-time assertion challenge and sign
185
- client data that includes the challenge plus request context.
186
- 5. Handle `DCError.invalidKey` by checking whether the key was already attested,
187
- not yet attested, or rejected before regenerating.
147
+ `baseQuery` is the actor property from the skill overview and already
148
+ includes `"attest-key.\(accountID)"` as `kSecAttrAccount`. Building a separate
149
+ delete query with a bare account string would miss the stored item, leave the
150
+ stale `keyId` behind, and the next launch would load it again.
188
151
 
189
- ## Gradual Rollout
152
+ ## Integration outline
190
153
 
191
- Apple recommends a gradual rollout. Gate App Attest behind a remote feature
192
- flag and fall back to `DCDevice` tokens on unsupported devices. For large apps,
193
- ramp production adoption gradually and be prepared to reduce attestation traffic
194
- if `.serverUnavailable` or rate-limit behavior increases during rollout.
154
+ 1. Check `DCAppAttestService.shared.isSupported`; when false, fall back to `DCDevice`.
155
+ 2. Call `generateKeyIfNeeded()` for the signed-in account. A new key is justified
156
+ only for a new account, device or install enrollment, or for confirmed
157
+ bad-key recovery.
158
+ 3. Attest once per key. On `.serverUnavailable`, retry with the same challenge,
159
+ key and hash.
160
+ 4. For each sensitive request, fetch a one-time challenge and sign it together
161
+ with the request context.
162
+ 5. On `invalidKey`, establish whether the key is already attested, not attested,
163
+ or rejected before replacing it.
195
164
 
196
- ## Environment Entitlement
165
+ ## Gradual rollout
197
166
 
198
- Set the App Attest environment in your entitlements file. Use `development`
199
- during testing and `production` for App Store builds:
167
+ Apple recommends enabling App Attest gradually. Put it behind a remote feature
168
+ flag, keep the `DCDevice` fallback for unsupported devices, and ramp large
169
+ audiences in steps. Be ready to switch attestation traffic off if
170
+ `.serverUnavailable` errors or rate limiting climb.
200
171
 
201
- ```xml
202
- <key>com.apple.developer.devicecheck.appattest-environment</key>
203
- <string>production</string>
204
- ```
205
-
206
- When the entitlement is omitted during development, the app uses the App Attest
207
- sandbox by default. After distribution through TestFlight, the App Store, or the
208
- Apple Developer Enterprise Program, the app ignores the entitlement value and
209
- uses production. Sandbox keys and receipts do not work in production, and
210
- production keys and receipts do not work in sandbox.
172
+ ## Environment entitlement
211
173
 
212
- If an App Clip or extension uses App Attest, configure the capability for that
213
- target too. App Attest is supported only in Action, extensible SSO, and watchOS
214
- extensions; other extension types are unsupported even if `isSupported` returns
215
- `true`.
174
+ The environment entitlement (`...devicecheck.appattest-environment`) is
175
+ `development` or `production`. Development builds without it use the sandbox; TestFlight, App
176
+ Store and Enterprise builds always use production. Keys and receipts from one
177
+ environment fail in the other, so route server verification to match. App
178
+ Clips and extensions that call App Attest need the capability on their own
179
+ target as well.
216
180
 
217
- ### Error Type
181
+ ### Error type used in the examples
218
182
 
219
183
  ```swift
220
- enum DeviceIntegrityError: Error {
184
+ enum IntegrityError: Error {
221
185
  case deviceCheckUnsupported
222
186
  case keyNotGenerated
223
187
  case attestationFailed
@@ -227,14 +191,12 @@ enum DeviceIntegrityError: Error {
227
191
  }
228
192
  ```
229
193
 
230
- ## Apple Documentation Links
231
-
232
- - [DeviceCheck framework](https://sosumi.ai/documentation/devicecheck)
233
- - [DCDevice](https://sosumi.ai/documentation/devicecheck/dcdevice)
234
- - [DCAppAttestService](https://sosumi.ai/documentation/devicecheck/dcappattestservice)
235
- - [Establishing your app's integrity](https://sosumi.ai/documentation/devicecheck/establishing-your-app-s-integrity)
236
- - [Validating apps that connect to your server](https://sosumi.ai/documentation/devicecheck/validating-apps-that-connect-to-your-server)
237
- - [Assessing fraud risk](https://sosumi.ai/documentation/devicecheck/assessing-fraud-risk)
238
- - [Preparing to use the app attest service](https://sosumi.ai/documentation/devicecheck/preparing-to-use-the-app-attest-service)
239
- - [Attestation Object Validation Guide](https://sosumi.ai/documentation/devicecheck/attestation-object-validation-guide)
240
- - [App Attest Environment](https://sosumi.ai/documentation/bundleresources/entitlements/com.apple.developer.devicecheck.appattest-environment)
194
+ ## Apple documentation
195
+
196
+ - [DeviceCheck framework](https://developer.apple.com/documentation/devicecheck), whose article list includes
197
+ the app integrity overview, validating apps that talk to your server, the
198
+ attestation object guide, and preparation steps for the App Attest service
199
+ - [Fraud risk assessment](https://developer.apple.com/documentation/devicecheck/assessing-fraud-risk)
200
+ - [DCAppAttestService](https://developer.apple.com/documentation/devicecheck/dcappattestservice)
201
+ - [DCDevice](https://developer.apple.com/documentation/devicecheck/dcdevice)
202
+ - The App Attest environment page under Bundle Resources > Entitlements