@mmerterden/multi-agent-pipeline 20.6.0 → 20.8.0

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 (326) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +328 -329
  5. package/package.json +2 -2
  6. package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
  7. package/pipeline/scripts/_notices.mjs +12 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +1 -1
  9. package/pipeline/skills/.skill-manifest.json +106 -106
  10. package/pipeline/skills/shared/README.md +71 -71
  11. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
  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/android-architecture/SKILL.md +2 -0
  16. package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
  17. package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
  18. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  19. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  20. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  21. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  22. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  23. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  24. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  25. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  26. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  27. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  28. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  29. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  30. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  31. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  32. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  33. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  34. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  35. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  37. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  38. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  39. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  40. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  41. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  42. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  43. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  44. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  45. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  46. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  47. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  48. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  49. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  50. package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
  51. package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
  52. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  53. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  54. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  55. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
  56. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  57. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  58. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  59. package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
  60. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
  61. package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
  62. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  63. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  64. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  65. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  66. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  67. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  68. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  69. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  70. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  71. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  72. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  73. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  74. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  75. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  76. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  77. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  78. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  79. package/pipeline/skills/shared/external/council/SKILL.md +1 -0
  80. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  81. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  82. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  83. package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
  84. package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
  85. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  86. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  87. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  88. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  89. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  90. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  91. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  92. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  93. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  94. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  95. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  96. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  97. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  98. package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
  99. package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
  100. package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
  101. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  102. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  103. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  104. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  105. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  106. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  107. package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
  108. package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
  109. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  110. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  111. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  112. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  113. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  114. package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
  115. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  116. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  117. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  118. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  119. package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
  120. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  121. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  122. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  123. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  124. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  125. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  126. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  127. package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
  128. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  129. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  130. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  131. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  132. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  133. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  134. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
  135. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
  136. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
  137. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
  138. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
  139. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
  140. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
  141. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
  142. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
  143. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
  144. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
  145. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
  146. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
  147. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
  148. package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
  149. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
  150. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  151. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  152. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  153. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  154. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  155. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  156. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  157. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  158. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  159. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  160. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  161. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  162. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  163. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
  164. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  165. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  166. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  167. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  168. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  169. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  170. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  171. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  172. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  173. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  174. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  175. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  176. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  177. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  178. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  179. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  180. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  181. package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
  182. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  183. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  184. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  185. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  186. package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
  187. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
  188. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  189. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  190. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  191. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
  192. package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
  193. package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
  194. package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
  195. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  196. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  197. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  198. package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
  199. package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
  200. package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
  201. package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
  202. package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
  203. package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
  204. package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
  205. package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
  206. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  207. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  208. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  209. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  210. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  211. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  212. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  213. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  214. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  215. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  216. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  217. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  218. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  219. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  220. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  221. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  222. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  223. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  224. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  225. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  226. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  227. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  228. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  229. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  230. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  231. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  232. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  233. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  234. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  235. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  236. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  237. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  238. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  239. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  240. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  241. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  242. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  243. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  244. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  245. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  246. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  247. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  248. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  249. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  250. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  251. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  252. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  253. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  254. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  255. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  256. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  257. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  258. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  259. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  260. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  261. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  262. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  263. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  264. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  265. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  266. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  267. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  268. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  269. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  270. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  271. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  272. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  273. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  274. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  275. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  276. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  277. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  278. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  279. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  280. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  281. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  282. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  283. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  284. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  285. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  286. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  287. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  288. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  289. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  290. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  291. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  292. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  293. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  294. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  295. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  296. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  297. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  298. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  299. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  300. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  301. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  302. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  303. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  304. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  305. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  306. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  307. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  308. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  309. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  310. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
  311. package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
  312. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  313. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  314. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
  315. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  316. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  317. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  318. package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
  319. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  320. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  321. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
  322. package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
  323. package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
  324. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  325. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  326. 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