@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
@@ -1,495 +1,354 @@
1
1
  ---
2
2
  name: cryptokit
3
- description: "Use Apple CryptoKit for Swift cryptographic primitives. Use when hashing with SHA-2 or SHA-3, generating HMACs, encrypting with AES-GCM or ChaChaPoly, signing with P256/P384/P521/Curve25519 or ML-DSA keys, performing ECDH, HPKE, ML-KEM, or X-Wing key exchange, using Secure Enclave CryptoKit keys, or migrating CommonCrypto code to CryptoKit."
3
+ description: "CryptoKit primitives in Swift: SHA-2 and SHA-3, HMAC, AES-GCM and ChaChaPoly, P256, P384, P521, Curve25519 and ML-DSA signatures, ECDH with HKDF, HPKE, ML-KEM and X-Wing, Secure Enclave keys. Use when hashing, encrypting, signing or exchanging keys, or migrating from CommonCrypto. Not for Keychain policy (swift-security)."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
8
  # CryptoKit
9
9
 
10
- Apple CryptoKit provides a Swift-native API for cryptographic operations:
11
- hashing, message authentication, symmetric encryption, public-key signing,
12
- key agreement, HPKE, quantum-secure key encapsulation/signing, and Secure
13
- Enclave-backed keys. Most core primitives are available on iOS 13+; check
14
- availability for HPKE (iOS 17+) and SHA-3 / post-quantum APIs (iOS 26+).
15
- Prefer CryptoKit over CommonCrypto or raw Security framework APIs for new
16
- cryptographic primitive code targeting Swift 6.3+.
17
-
18
- ## Contents
19
-
20
- - [Hashing](#hashing)
21
- - [HMAC](#hmac)
22
- - [Symmetric Encryption](#symmetric-encryption)
23
- - [Public-Key Signing](#public-key-signing)
24
- - [Key Agreement](#key-agreement)
25
- - [HPKE](#hpke)
26
- - [Post-Quantum CryptoKit](#post-quantum-cryptokit)
27
- - [Secure Enclave](#secure-enclave)
28
- - [Common Mistakes](#common-mistakes)
29
- - [Review Checklist](#review-checklist)
30
- - [References](#references)
10
+ CryptoKit is Apple's Swift API for hashing, message authentication, symmetric
11
+ encryption, signatures, key agreement, HPKE, quantum-secure key encapsulation
12
+ and signatures, and keys kept in the Secure Enclave. For new code (Swift 6.3+)
13
+ reach for it before CommonCrypto or raw Security framework calls.
31
14
 
32
- ## Hashing
15
+ | Feature set | Minimum iOS |
16
+ |---|---|
17
+ | Hashing, HMAC, AES-GCM, ChaChaPoly, P-curves, Curve25519, Secure Enclave P256 | 13 |
18
+ | HPKE | 17 |
19
+ | SHA-3, ML-KEM, ML-DSA, X-Wing | 26 |
33
20
 
34
- CryptoKit provides SHA256, SHA384, and SHA512 hash functions on iOS 13+.
35
- SHA3_256, SHA3_384, and SHA3_512 are available on iOS 26+. All conform
36
- to the `HashFunction` protocol.
21
+ ## Hashing
37
22
 
38
- ### One-shot hashing
23
+ `SHA256`, `SHA384` and `SHA512` exist from iOS 13; `SHA3_256`, `SHA3_384` and
24
+ `SHA3_512` from iOS 26. All of them conform to `HashFunction`, so the API is the
25
+ same for each.
39
26
 
40
27
  ```swift
41
28
  import CryptoKit
29
+ import Foundation
42
30
 
43
- let data = Data("Hello, world!".utf8)
44
- let digest = SHA256.hash(data: data)
45
- let hex = digest.compactMap { String(format: "%02x", $0) }.joined()
46
- ```
47
-
48
- SHA384 and SHA512 work identically -- substitute the type name.
49
-
50
- ### SHA-3 availability
51
-
52
- Use SHA-3 only behind an availability check unless the deployment target is
53
- iOS 26+:
54
-
55
- ```swift
56
- if #available(iOS 26.0, *) {
57
- let digest = SHA3_256.hash(data: data)
31
+ func fingerprint(_ blob: Data) -> String {
32
+ SHA256.hash(data: blob).map { String(format: "%02x", $0) }.joined()
58
33
  }
59
- ```
60
-
61
- ### Incremental hashing
62
-
63
- For large data or streaming input, hash incrementally:
64
-
65
- ```swift
66
- var hasher = SHA256()
67
- hasher.update(data: chunk1)
68
- hasher.update(data: chunk2)
69
- let digest = hasher.finalize()
70
- ```
71
-
72
- ### Digest comparison
73
34
 
74
- Compare CryptoKit digest values directly. Do not convert digests to
75
- strings or arrays for security-sensitive equality checks.
35
+ func strongerFingerprint(_ blob: Data) -> Data {
36
+ if #available(iOS 26.0, *) {
37
+ return Data(SHA3_384.hash(data: blob))
38
+ }
39
+ return Data(SHA384.hash(data: blob))
40
+ }
76
41
 
77
- ```swift
78
- let expected = SHA256.hash(data: reference)
79
- let actual = SHA256.hash(data: received)
80
- if expected == actual {
81
- // Data integrity verified
42
+ func streamingDigest(_ chunks: [Data]) -> SHA512.Digest {
43
+ var running = SHA512()
44
+ for chunk in chunks {
45
+ running.update(data: chunk)
46
+ }
47
+ return running.finalize()
82
48
  }
83
49
  ```
84
50
 
85
- ## HMAC
51
+ - Put SHA-3 behind `if #available(iOS 26.0, *)` unless the deployment target is
52
+ already 26.
53
+ - Use the incremental `update(data:)` / `finalize()` form for large or
54
+ streamed input.
55
+ - Compare digests with `==` on the digest values. Do not turn them into strings
56
+ or arrays for a security-relevant equality check.
86
57
 
87
- HMAC provides message authentication using a symmetric key and a hash function.
58
+ ## HMAC
88
59
 
89
- ### Computing an authentication code
60
+ An HMAC proves that data came from someone holding a shared symmetric key.
90
61
 
91
62
  ```swift
92
- let key = SymmetricKey(size: .bits256)
93
- let data = Data("message".utf8)
94
-
95
- let mac = HMAC<SHA256>.authenticationCode(for: data, using: key)
96
- ```
63
+ import CryptoKit
64
+ import Foundation
97
65
 
98
- ### Verifying an authentication code
66
+ let webhookKey = SymmetricKey(size: .bits256)
99
67
 
100
- ```swift
101
- let isValid = HMAC<SHA256>.isValidAuthenticationCode(
102
- mac, authenticating: data, using: key
103
- )
104
- ```
105
-
106
- This uses constant-time comparison internally.
68
+ func tag(_ body: Data) -> HMAC<SHA256>.MAC {
69
+ HMAC<SHA256>.authenticationCode(for: body, using: webhookKey)
70
+ }
107
71
 
108
- ### Incremental HMAC
72
+ func isGenuine(_ body: Data, mac: HMAC<SHA256>.MAC) -> Bool {
73
+ HMAC<SHA256>.isValidAuthenticationCode(mac, authenticating: body, using: webhookKey)
74
+ }
109
75
 
110
- ```swift
111
- var hmac = HMAC<SHA256>(key: key)
112
- hmac.update(data: chunk1)
113
- hmac.update(data: chunk2)
114
- let mac = hmac.finalize()
76
+ func tagInPieces(_ parts: [Data]) -> HMAC<SHA256>.MAC {
77
+ var signer = HMAC<SHA256>(key: webhookKey)
78
+ parts.forEach { signer.update(data: $0) }
79
+ return signer.finalize()
80
+ }
115
81
  ```
116
82
 
117
- ## Symmetric Encryption
83
+ `isValidAuthenticationCode(_:authenticating:using:)` compares in constant time.
118
84
 
119
- CryptoKit provides two authenticated encryption ciphers: AES-GCM and
120
- ChaChaPoly. Both produce a sealed box containing the nonce, ciphertext,
121
- and authentication tag.
85
+ ## Symmetric encryption
122
86
 
123
- ### AES-GCM
87
+ Both ciphers are AEAD: the sealed box bundles a nonce, the ciphertext and an
88
+ authentication tag.
124
89
 
125
- The default choice for symmetric encryption. Hardware-accelerated on Apple
126
- silicon.
90
+ - **AES-GCM** is the default. Apple silicon accelerates it in hardware.
91
+ - **ChaChaPoly** fits devices without AES acceleration or protocols that
92
+ mandate ChaCha20-Poly1305, such as TLS cipher suites or WireGuard.
127
93
 
128
94
  ```swift
129
- let key = SymmetricKey(size: .bits256)
130
- let plaintext = Data("Secret message".utf8)
131
-
132
- // Encrypt
133
- let sealedBox = try AES.GCM.seal(plaintext, using: key)
134
- let ciphertext = sealedBox.combined! // nonce + ciphertext + tag
135
-
136
- // Decrypt
137
- let box = try AES.GCM.SealedBox(combined: ciphertext)
138
- let decrypted = try AES.GCM.open(box, using: key)
139
- ```
140
-
141
- ### ChaChaPoly
142
-
143
- Use ChaChaPoly when AES hardware acceleration is unavailable or when
144
- interoperating with protocols that require ChaCha20-Poly1305 (e.g., TLS,
145
- WireGuard).
146
-
147
- ```swift
148
- let sealedBox = try ChaChaPoly.seal(plaintext, using: key)
149
- let combined = sealedBox.combined // Always non-optional for ChaChaPoly
150
-
151
- let box = try ChaChaPoly.SealedBox(combined: combined)
152
- let decrypted = try ChaChaPoly.open(box, using: key)
153
- ```
154
-
155
- ### Authenticated data
95
+ import CryptoKit
96
+ import Foundation
156
97
 
157
- Both ciphers support additional authenticated data (AAD). The AAD is
158
- authenticated but not encrypted -- useful for metadata that must remain
159
- in the clear but be tamper-proof.
98
+ func lockNote(_ note: Data, key: SymmetricKey) throws -> Data {
99
+ let box = try AES.GCM.seal(note, using: key)
100
+ guard let packed = box.combined else { throw CryptoKitError.incorrectParameterSize }
101
+ return packed
102
+ }
160
103
 
161
- ```swift
162
- let header = Data("v1".utf8)
163
- let sealedBox = try AES.GCM.seal(
164
- plaintext, using: key, authenticating: header
165
- )
166
- let decrypted = try AES.GCM.open(
167
- sealedBox, using: key, authenticating: header
168
- )
169
- ```
104
+ func unlockNote(_ packed: Data, key: SymmetricKey) throws -> Data {
105
+ try AES.GCM.open(AES.GCM.SealedBox(combined: packed), using: key)
106
+ }
170
107
 
171
- Use `.bits256` as the default `SymmetricKey` size for AES-256-GCM or
172
- ChaChaPoly. To create a key from existing data:
108
+ func lockWithChaCha(_ note: Data, key: SymmetricKey) throws -> Data {
109
+ try ChaChaPoly.seal(note, using: key).combined
110
+ }
173
111
 
174
- ```swift
175
- let key = SymmetricKey(data: existingKeyData)
112
+ func unlockWithChaCha(_ packed: Data, key: SymmetricKey) throws -> Data {
113
+ try ChaChaPoly.open(ChaChaPoly.SealedBox(combined: packed), using: key)
114
+ }
176
115
  ```
177
116
 
178
- ## Public-Key Signing
117
+ `combined` is optional on `AES.GCM.SealedBox` (it is `nil` when a non-standard
118
+ nonce size was used) and non-optional on `ChaChaPoly.SealedBox`.
179
119
 
180
- CryptoKit supports ECDSA signing with NIST curves and Ed25519 via
181
- Curve25519.
120
+ ### Additional authenticated data
182
121
 
183
- ### NIST curves: P256, P384, P521
122
+ Metadata that must travel in the clear but must not be altered goes in the AAD.
123
+ It is authenticated, not encrypted.
184
124
 
185
125
  ```swift
186
- let signingKey = P256.Signing.PrivateKey()
187
- let publicKey = signingKey.publicKey
126
+ import CryptoKit
127
+ import Foundation
188
128
 
189
- // Sign
190
- let signature = try signingKey.signature(for: data)
129
+ func sealRecord(_ payload: Data, recordID: String, key: SymmetricKey) throws -> AES.GCM.SealedBox {
130
+ try AES.GCM.seal(payload, using: key, authenticating: Data(recordID.utf8))
131
+ }
191
132
 
192
- // Verify
193
- let isValid = publicKey.isValidSignature(signature, for: data)
133
+ func openRecord(_ box: AES.GCM.SealedBox, recordID: String, key: SymmetricKey) throws -> Data {
134
+ try AES.GCM.open(box, using: key, authenticating: Data(recordID.utf8))
135
+ }
194
136
  ```
195
137
 
196
- P384 and P521 use the same API -- substitute the curve name.
138
+ ### Keys
139
+
140
+ `SymmetricKey(size: .bits256)` gives AES-256-GCM or ChaChaPoly strength and is
141
+ the right default. Wrap existing key bytes with `SymmetricKey(data:)`.
197
142
 
198
- NIST keys support DER, PEM, X9.63, and raw representations. See
199
- [references/cryptokit-patterns.md](references/cryptokit-patterns.md) for
200
- serialization examples.
143
+ ## Signatures
201
144
 
202
- ### Curve25519 / Ed25519
145
+ ECDSA uses the NIST curves; Ed25519 comes from `Curve25519`.
203
146
 
204
147
  ```swift
205
- let signingKey = Curve25519.Signing.PrivateKey()
206
- let publicKey = signingKey.publicKey
148
+ import CryptoKit
149
+ import Foundation
207
150
 
208
- // Sign
209
- let signature = try signingKey.signature(for: data)
151
+ func signRelease(_ manifest: Data) throws -> (P256.Signing.PublicKey, P256.Signing.ECDSASignature) {
152
+ let signer = P256.Signing.PrivateKey()
153
+ return (signer.publicKey, try signer.signature(for: manifest))
154
+ }
155
+
156
+ func verifyRelease(_ manifest: Data, key: P256.Signing.PublicKey, sig: P256.Signing.ECDSASignature) -> Bool {
157
+ key.isValidSignature(sig, for: manifest)
158
+ }
210
159
 
211
- // Verify
212
- let isValid = publicKey.isValidSignature(signature, for: data)
160
+ func edSign(_ message: Data) throws -> (Curve25519.Signing.PublicKey, Data) {
161
+ let signer = Curve25519.Signing.PrivateKey()
162
+ return (signer.publicKey, try signer.signature(for: message))
163
+ }
213
164
  ```
214
165
 
215
- Curve25519 keys use `rawRepresentation` only (no DER/PEM/X9.63).
166
+ P384 and P521 have the same shape as P256. NIST keys serialize as DER, PEM,
167
+ X9.63 or raw. Curve25519 keys offer only `rawRepresentation`.
216
168
 
217
169
  ### Choosing a curve
218
170
 
219
- | Curve | Signature Scheme | Key Size | Typical Use |
171
+ | Curve | Algorithm | Size | Notes |
220
172
  |---|---|---|---|
221
- | P256 | ECDSA | 256-bit | General purpose; Secure Enclave support |
222
- | P384 | ECDSA | 384-bit | Higher security requirements |
223
- | P521 | ECDSA | 521-bit | Maximum NIST security level |
224
- | Curve25519 | Ed25519 | 256-bit | Fast; simple API; no Secure Enclave |
173
+ | P256 | ECDSA | 256-bit | general default; Secure Enclave capable |
174
+ | P384 | ECDSA | 384-bit | higher margin |
175
+ | P521 | ECDSA | 521-bit | top NIST level |
176
+ | Curve25519 | Ed25519 | 256-bit | fast and simple; no Secure Enclave |
225
177
 
226
- Use P256 by default. Use Curve25519 when interoperating with Ed25519-based
227
- protocols.
178
+ Start with P256. Use Curve25519 when a protocol specifies Ed25519.
228
179
 
229
- ## Key Agreement
180
+ ## Key agreement
230
181
 
231
- Key agreement lets two parties derive a shared symmetric key from their
232
- public/private key pairs using ECDH.
233
-
234
- ### ECDH with P256
182
+ ECDH turns two key pairs into one shared secret. Each side combines its own
183
+ private key with the other side's public key, and both arrive at the same value.
235
184
 
236
185
  ```swift
237
- // Alice
238
- let aliceKey = P256.KeyAgreement.PrivateKey()
239
-
240
- // Bob
241
- let bobKey = P256.KeyAgreement.PrivateKey()
242
-
243
- // Alice computes shared secret
244
- let sharedSecret = try aliceKey.sharedSecretFromKeyAgreement(
245
- with: bobKey.publicKey
246
- )
247
-
248
- // Derive a symmetric key using HKDF
249
- let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
250
- using: SHA256.self,
251
- salt: Data("salt".utf8),
252
- sharedInfo: Data("my-app-v1".utf8),
253
- outputByteCount: 32
254
- )
255
- ```
256
-
257
- Bob computes the same `sharedSecret` using his private key and Alice's
258
- public key. Both derive the same `symmetricKey`.
259
-
260
- ### ECDH with Curve25519
186
+ import CryptoKit
187
+ import Foundation
188
+
189
+ func sessionKey(mine: P256.KeyAgreement.PrivateKey, theirs: P256.KeyAgreement.PublicKey) throws -> SymmetricKey {
190
+ let secret = try mine.sharedSecretFromKeyAgreement(with: theirs)
191
+ return secret.hkdfDerivedSymmetricKey(
192
+ using: SHA256.self,
193
+ salt: Data("chat-v2-salt".utf8),
194
+ sharedInfo: Data("chat-v2 message key".utf8),
195
+ outputByteCount: 32
196
+ )
197
+ }
261
198
 
262
- ```swift
263
- let aliceKey = Curve25519.KeyAgreement.PrivateKey()
264
- let bobKey = Curve25519.KeyAgreement.PrivateKey()
265
-
266
- let sharedSecret = try aliceKey.sharedSecretFromKeyAgreement(
267
- with: bobKey.publicKey
268
- )
269
-
270
- let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
271
- using: SHA256.self,
272
- salt: Data(),
273
- sharedInfo: Data("context".utf8),
274
- outputByteCount: 32
275
- )
199
+ func x25519Key(mine: Curve25519.KeyAgreement.PrivateKey, theirs: Curve25519.KeyAgreement.PublicKey) throws -> SymmetricKey {
200
+ try mine.sharedSecretFromKeyAgreement(with: theirs).hkdfDerivedSymmetricKey(
201
+ using: SHA256.self,
202
+ salt: Data(),
203
+ sharedInfo: Data("sync-pairing v1".utf8),
204
+ outputByteCount: 32
205
+ )
206
+ }
276
207
  ```
277
208
 
278
- ### Key derivation functions
209
+ ### Derivation
279
210
 
280
- `SharedSecret` is not directly usable as a `SymmetricKey`. Always derive
281
- a key using one of:
211
+ A `SharedSecret` is not a `SymmetricKey` and must always go through a KDF.
282
212
 
283
- | Method | Standard | Use |
213
+ | Method | Standard | When |
284
214
  |---|---|---|
285
- | `hkdfDerivedSymmetricKey` | HKDF (RFC 5869) | Recommended default |
286
- | `x963DerivedSymmetricKey` | ANSI X9.63 | Interop with X9.63 systems |
215
+ | `hkdfDerivedSymmetricKey` | HKDF, RFC 5869 | default choice |
216
+ | `x963DerivedSymmetricKey` | ANSI X9.63 | interoperating with X9.63 systems |
287
217
 
288
- Always provide a non-empty `sharedInfo` string to bind the derived key
289
- to a specific protocol context.
218
+ Always pass a non-empty `sharedInfo` that names the protocol and purpose, so
219
+ the derived key cannot be reused somewhere else.
290
220
 
291
221
  ## HPKE
292
222
 
293
- HPKE is available on iOS 17+ for public-key encryption workflows. Prefer it over
294
- hand-rolled ECDH + HKDF + AEAD protocols when encrypting to a recipient public key.
223
+ HPKE (iOS 17+) is the ready-made way to encrypt to someone's public key.
224
+ Prefer it over wiring ECDH, HKDF and an AEAD together by hand.
295
225
 
296
226
  ```swift
297
- let info = Data("my-protocol-v1".utf8)
298
- let recipientKey = Curve25519.KeyAgreement.PrivateKey()
299
- var sender = try HPKE.Sender(
300
- recipientKey: recipientKey.publicKey,
301
- ciphersuite: .Curve25519_SHA256_ChachaPoly,
302
- info: info
303
- )
304
- let encapsulatedKey = sender.encapsulatedKey
305
- let ciphertext = try sender.seal(
306
- plaintext,
307
- authenticating: Data("metadata".utf8)
308
- )
309
-
310
- var recipient = try HPKE.Recipient(
311
- privateKey: recipientKey,
312
- ciphersuite: .Curve25519_SHA256_ChachaPoly,
313
- info: info,
314
- encapsulatedKey: encapsulatedKey
315
- )
316
- ```
317
-
318
- `HPKE.Sender` and `HPKE.Recipient` are stateful; keep them as `var`, send
319
- `encapsulatedKey` alongside the ciphertext, and open messages in the same
320
- order they were sealed. See [references/cryptokit-patterns.md](references/cryptokit-patterns.md)
321
- for ciphersuite selection and post-quantum HPKE.
322
-
323
- ## Post-Quantum CryptoKit
324
-
325
- iOS 26+ adds quantum-secure APIs:
326
-
327
- - Key encapsulation: `MLKEM768`, `MLKEM1024`
328
- - Hybrid HPKE: `XWingMLKEM768X25519` with `.XWingMLKEM768X25519_SHA256_AES_GCM_256`
329
- - Digital signatures: `MLDSA65`, `MLDSA87`
330
- - Secure Enclave variants: `SecureEnclave.MLKEM768`, `SecureEnclave.MLKEM1024`,
331
- `SecureEnclave.MLDSA65`, `SecureEnclave.MLDSA87`
332
-
333
- Use hybrid mechanisms for migration when both classical and quantum-secure
334
- resistance matter. Account for much larger public keys, ciphertexts, and
335
- signatures than P256 or Curve25519.
336
-
337
- ## Secure Enclave
338
-
339
- The Secure Enclave provides hardware-backed key storage. Private keys
340
- never leave the hardware. For classical elliptic-curve CryptoKit, Secure
341
- Enclave supports P256 signing and key agreement. On iOS 26+ supported
342
- hardware, CryptoKit also exposes Secure Enclave ML-KEM key encapsulation
343
- and ML-DSA signing types.
344
-
345
- ### Availability check
227
+ import CryptoKit
228
+ import Foundation
346
229
 
347
- ```swift
348
- guard SecureEnclave.isAvailable else {
349
- // Fall back to software keys
350
- return
230
+ func encryptForDevice(_ messages: [Data], to device: Curve25519.KeyAgreement.PublicKey) throws -> (Data, [Data]) {
231
+ let context = Data("device-backup v3".utf8)
232
+ var sender = try HPKE.Sender(recipientKey: device, ciphersuite: .Curve25519_SHA256_ChachaPoly, info: context)
233
+ let sealed = try messages.map { try sender.seal($0, authenticating: Data("header".utf8)) }
234
+ return (sender.encapsulatedKey, sealed)
351
235
  }
352
- ```
353
-
354
- ### Creating a Secure Enclave signing key
355
-
356
- ```swift
357
- let privateKey = try SecureEnclave.P256.Signing.PrivateKey()
358
- let publicKey = privateKey.publicKey // Standard P256.Signing.PublicKey
359
-
360
- let signature = try privateKey.signature(for: data)
361
- let isValid = publicKey.isValidSignature(signature, for: data)
362
- ```
363
-
364
- ### Access control
365
-
366
- Use `SecAccessControl` with `.privateKeyUsage` when the key requires biometric
367
- or passcode-gated use. Keep detailed Keychain policy decisions in the
368
- `swift-security` domain.
369
-
370
- ### Persisting Secure Enclave keys
371
-
372
- The `dataRepresentation` is an encrypted blob that only the same device's
373
- Secure Enclave can restore. Store it in the Keychain.
374
-
375
- ```swift
376
- // Export
377
- let blob = privateKey.dataRepresentation
378
236
 
379
- // Restore
380
- let restored = try SecureEnclave.P256.Signing.PrivateKey(
381
- dataRepresentation: blob
382
- )
383
- ```
384
-
385
- ### Secure Enclave key agreement
386
-
387
- ```swift
388
- let seKey = try SecureEnclave.P256.KeyAgreement.PrivateKey()
389
- let peerPublicKey: P256.KeyAgreement.PublicKey = // from peer
390
-
391
- let sharedSecret = try seKey.sharedSecretFromKeyAgreement(
392
- with: peerPublicKey
393
- )
394
- ```
395
-
396
- ## Common Mistakes
397
-
398
- ### 1. Using the shared secret directly as a key
399
-
400
- ```swift
401
- // DON'T
402
- let badKey = sharedSecret.withUnsafeBytes { bytes in
403
- SymmetricKey(data: Data(bytes))
237
+ func decryptOnDevice(_ sealed: [Data], encapsulated: Data, key: Curve25519.KeyAgreement.PrivateKey) throws -> [Data] {
238
+ let context = Data("device-backup v3".utf8)
239
+ var receiver = try HPKE.Recipient(privateKey: key, ciphersuite: .Curve25519_SHA256_ChachaPoly,
240
+ info: context, encapsulatedKey: encapsulated)
241
+ return try sealed.map { try receiver.open($0, authenticating: Data("header".utf8)) }
404
242
  }
405
-
406
- // DO -- derive with HKDF
407
- let goodKey = sharedSecret.hkdfDerivedSymmetricKey(
408
- using: SHA256.self,
409
- salt: salt,
410
- sharedInfo: info,
411
- outputByteCount: 32
412
- )
413
243
  ```
414
244
 
415
- ### 2. Reusing nonces
245
+ - `HPKE.Sender` and `HPKE.Recipient` keep a sequence counter, so they must be
246
+ `var`.
247
+ - Ship `encapsulatedKey` together with the ciphertext.
248
+ - The recipient must open messages in the same order the sender sealed them.
416
249
 
417
- ```swift
418
- // DON'T -- hardcoded nonce
419
- let nonce = try AES.GCM.Nonce(data: Data(repeating: 0, count: 12))
420
- let box = try AES.GCM.seal(data, using: key, nonce: nonce)
250
+ ## Post-quantum CryptoKit (iOS 26+)
421
251
 
422
- // DO -- let CryptoKit generate a random nonce (default behavior)
423
- let box = try AES.GCM.seal(data, using: key)
424
- ```
252
+ | Purpose | Types |
253
+ |---|---|
254
+ | Key encapsulation | `MLKEM768`, `MLKEM1024` |
255
+ | Hybrid HPKE | `XWingMLKEM768X25519` with `.XWingMLKEM768X25519_SHA256_AES_GCM_256` |
256
+ | Signatures | `MLDSA65`, `MLDSA87` |
257
+ | Secure Enclave | `SecureEnclave.MLKEM768`, `SecureEnclave.MLKEM1024`, `SecureEnclave.MLDSA65`, `SecureEnclave.MLDSA87` |
425
258
 
426
- ### 3. Ignoring authentication tag verification
259
+ - During a migration where both classical and quantum resistance matter, use
260
+ the hybrid X-Wing suite.
261
+ - Keys, ciphertexts and signatures are far larger than their P256 or
262
+ Curve25519 counterparts. Budget for that in storage and on the wire.
427
263
 
428
- ```swift
429
- // DON'T -- manually strip tag and decrypt
430
- // DO -- always use AES.GCM.open() or ChaChaPoly.open()
431
- // which verifies the tag automatically
432
- ```
433
-
434
- ### 4. Using Insecure hashes for security
435
-
436
- ```swift
437
- // DON'T -- MD5/SHA1 for integrity or security
438
- import CryptoKit
439
- let bad = Insecure.MD5.hash(data: data)
440
-
441
- // DO -- use SHA256 or stronger
442
- let good = SHA256.hash(data: data)
443
- ```
264
+ ## Secure Enclave
444
265
 
445
- `Insecure.MD5` and `Insecure.SHA1` exist only for legacy compatibility
446
- (checksum verification, protocol interop). Never use them for new
447
- security-sensitive operations.
266
+ The Secure Enclave generates and holds private keys in hardware; they never
267
+ leave it.
448
268
 
449
- ### 5. Storing symmetric keys in UserDefaults
269
+ - Classical support covers P256 signing and P256 key agreement only.
270
+ - On iOS 26 with supported hardware, ML-KEM and ML-DSA keys can live there too.
271
+ - Always check `SecureEnclave.isAvailable` and fall back to software keys.
450
272
 
451
273
  ```swift
452
- // DON'T
453
- UserDefaults.standard.set(rawKeyData, forKey: "encryptionKey")
274
+ import CryptoKit
275
+ import Foundation
276
+ import Security
454
277
 
455
- // DO -- store in Keychain
456
- // See references/cryptokit-patterns.md for Keychain storage patterns
457
- ```
278
+ enum DeviceKeyError: Error {
279
+ case noSecureEnclave
280
+ case accessControlRejected
281
+ }
458
282
 
459
- ### 6. Not checking Secure Enclave availability
283
+ func deviceSigningKey() throws -> Data {
284
+ guard SecureEnclave.isAvailable else { throw DeviceKeyError.noSecureEnclave }
285
+ guard let rule = SecAccessControlCreateWithFlags(nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
286
+ [.privateKeyUsage, .biometryCurrentSet], nil) else {
287
+ throw DeviceKeyError.accessControlRejected
288
+ }
289
+ let key = try SecureEnclave.P256.Signing.PrivateKey(accessControl: rule)
290
+ _ = key.publicKey
291
+ return key.dataRepresentation
292
+ }
460
293
 
461
- ```swift
462
- // DON'T -- crash on simulator or unsupported hardware
463
- let key = try SecureEnclave.P256.Signing.PrivateKey()
294
+ func restoreDeviceKey(_ blob: Data) throws -> SecureEnclave.P256.Signing.PrivateKey {
295
+ try SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: blob)
296
+ }
464
297
 
465
- // DO
466
- guard SecureEnclave.isAvailable else { /* fallback */ }
467
- let key = try SecureEnclave.P256.Signing.PrivateKey()
298
+ func enclaveAgreement(with peer: P256.KeyAgreement.PublicKey) throws -> SharedSecret {
299
+ let mine = try SecureEnclave.P256.KeyAgreement.PrivateKey()
300
+ return try mine.sharedSecretFromKeyAgreement(with: peer)
301
+ }
468
302
  ```
469
303
 
470
- ## Review Checklist
471
-
472
- - [ ] Using CryptoKit, not CommonCrypto or raw Security framework
473
- - [ ] SHA256+ for hashing; no MD5/SHA1 for security purposes
474
- - [ ] HMAC verification uses `isValidAuthenticationCode` (constant-time)
475
- - [ ] AES-GCM or ChaChaPoly for symmetric encryption; 256-bit keys
476
- - [ ] Nonces are random (default) -- not hardcoded or reused
477
- - [ ] Authenticated data (AAD) used where metadata needs integrity
478
- - [ ] SharedSecret derived via HKDF, not used directly
479
- - [ ] sharedInfo parameter is non-empty and context-specific
480
- - [ ] HPKE used instead of custom ECDH+HKDF+AEAD for recipient public-key encryption on iOS 17+
481
- - [ ] SHA-3 and post-quantum APIs guarded with iOS 26+ availability
482
- - [ ] Secure Enclave availability checked before use
483
- - [ ] Secure Enclave key `dataRepresentation` stored in Keychain
484
- - [ ] Private keys not logged, printed, or serialized unnecessarily
485
- - [ ] Symmetric keys stored in Keychain, not UserDefaults or files
486
- - [ ] Encryption export compliance considered (`ITSAppUsesNonExemptEncryption`)
304
+ - The public key of a Secure Enclave signing key is an ordinary
305
+ `P256.Signing.PublicKey`; signing and verifying look the same as in software.
306
+ - Gate use behind biometrics or the passcode with a `SecAccessControl` that
307
+ includes `.privateKeyUsage`. Deeper Keychain policy choices belong to
308
+ `swift-security`.
309
+ - `dataRepresentation` is an encrypted blob that only the same device's Secure
310
+ Enclave can turn back into a key. Store it in the Keychain and restore it
311
+ with `init(dataRepresentation:)`.
312
+
313
+ ## Common mistakes
314
+
315
+ - **Using the raw shared secret as a key.** Always derive with HKDF.
316
+ - **Fixed or repeated nonces.** Passing something like
317
+ `AES.GCM.Nonce(data: Data(count: 12))` to `seal(_:using:nonce:)` for every
318
+ message breaks GCM. Let CryptoKit pick a random nonce by leaving the argument
319
+ out.
320
+ - **Decrypting without the tag check.** Never peel the tag off and decrypt by
321
+ hand. `AES.GCM.open` and `ChaChaPoly.open` verify it for you.
322
+ - **Insecure hashes for security.** `Insecure.MD5` and `Insecure.SHA1` exist
323
+ for legacy checksums and protocol interop only.
324
+ - **Key bytes in `UserDefaults`.** Keys go in the Keychain; see
325
+ [the Keychain patterns](references/cryptokit-patterns.md#keychain-storage).
326
+ - **Secure Enclave without an availability check.** Key creation fails in
327
+ Simulator and on unsupported hardware.
328
+
329
+ ## Review checklist
330
+
331
+ - [ ] CryptoKit is used instead of CommonCrypto or raw Security calls
332
+ - [ ] Hashing uses SHA-256 or stronger; no MD5 or SHA-1 for security
333
+ - [ ] HMACs are verified with `isValidAuthenticationCode`
334
+ - [ ] Encryption is AES-GCM or ChaChaPoly with 256-bit keys
335
+ - [ ] Nonces are random, never hardcoded or reused
336
+ - [ ] AAD protects metadata that needs integrity
337
+ - [ ] Every `SharedSecret` goes through HKDF
338
+ - [ ] `sharedInfo` is non-empty and specific to the context
339
+ - [ ] HPKE replaces hand-built ECDH + HKDF + AEAD for recipient encryption on iOS 17+
340
+ - [ ] SHA-3 and post-quantum code is behind an iOS 26 availability check
341
+ - [ ] `SecureEnclave.isAvailable` is checked
342
+ - [ ] Secure Enclave `dataRepresentation` is stored in the Keychain
343
+ - [ ] Private keys are never logged, printed or serialized without need
344
+ - [ ] Symmetric keys live in the Keychain, not `UserDefaults` or loose files
345
+ - [ ] Export compliance (`ITSAppUsesNonExemptEncryption`) has been considered
487
346
 
488
347
  ## References
489
348
 
490
- - Extended patterns (key serialization, Insecure module, Keychain integration, AES key wrapping, HPKE): [references/cryptokit-patterns.md](references/cryptokit-patterns.md)
491
- - Apple documentation: [CryptoKit](https://sosumi.ai/documentation/cryptokit)
492
- - Apple documentation: [HPKE](https://sosumi.ai/documentation/cryptokit/hpke)
493
- - Apple documentation: [Quantum-secure workflows](https://sosumi.ai/documentation/cryptokit/enhancing-your-app-s-privacy-and-security-with-quantum-secure-workflows)
494
- - Apple sample: [Performing Common Cryptographic Operations](https://sosumi.ai/documentation/cryptokit/performing-common-cryptographic-operations)
495
- - Apple sample: [Storing CryptoKit Keys in the Keychain](https://sosumi.ai/documentation/cryptokit/storing-cryptokit-keys-in-the-keychain)
349
+ - [CryptoKit patterns](references/cryptokit-patterns.md) - key serialization, Keychain storage, AES key wrap, HKDF, HPKE ciphersuites, post-quantum usage, the Insecure namespace, sealed box layout, digest signing, export compliance, performance, CommonCrypto migration
350
+ - [CryptoKit](https://developer.apple.com/documentation/cryptokit)
351
+ - [HPKE](https://developer.apple.com/documentation/cryptokit/hpke)
352
+ - [Enhancing your app's privacy and security with quantum-secure workflows](https://developer.apple.com/documentation/cryptokit/enhancing-your-app-s-privacy-and-security-with-quantum-secure-workflows)
353
+ - [Performing common cryptographic operations](https://developer.apple.com/documentation/cryptokit/performing-common-cryptographic-operations)
354
+ - [Storing CryptoKit keys in the keychain](https://developer.apple.com/documentation/cryptokit/storing-cryptokit-keys-in-the-keychain)