buildanything 1.7.1 → 2.0.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 (633) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +9 -3
  3. package/CHANGELOG.md +112 -0
  4. package/README.md +2 -2
  5. package/agents/a11y-architect.md +166 -0
  6. package/agents/business-model.md +80 -29
  7. package/agents/code-architect.md +75 -0
  8. package/agents/code-reviewer.md +255 -0
  9. package/agents/code-simplifier.md +64 -0
  10. package/agents/design-brand-guardian.md +293 -53
  11. package/agents/design-critic.md +139 -0
  12. package/agents/design-inclusive-visuals-specialist.md +6 -19
  13. package/agents/design-ui-designer.md +335 -56
  14. package/agents/design-ux-architect.md +403 -55
  15. package/agents/design-ux-researcher.md +264 -49
  16. package/agents/engineering-ai-engineer.md +26 -36
  17. package/agents/engineering-backend-architect.md +185 -36
  18. package/agents/engineering-data-engineer.md +225 -43
  19. package/agents/engineering-devops-automator.md +227 -74
  20. package/agents/engineering-frontend-developer.md +210 -34
  21. package/agents/engineering-mobile-app-builder.md +6 -1
  22. package/agents/engineering-rapid-prototyper.md +30 -9
  23. package/agents/engineering-security-engineer.md +263 -61
  24. package/agents/engineering-senior-developer.md +128 -19
  25. package/agents/engineering-sre.md +84 -0
  26. package/agents/engineering-technical-writer.md +285 -41
  27. package/agents/feature-intel.md +110 -0
  28. package/agents/ios-app-review-guardian.md +66 -0
  29. package/agents/ios-foundation-models-specialist.md +64 -0
  30. package/agents/ios-storekit-specialist.md +59 -0
  31. package/agents/ios-swift-architect.md +129 -0
  32. package/agents/ios-swift-search.md +137 -0
  33. package/agents/ios-swift-ui-design.md +136 -0
  34. package/agents/marketing-app-store-optimizer.md +246 -64
  35. package/agents/planner.md +216 -0
  36. package/agents/pr-test-analyzer.md +63 -0
  37. package/agents/product-feedback-synthesizer.md +8 -2
  38. package/agents/refactor-cleaner.md +102 -0
  39. package/agents/security-reviewer.md +128 -0
  40. package/agents/silent-failure-hunter.md +54 -0
  41. package/agents/swift-build-resolver.md +119 -0
  42. package/agents/swift-reviewer.md +112 -0
  43. package/agents/tech-feasibility.md +21 -1
  44. package/agents/testing-api-tester.md +236 -59
  45. package/agents/testing-evidence-collector.md +26 -1
  46. package/agents/testing-performance-benchmarker.md +21 -1
  47. package/agents/testing-reality-checker.md +6 -1
  48. package/agents/visual-research.md +116 -0
  49. package/bin/adapters/cycle-counter-tool.ts +155 -0
  50. package/bin/adapters/scribe-tool.ts +71 -0
  51. package/bin/adapters/state-save-tool.ts +130 -0
  52. package/bin/adapters/write-lease-tool.ts +127 -0
  53. package/bin/buildanything-runtime.js +15 -0
  54. package/bin/buildanything-runtime.ts +328 -0
  55. package/bin/setup.js +83 -8
  56. package/commands/add-feature.md +2 -0
  57. package/commands/build.md +752 -332
  58. package/commands/fix.md +65 -0
  59. package/commands/self-check.md +121 -0
  60. package/commands/setup.md +114 -0
  61. package/commands/ux-review.md +63 -0
  62. package/commands/verify.md +69 -0
  63. package/docs/migration/agents.yaml +729 -0
  64. package/docs/migration/phase-graph.yaml +1088 -0
  65. package/docs/migration/sdk-host-compat.md +18 -0
  66. package/hooks/compile-writer-owner-cache.ts +171 -0
  67. package/hooks/hooks.json +36 -0
  68. package/hooks/pre-tool-use +19 -0
  69. package/hooks/pre-tool-use.ts +776 -0
  70. package/hooks/record-mode-transitions.ts +178 -0
  71. package/hooks/session-start +89 -2
  72. package/hooks/subagent-start +17 -0
  73. package/hooks/subagent-start.ts +471 -0
  74. package/hooks/subagent-stop +17 -0
  75. package/hooks/subagent-stop.ts +153 -0
  76. package/package.json +28 -5
  77. package/protocols/architecture-schema.md +171 -0
  78. package/protocols/build-fix.md +52 -0
  79. package/protocols/cleanup.md +54 -0
  80. package/protocols/decision-log.md +131 -0
  81. package/protocols/eval-harness.md +61 -0
  82. package/protocols/fake-data-detector.md +64 -0
  83. package/protocols/ios-context.md +234 -0
  84. package/protocols/ios-frameworks-map.md +323 -0
  85. package/protocols/ios-phase-branches.md +337 -0
  86. package/protocols/ios-preflight.md +27 -0
  87. package/protocols/launch-readiness.md +258 -0
  88. package/protocols/metric-loop.md +153 -0
  89. package/protocols/smoke-test.md +118 -0
  90. package/protocols/state-schema.json +388 -0
  91. package/protocols/state-schema.md +172 -0
  92. package/protocols/verify.md +127 -0
  93. package/protocols/visual-dna.md +185 -0
  94. package/protocols/web-phase-branches.md +351 -0
  95. package/skills/ios/_VENDORED.md +62 -0
  96. package/skills/ios/activitykit/LICENSE +131 -0
  97. package/skills/ios/activitykit/SKILL.md +505 -0
  98. package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
  99. package/skills/ios/app-intents/LICENSE +131 -0
  100. package/skills/ios/app-intents/SKILL.md +494 -0
  101. package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
  102. package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
  103. package/skills/ios/apple-on-device-ai/LICENSE +131 -0
  104. package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
  105. package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
  106. package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
  107. package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
  108. package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
  109. package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
  110. package/skills/ios/hig-components-content/SKILL.md +86 -0
  111. package/skills/ios/hig-components-content/references/activity-views.md +79 -0
  112. package/skills/ios/hig-components-content/references/charts.md +180 -0
  113. package/skills/ios/hig-components-content/references/collections.md +48 -0
  114. package/skills/ios/hig-components-content/references/color-wells.md +42 -0
  115. package/skills/ios/hig-components-content/references/image-views.md +82 -0
  116. package/skills/ios/hig-components-content/references/image-wells.md +34 -0
  117. package/skills/ios/hig-components-content/references/lockups.md +78 -0
  118. package/skills/ios/hig-components-content/references/web-views.md +36 -0
  119. package/skills/ios/hig-components-controls/SKILL.md +88 -0
  120. package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
  121. package/skills/ios/hig-components-controls/references/controls.md +112 -0
  122. package/skills/ios/hig-components-controls/references/gauges.md +74 -0
  123. package/skills/ios/hig-components-controls/references/labels.md +92 -0
  124. package/skills/ios/hig-components-controls/references/pickers.md +128 -0
  125. package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
  126. package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
  127. package/skills/ios/hig-components-controls/references/sliders.md +92 -0
  128. package/skills/ios/hig-components-controls/references/steppers.md +40 -0
  129. package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
  130. package/skills/ios/hig-components-controls/references/text-views.md +56 -0
  131. package/skills/ios/hig-components-controls/references/toggles.md +127 -0
  132. package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
  133. package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
  134. package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
  135. package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
  136. package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
  137. package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
  138. package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
  139. package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
  140. package/skills/ios/hig-components-layout/SKILL.md +99 -0
  141. package/skills/ios/hig-components-layout/references/boxes.md +48 -0
  142. package/skills/ios/hig-components-layout/references/column-views.md +44 -0
  143. package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
  144. package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
  145. package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
  146. package/skills/ios/hig-components-layout/references/panels.md +75 -0
  147. package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
  148. package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
  149. package/skills/ios/hig-components-layout/references/split-views.md +110 -0
  150. package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
  151. package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
  152. package/skills/ios/hig-components-layout/references/windows.md +188 -0
  153. package/skills/ios/hig-components-menus/SKILL.md +81 -0
  154. package/skills/ios/hig-components-menus/references/action-button.md +61 -0
  155. package/skills/ios/hig-components-menus/references/buttons.md +261 -0
  156. package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
  157. package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
  158. package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
  159. package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
  160. package/skills/ios/hig-components-menus/references/menus.md +171 -0
  161. package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
  162. package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
  163. package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
  164. package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
  165. package/skills/ios/hig-components-search/SKILL.md +68 -0
  166. package/skills/ios/hig-components-search/references/page-controls.md +120 -0
  167. package/skills/ios/hig-components-search/references/path-controls.md +40 -0
  168. package/skills/ios/hig-components-search/references/search-fields.md +189 -0
  169. package/skills/ios/hig-components-status/SKILL.md +80 -0
  170. package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
  171. package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
  172. package/skills/ios/hig-components-status/references/status-bars.md +38 -0
  173. package/skills/ios/hig-components-system/SKILL.md +88 -0
  174. package/skills/ios/hig-components-system/references/app-clips.md +387 -0
  175. package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
  176. package/skills/ios/hig-components-system/references/complications.md +425 -0
  177. package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
  178. package/skills/ios/hig-components-system/references/live-activities.md +442 -0
  179. package/skills/ios/hig-components-system/references/notifications.md +153 -0
  180. package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
  181. package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
  182. package/skills/ios/hig-components-system/references/widgets.md +517 -0
  183. package/skills/ios/hig-foundations/SKILL.md +98 -0
  184. package/skills/ios/hig-foundations/references/accessibility.md +291 -0
  185. package/skills/ios/hig-foundations/references/app-icons.md +210 -0
  186. package/skills/ios/hig-foundations/references/branding.md +44 -0
  187. package/skills/ios/hig-foundations/references/color.md +274 -0
  188. package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
  189. package/skills/ios/hig-foundations/references/icons.md +263 -0
  190. package/skills/ios/hig-foundations/references/images.md +176 -0
  191. package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
  192. package/skills/ios/hig-foundations/references/inclusion.md +189 -0
  193. package/skills/ios/hig-foundations/references/layout.md +425 -0
  194. package/skills/ios/hig-foundations/references/materials.md +238 -0
  195. package/skills/ios/hig-foundations/references/motion.md +103 -0
  196. package/skills/ios/hig-foundations/references/privacy.md +231 -0
  197. package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
  198. package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
  199. package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
  200. package/skills/ios/hig-foundations/references/typography.md +1146 -0
  201. package/skills/ios/hig-foundations/references/writing.md +91 -0
  202. package/skills/ios/hig-inputs/SKILL.md +94 -0
  203. package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
  204. package/skills/ios/hig-inputs/references/camera-control.md +107 -0
  205. package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
  206. package/skills/ios/hig-inputs/references/eyes.md +120 -0
  207. package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
  208. package/skills/ios/hig-inputs/references/game-controls.md +156 -0
  209. package/skills/ios/hig-inputs/references/gestures.md +208 -0
  210. package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
  211. package/skills/ios/hig-inputs/references/keyboards.md +234 -0
  212. package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
  213. package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
  214. package/skills/ios/hig-inputs/references/remotes.md +67 -0
  215. package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
  216. package/skills/ios/hig-patterns/SKILL.md +104 -0
  217. package/skills/ios/hig-patterns/references/charting-data.md +81 -0
  218. package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
  219. package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
  220. package/skills/ios/hig-patterns/references/entering-data.md +69 -0
  221. package/skills/ios/hig-patterns/references/feedback.md +67 -0
  222. package/skills/ios/hig-patterns/references/file-management.md +135 -0
  223. package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
  224. package/skills/ios/hig-patterns/references/launching.md +81 -0
  225. package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
  226. package/skills/ios/hig-patterns/references/loading.md +59 -0
  227. package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
  228. package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
  229. package/skills/ios/hig-patterns/references/modality.md +82 -0
  230. package/skills/ios/hig-patterns/references/multitasking.md +131 -0
  231. package/skills/ios/hig-patterns/references/offering-help.md +117 -0
  232. package/skills/ios/hig-patterns/references/onboarding.md +69 -0
  233. package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
  234. package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
  235. package/skills/ios/hig-patterns/references/playing-video.md +180 -0
  236. package/skills/ios/hig-patterns/references/printing.md +50 -0
  237. package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
  238. package/skills/ios/hig-patterns/references/searching.md +70 -0
  239. package/skills/ios/hig-patterns/references/settings.md +84 -0
  240. package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
  241. package/skills/ios/hig-patterns/references/workouts.md +76 -0
  242. package/skills/ios/hig-platforms/SKILL.md +84 -0
  243. package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
  244. package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
  245. package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
  246. package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
  247. package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
  248. package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
  249. package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
  250. package/skills/ios/hig-project-context/SKILL.md +133 -0
  251. package/skills/ios/hig-technologies/SKILL.md +107 -0
  252. package/skills/ios/hig-technologies/references/airplay.md +125 -0
  253. package/skills/ios/hig-technologies/references/always-on.md +62 -0
  254. package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
  255. package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
  256. package/skills/ios/hig-technologies/references/carekit.md +224 -0
  257. package/skills/ios/hig-technologies/references/carplay.md +119 -0
  258. package/skills/ios/hig-technologies/references/game-center.md +343 -0
  259. package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
  260. package/skills/ios/hig-technologies/references/healthkit.md +120 -0
  261. package/skills/ios/hig-technologies/references/homekit.md +343 -0
  262. package/skills/ios/hig-technologies/references/icloud.md +52 -0
  263. package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
  264. package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
  265. package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
  266. package/skills/ios/hig-technologies/references/live-photos.md +54 -0
  267. package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
  268. package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
  269. package/skills/ios/hig-technologies/references/maps.md +221 -0
  270. package/skills/ios/hig-technologies/references/nfc.md +51 -0
  271. package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
  272. package/skills/ios/hig-technologies/references/researchkit.md +134 -0
  273. package/skills/ios/hig-technologies/references/shareplay.md +142 -0
  274. package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
  275. package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
  276. package/skills/ios/hig-technologies/references/siri.md +523 -0
  277. package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
  278. package/skills/ios/hig-technologies/references/voiceover.md +90 -0
  279. package/skills/ios/hig-technologies/references/wallet.md +420 -0
  280. package/skills/ios/ios-26-platform/SKILL.md +53 -0
  281. package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
  282. package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
  283. package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
  284. package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
  285. package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
  286. package/skills/ios/ios-bootstrap/SKILL.md +107 -0
  287. package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
  288. package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
  289. package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
  290. package/skills/ios/ios-debugger-agent/LICENSE +21 -0
  291. package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
  292. package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
  293. package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
  294. package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
  295. package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
  296. package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
  297. package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
  298. package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
  299. package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
  300. package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
  301. package/skills/ios/swift-accessibility/LICENSE +21 -0
  302. package/skills/ios/swift-accessibility/SKILL.md +371 -0
  303. package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
  304. package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
  305. package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
  306. package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
  307. package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
  308. package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
  309. package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
  310. package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
  311. package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
  312. package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
  313. package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
  314. package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
  315. package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
  316. package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
  317. package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
  318. package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
  319. package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
  320. package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
  321. package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
  322. package/skills/ios/swift-concurrency/LICENSE +21 -0
  323. package/skills/ios/swift-concurrency/SKILL.md +171 -0
  324. package/skills/ios/swift-concurrency/references/_index.md +50 -0
  325. package/skills/ios/swift-concurrency/references/actors.md +660 -0
  326. package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
  327. package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
  328. package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
  329. package/skills/ios/swift-concurrency/references/core-data.md +560 -0
  330. package/skills/ios/swift-concurrency/references/glossary.md +135 -0
  331. package/skills/ios/swift-concurrency/references/linting.md +155 -0
  332. package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
  333. package/skills/ios/swift-concurrency/references/migration.md +1104 -0
  334. package/skills/ios/swift-concurrency/references/performance.md +593 -0
  335. package/skills/ios/swift-concurrency/references/sendable.md +598 -0
  336. package/skills/ios/swift-concurrency/references/tasks.md +636 -0
  337. package/skills/ios/swift-concurrency/references/testing.md +592 -0
  338. package/skills/ios/swift-concurrency/references/threading.md +495 -0
  339. package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
  340. package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
  341. package/skills/ios/swift-security-expert/LICENSE +21 -0
  342. package/skills/ios/swift-security-expert/SKILL.md +470 -0
  343. package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
  344. package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
  345. package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
  346. package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
  347. package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
  348. package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
  349. package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
  350. package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
  351. package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
  352. package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
  353. package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
  354. package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
  355. package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
  356. package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
  357. package/skills/ios/swift-testing-expert/LICENSE +21 -0
  358. package/skills/ios/swift-testing-expert/SKILL.md +79 -0
  359. package/skills/ios/swift-testing-expert/references/_index.md +12 -0
  360. package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
  361. package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
  362. package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
  363. package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
  364. package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
  365. package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
  366. package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
  367. package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
  368. package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
  369. package/skills/ios/swiftdata-pro/LICENSE +21 -0
  370. package/skills/ios/swiftdata-pro/SKILL.md +102 -0
  371. package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
  372. package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
  373. package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
  374. package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
  375. package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
  376. package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
  377. package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
  378. package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
  379. package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
  380. package/skills/ios/swiftui-design-principles/LICENSE +21 -0
  381. package/skills/ios/swiftui-design-principles/README.md +41 -0
  382. package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
  383. package/skills/ios/swiftui-design-principles/metadata.json +10 -0
  384. package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
  385. package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
  386. package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
  387. package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
  388. package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
  389. package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
  390. package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
  391. package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
  392. package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
  393. package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
  394. package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
  395. package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
  396. package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
  397. package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
  398. package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
  399. package/skills/ios/swiftui-pro/LICENSE +21 -0
  400. package/skills/ios/swiftui-pro/SKILL.md +108 -0
  401. package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
  402. package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  403. package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  404. package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
  405. package/skills/ios/swiftui-pro/references/api.md +39 -0
  406. package/skills/ios/swiftui-pro/references/data.md +43 -0
  407. package/skills/ios/swiftui-pro/references/design.md +31 -0
  408. package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
  409. package/skills/ios/swiftui-pro/references/navigation.md +14 -0
  410. package/skills/ios/swiftui-pro/references/performance.md +46 -0
  411. package/skills/ios/swiftui-pro/references/swift.md +56 -0
  412. package/skills/ios/swiftui-pro/references/views.md +35 -0
  413. package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
  414. package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
  415. package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
  416. package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
  417. package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
  418. package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
  419. package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
  420. package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
  421. package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
  422. package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
  423. package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
  424. package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
  425. package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  426. package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  427. package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
  428. package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  429. package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
  430. package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  431. package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
  432. package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
  433. package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
  434. package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
  435. package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
  436. package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
  437. package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  438. package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
  439. package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
  440. package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
  441. package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
  442. package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
  443. package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
  444. package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
  445. package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
  446. package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
  447. package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
  448. package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
  449. package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
  450. package/skills/ios/widgetkit/LICENSE +131 -0
  451. package/skills/ios/widgetkit/SKILL.md +502 -0
  452. package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
  453. package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
  454. package/skills/web/accessibility/SKILL.md +146 -0
  455. package/skills/web/aceternity-ui/SKILL.md +719 -0
  456. package/skills/web/aceternity-ui/metadata.json +10 -0
  457. package/skills/web/api-design/SKILL.md +523 -0
  458. package/skills/web/chart-accessibility/SKILL.md +332 -0
  459. package/skills/web/composition-patterns/AGENTS.md +946 -0
  460. package/skills/web/composition-patterns/README.md +60 -0
  461. package/skills/web/composition-patterns/SKILL.md +89 -0
  462. package/skills/web/composition-patterns/metadata.json +11 -0
  463. package/skills/web/composition-patterns/rules/_sections.md +29 -0
  464. package/skills/web/composition-patterns/rules/_template.md +24 -0
  465. package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  466. package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
  467. package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  468. package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
  469. package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
  470. package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
  471. package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
  472. package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
  473. package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
  474. package/skills/web/database-migrations/SKILL.md +429 -0
  475. package/skills/web/deployment-patterns/SKILL.md +427 -0
  476. package/skills/web/docker-patterns/SKILL.md +364 -0
  477. package/skills/web/e2e-testing/SKILL.md +326 -0
  478. package/skills/web/lighthouse-ci/SKILL.md +361 -0
  479. package/skills/web/mcp-server-patterns/SKILL.md +69 -0
  480. package/skills/web/next-best-practices/SKILL.md +153 -0
  481. package/skills/web/next-best-practices/async-patterns.md +87 -0
  482. package/skills/web/next-best-practices/bundling.md +180 -0
  483. package/skills/web/next-best-practices/data-patterns.md +297 -0
  484. package/skills/web/next-best-practices/debug-tricks.md +105 -0
  485. package/skills/web/next-best-practices/directives.md +73 -0
  486. package/skills/web/next-best-practices/error-handling.md +227 -0
  487. package/skills/web/next-best-practices/file-conventions.md +140 -0
  488. package/skills/web/next-best-practices/font.md +245 -0
  489. package/skills/web/next-best-practices/functions.md +108 -0
  490. package/skills/web/next-best-practices/hydration-error.md +91 -0
  491. package/skills/web/next-best-practices/image.md +173 -0
  492. package/skills/web/next-best-practices/metadata.md +301 -0
  493. package/skills/web/next-best-practices/parallel-routes.md +287 -0
  494. package/skills/web/next-best-practices/route-handlers.md +146 -0
  495. package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
  496. package/skills/web/next-best-practices/runtime-selection.md +39 -0
  497. package/skills/web/next-best-practices/scripts.md +141 -0
  498. package/skills/web/next-best-practices/self-hosting.md +371 -0
  499. package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
  500. package/skills/web/next-cache-components/SKILL.md +411 -0
  501. package/skills/web/postgres-best-practices/SKILL.md +14 -0
  502. package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
  503. package/skills/web/react-best-practices/AGENTS.md +3810 -0
  504. package/skills/web/react-best-practices/README.md +123 -0
  505. package/skills/web/react-best-practices/SKILL.md +149 -0
  506. package/skills/web/react-best-practices/metadata.json +15 -0
  507. package/skills/web/react-best-practices/rules/_sections.md +46 -0
  508. package/skills/web/react-best-practices/rules/_template.md +28 -0
  509. package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
  510. package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  511. package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
  512. package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
  513. package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
  514. package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  515. package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
  516. package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
  517. package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
  518. package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  519. package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
  520. package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
  521. package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
  522. package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  523. package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  524. package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
  525. package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
  526. package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
  527. package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  528. package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
  529. package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
  530. package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
  531. package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
  532. package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
  533. package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
  534. package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
  535. package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
  536. package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
  537. package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
  538. package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
  539. package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
  540. package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
  541. package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
  542. package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  543. package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
  544. package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  545. package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
  546. package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
  547. package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  548. package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  549. package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  550. package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
  551. package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
  552. package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
  553. package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  554. package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
  555. package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
  556. package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  557. package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
  558. package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  559. package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  560. package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  561. package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
  562. package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  563. package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
  564. package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  565. package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  566. package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
  567. package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  568. package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  569. package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
  570. package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
  571. package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
  572. package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
  573. package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
  574. package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
  575. package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
  576. package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
  577. package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
  578. package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
  579. package/skills/web/seo/SKILL.md +154 -0
  580. package/skills/web/web-design-guidelines/SKILL.md +39 -0
  581. package/skills/web/zap-scan-config/SKILL.md +444 -0
  582. package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
  583. package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
  584. package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
  585. package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
  586. package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
  587. package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
  588. package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
  589. package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
  590. package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
  591. package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
  592. package/src/lrr/aggregator.ts +80 -0
  593. package/src/orchestrator/hooks/context-header.ts +95 -0
  594. package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
  595. package/src/orchestrator/hooks/token-accounting.ts +101 -0
  596. package/src/orchestrator/mcp/cycle-counter.ts +129 -0
  597. package/src/orchestrator/mcp/scribe.ts +283 -0
  598. package/src/orchestrator/mcp/state-save.ts +149 -0
  599. package/src/orchestrator/mcp/write-lease.ts +167 -0
  600. package/src/orchestrator/phase4-shared-context.ts +41 -0
  601. package/src/orchestrator/schemas/backward-edge.ts +46 -0
  602. package/agents/agentic-identity-trust.md +0 -121
  603. package/agents/data-consolidation-agent.md +0 -39
  604. package/agents/design-image-prompt-engineer.md +0 -105
  605. package/agents/design-visual-storyteller.md +0 -147
  606. package/agents/design-whimsy-injector.md +0 -89
  607. package/agents/engineering-autonomous-optimization-architect.md +0 -105
  608. package/agents/market-intel.md +0 -35
  609. package/agents/marketing-instagram-curator.md +0 -111
  610. package/agents/marketing-reddit-community-builder.md +0 -121
  611. package/agents/marketing-social-media-strategist.md +0 -74
  612. package/agents/marketing-tiktok-strategist.md +0 -123
  613. package/agents/marketing-twitter-engager.md +0 -124
  614. package/agents/marketing-wechat-official-account.md +0 -143
  615. package/agents/marketing-xiaohongshu-specialist.md +0 -136
  616. package/agents/marketing-zhihu-strategist.md +0 -160
  617. package/agents/product-behavioral-nudge-engine.md +0 -78
  618. package/agents/project-management-experiment-tracker.md +0 -102
  619. package/agents/report-distribution-agent.md +0 -43
  620. package/agents/risk-analysis.md +0 -45
  621. package/agents/sales-data-extraction-agent.md +0 -46
  622. package/agents/specialized-cultural-intelligence-strategist.md +0 -65
  623. package/agents/specialized-developer-advocate.md +0 -146
  624. package/agents/support-analytics-reporter.md +0 -133
  625. package/agents/support-executive-summary-generator.md +0 -64
  626. package/agents/support-finance-tracker.md +0 -145
  627. package/agents/support-legal-compliance-checker.md +0 -129
  628. package/agents/support-support-responder.md +0 -91
  629. package/agents/testing-accessibility-auditor.md +0 -110
  630. package/agents/testing-test-results-analyzer.md +0 -97
  631. package/agents/testing-tool-evaluator.md +0 -76
  632. package/agents/testing-workflow-optimizer.md +0 -99
  633. package/agents/user-research.md +0 -40
@@ -0,0 +1,508 @@
1
+ # Keychain Access Control
2
+
3
+ > Scope: Selecting `kSecAttrAccessible` classes and `SecAccessControl` flags to enforce the correct lock-state and user-presence guarantees for keychain items.
4
+
5
+ Data protection classes (`kSecAttrAccessible`) and runtime authentication gates (`SecAccessControl`) form the two-layer security model protecting every keychain item. The first controls **when** an item's class key is available in memory based on device state; the second controls **how** the user must authenticate at access time. Both must be satisfied for a read to succeed. Getting this wrong is the single most common cause of production keychain failures — background operations that silently return `nil`, items that vanish after device migration, or credentials left decryptable at rest.
6
+
7
+ Sources: Apple Platform Security Guide (2024–2026 editions), Apple Keychain Services documentation, TN3137, WWDC 2014 Session 711 ("Keychain and Authentication with Touch ID"), WWDC 2015 Session 706, SecAccessControl documentation, OWASP MASTG.
8
+
9
+ ---
10
+
11
+ ## The "When" Layer: Seven Accessibility Constants
12
+
13
+ Every keychain item is encrypted with a class key derived from the device's hardware UID and (for most classes) the user's passcode. The `kSecAttrAccessible` attribute selects which class key protects the item, determining when the system can decrypt it. **If you omit `kSecAttrAccessible`, the default is `kSecAttrAccessibleWhenUnlocked`** — confirmed by Apple documentation. This default breaks all background operations.
14
+
15
+ ### The Protection Spectrum
16
+
17
+ Listed from most restrictive to least:
18
+
19
+ **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`** (iOS 8+) — the highest-security class. Items are accessible only while unlocked, and only if a device passcode is currently set. Two unique behaviors: (1) `SecItemAdd` fails on devices without a passcode, (2) **removing the passcode permanently deletes all items in this class** — class keys are discarded, data is unrecoverable. No non-`ThisDeviceOnly` variant exists. Items don't sync to iCloud Keychain, aren't backed up, and aren't in escrow keybags.
20
+
21
+ **`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`** — Items decryptable only while unlocked. Device-bound: excluded from backups and device migration.
22
+
23
+ **`kSecAttrAccessibleWhenUnlocked`** ⭐ (system default) — Same lock-state behavior as above, but items migrate with encrypted backups. Maps to `NSFileProtectionComplete`. Class key is discarded from memory shortly after the device locks (~10 seconds with Require Password set to Immediately).
24
+
25
+ **`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`** — **The correct choice for background operations.** After the user unlocks the device once following a restart, the class key remains in memory until the next restart — even while locked. Device-bound.
26
+
27
+ **`kSecAttrAccessibleAfterFirstUnlock`** — Same background accessibility, but items migrate with encrypted backups. Apple uses this for system Wi-Fi passwords, mail accounts, and iCloud tokens. Maps to `NSFileProtectionCompleteUntilFirstUserAuthentication`.
28
+
29
+ **`kSecAttrAccessibleAlwaysThisDeviceOnly`** ⚠️ DEPRECATED — Deprecated in iOS 12 / macOS 10.14. Apple announced intent at WWDC 2015 Session 706.
30
+
31
+ **`kSecAttrAccessibleAlways`** ⚠️ DEPRECATED — Same deprecation. Items encrypted with only the device UID (no passcode involvement), equivalent to `NSFileProtectionNone`.
32
+
33
+ > **Cross-validation note — deprecated "Always" runtime behavior:** One research source reports these constants "still function at runtime" with original semantics on iOS 15–18. The other reports modern iOS silently remaps them to `AfterFirstUnlock` behavior. The practical guidance is identical either way: **migrate immediately to `kSecAttrAccessibleAfterFirstUnlock`**. Block these constants in CI linting. Do not rely on any specific runtime behavior for deprecated constants across OS versions.
34
+
35
+ ### Quick Reference Table
36
+
37
+ | Constant | Accessible When | Survives Lock | Migrates in Backup | Special |
38
+ | -------------------------------- | ----------------------- | ------------- | ------------------ | ------------------------------- |
39
+ | `WhenPasscodeSetThisDeviceOnly` | Unlocked + passcode set | No | No | **Deleted on passcode removal** |
40
+ | `WhenUnlockedThisDeviceOnly` | Unlocked | No | No | — |
41
+ | `WhenUnlocked` ⭐ default | Unlocked | No | Yes | — |
42
+ | `AfterFirstUnlockThisDeviceOnly` | After first unlock | Yes | No | Background-safe |
43
+ | `AfterFirstUnlock` | After first unlock | Yes | Yes | Background-safe + migratable |
44
+ | `AlwaysThisDeviceOnly` ⚠️ | Always¹ | Yes | No | Deprecated iOS 12 |
45
+ | `Always` ⚠️ | Always¹ | Yes | Yes | Deprecated iOS 12 |
46
+
47
+ ¹ Behavior may be remapped to `AfterFirstUnlock` on modern iOS versions.
48
+
49
+ ### Lock-State Spectrum Explained
50
+
51
+ After a device restart, the system is in **Before First Unlock (BFU)** state. Only items with the deprecated `Always` class are supposed to be accessible. Even `AfterFirstUnlock` items are locked.
52
+
53
+ Once the user enters their passcode, the device enters **After First Unlock (AFU)** state. `AfterFirstUnlock` class keys load into memory and remain there through subsequent lock/unlock cycles until the next restart. `WhenUnlocked` class keys are available only during active unlocked periods and discarded each time the device locks.
54
+
55
+ > **iOS 15+ caveat — app pre-warming:** iOS can launch your process before first unlock for faster app startup. This means even `AfterFirstUnlock` items may be temporarily unavailable during pre-warm. Check `UIApplication.shared.isProtectedDataAvailable` before accessing keychain items, and defer if it returns `false`.
56
+
57
+ ---
58
+
59
+ ## The "How" Layer: SecAccessControl Flags
60
+
61
+ `SecAccessControl` adds runtime authentication requirements on top of data-at-rest protection. It is created via `SecAccessControlCreateWithFlags`, which embeds the accessibility level inside the control object:
62
+
63
+ ```swift
64
+ func SecAccessControlCreateWithFlags(
65
+ _ allocator: CFAllocator?, // Pass nil
66
+ _ protection: CFTypeRef, // A kSecAttrAccessible constant
67
+ _ flags: SecAccessControlCreateFlags,
68
+ _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?
69
+ ) -> SecAccessControl?
70
+ ```
71
+
72
+ ### Available Flags
73
+
74
+ **Authentication constraints:**
75
+
76
+ - **`.userPresence`** (iOS 8+) — Biometry OR passcode. Does not require biometry enrollment; auto-falls back to passcode. Equivalent to `[.biometryAny, .or, .devicePasscode]` but handles no-biometry gracefully.
77
+ - **`.biometryAny`** (iOS 11.3+, was `.touchIDAny`) — Requires biometric authentication. Item **survives** enrollment changes (new fingerprints, Face ID re-enrollment).
78
+ - **`.biometryCurrentSet`** (iOS 11.3+, was `.touchIDCurrentSet`) — Requires biometric authentication. Item **invalidated** on enrollment changes. Most secure biometric option — blocks an attacker who enrolls their own biometrics.
79
+ - **`.devicePasscode`** (iOS 9+) — Requires device passcode entry only.
80
+
81
+ **Logical combinators:**
82
+
83
+ - **`.or`** — At least one constraint must be satisfied.
84
+ - **`.and`** — All constraints must be satisfied.
85
+
86
+ **Additional:**
87
+
88
+ - **`.privateKeyUsage`** (iOS 9+) — Required for Secure Enclave private key operations (signing, key agreement).
89
+ - **`.applicationPassword`** (iOS 9+) — Adds an app-provided password to key derivation. Not a constraint — an additional encryption layer.
90
+
91
+ ### Flag Compatibility Matrix
92
+
93
+ | Flag | Works in Background? | Typical Pairing | Failure if Misused |
94
+ | ---------------------- | ------------------------ | ----------------------------------------- | -------------------------------------------- |
95
+ | `.userPresence` | No | Foreground + `WhenUnlocked` | `-25308` in background |
96
+ | `.biometryAny` | No | Foreground secrets | `errSecAuthFailed` if no biometrics enrolled |
97
+ | `.biometryCurrentSet` | No | `WhenPasscodeSetTDO` for highest security | Auth fails on enrollment change |
98
+ | `.devicePasscode` | No | Compliance flows | `-25308` without UI |
99
+ | `.privateKeyUsage` | Yes (for key ops) | Secure Enclave keys | — |
100
+ | `.applicationPassword` | Yes (if password cached) | Niche models | Password lifecycle management |
101
+
102
+ ### Composing Constraints
103
+
104
+ Since `SecAccessControlCreateFlags` is an `OptionSet`, compose with array literal syntax:
105
+
106
+ ```swift
107
+ // Biometry OR passcode — most common pattern
108
+ let flags: SecAccessControlCreateFlags = [.biometryCurrentSet, .or, .devicePasscode]
109
+
110
+ // Biometry AND passcode — both required (rare, high security)
111
+ let flags: SecAccessControlCreateFlags = [.biometryAny, .and, .devicePasscode]
112
+
113
+ // Biometry OR passcode, plus application password encryption
114
+ let flags: SecAccessControlCreateFlags = [.biometryAny, .or, .devicePasscode, .applicationPassword]
115
+ ```
116
+
117
+ > **Critical rule: `.or` / `.and` is required between authentication flags.** Combining `.biometryCurrentSet` and `.devicePasscode` without a logical operator causes `SecAccessControlCreateWithFlags` to return `nil` with `errSecParam` (-50). Both sources confirm this behavior.
118
+
119
+ ---
120
+
121
+ ## The Cardinal Rule: Never Set Both Attributes
122
+
123
+ `kSecAttrAccessible` and `kSecAttrAccessControl` are **mutually exclusive** in the query dictionary. When you use `SecAccessControlCreateWithFlags`, the accessibility level is embedded inside the `SecAccessControl` object via the `protection` parameter. Setting both in the same `SecItemAdd` query causes **`errSecParam` (-50)**.
124
+
125
+ ```swift
126
+ // ❌ WRONG — sets accessibility twice, causes errSecParam (-50)
127
+ var error: Unmanaged<CFError>?
128
+ let access = SecAccessControlCreateWithFlags(
129
+ nil,
130
+ kSecAttrAccessibleWhenUnlockedThisDeviceOnly, // ← accessibility set HERE
131
+ [.biometryCurrentSet, .or, .devicePasscode],
132
+ &error
133
+ )!
134
+
135
+ let query: [String: Any] = [
136
+ kSecClass as String: kSecClassGenericPassword,
137
+ kSecAttrAccount as String: "credential",
138
+ kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, // ❌ CONFLICT
139
+ kSecAttrAccessControl as String: access, // ← already contains accessibility
140
+ kSecValueData as String: secretData
141
+ ]
142
+ // SecItemAdd returns errSecParam (-50)
143
+ ```
144
+
145
+ ```swift
146
+ // ✅ CORRECT — accessibility set only inside SecAccessControl
147
+ var error: Unmanaged<CFError>?
148
+ guard let access = SecAccessControlCreateWithFlags(
149
+ nil,
150
+ kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
151
+ [.biometryCurrentSet, .or, .devicePasscode],
152
+ &error
153
+ ) else { throw KeychainError.accessControlCreationFailed(error?.takeRetainedValue()) }
154
+
155
+ let query: [String: Any] = [
156
+ kSecClass as String: kSecClassGenericPassword,
157
+ kSecAttrAccount as String: "credential",
158
+ kSecAttrAccessControl as String: access, // Contains accessibility + auth flags
159
+ kSecValueData as String: secretData
160
+ ]
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Decision Matrix: Choosing the Right Accessibility Level
166
+
167
+ ### `WhenPasscodeSetThisDeviceOnly` — Data that should self-destruct
168
+
169
+ Use for your most sensitive credentials. Pair with `.biometryCurrentSet` via `SecAccessControl`. Accept the tradeoff: items are permanently destroyed on passcode removal and never survive device migration. Your app **must** handle item absence gracefully and guide users through re-authentication.
170
+
171
+ **Use cases:** Banking session tokens, password manager vault keys, healthcare credentials, E2E encryption private keys.
172
+
173
+ ### `WhenUnlockedThisDeviceOnly` — Standard device-bound credentials
174
+
175
+ Credentials that should be device-bound but don't need passcode-deletion behavior. Re-authenticate after device migration.
176
+
177
+ **Use cases:** OAuth access tokens (refreshable), app-specific API keys, cached credentials, device registration tokens.
178
+
179
+ ### `AfterFirstUnlockThisDeviceOnly` — Background operations (most common for services)
180
+
181
+ The correct choice for **any keychain item accessed by background code** — push notification handlers, WidgetKit timeline providers, background fetch, VPN extensions, notification service extensions. Device-bound.
182
+
183
+ **Use cases:** Push notification decryption keys, VPN credentials, background sync tokens, watch connectivity tokens.
184
+
185
+ ### `AfterFirstUnlock` — Background + backup migration
186
+
187
+ Same background accessibility, plus items migrate with encrypted backups. Use when background access and device-transfer continuity are both needed.
188
+
189
+ **Use cases:** Enterprise VPN credentials, email account credentials, Wi-Fi configuration passwords.
190
+
191
+ ### Dual-Item Strategy for Mixed Contexts
192
+
193
+ If a credential needs both background access (no UI) and foreground biometric protection (with UI), **store two separate items**: a background-capable token with `AfterFirstUnlockThisDeviceOnly` (no `SecAccessControl` user-presence flags) and a stronger foreground-only item with `WhenUnlockedThisDeviceOnly` + biometric `SecAccessControl`. This avoids the logical contradiction of biometric flags on background-accessible items.
194
+
195
+ ---
196
+
197
+ ## Common AI-Generated Mistakes
198
+
199
+ ### Mistake 1: Omitting `kSecAttrAccessible` (inheriting the wrong default)
200
+
201
+ The most pervasive error. AI code generators produce keychain wrappers that never set `kSecAttrAccessible`, inheriting `WhenUnlocked`. Works during development (device unlocked while testing), fails in production when background extensions execute while locked — `errSecInteractionNotAllowed` (-25308), often silently swallowed.
202
+
203
+ ```swift
204
+ // ❌ WRONG — omits kSecAttrAccessible, defaults to WhenUnlocked
205
+ let query: [String: Any] = [
206
+ kSecClass as String: kSecClassGenericPassword,
207
+ kSecAttrAccount as String: "authToken",
208
+ kSecAttrService as String: "com.example.app",
209
+ kSecValueData as String: tokenData
210
+ // Missing: kSecAttrAccessible — background extensions WILL fail with -25308
211
+ ]
212
+ ```
213
+
214
+ ```swift
215
+ // ✅ CORRECT — explicit accessibility for background use
216
+ let query: [String: Any] = [
217
+ kSecClass as String: kSecClassGenericPassword,
218
+ kSecAttrAccount as String: "authToken",
219
+ kSecAttrService as String: "com.example.app",
220
+ kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
221
+ kSecValueData as String: tokenData
222
+ ]
223
+ ```
224
+
225
+ ### Mistake 2: Using deprecated `kSecAttrAccessibleAlways`
226
+
227
+ Compiles with a warning on iOS 12+, runs at runtime — arguably worse than a hard failure. No meaningful lock-state protection.
228
+
229
+ ```swift
230
+ // ❌ WRONG — deprecated since iOS 12
231
+ let query: [String: Any] = [
232
+ kSecClass as String: kSecClassGenericPassword,
233
+ kSecAttrAccessible as String: kSecAttrAccessibleAlways, // ⚠️ Deprecated
234
+ kSecValueData as String: tokenData
235
+ ]
236
+ // Replacement: kSecAttrAccessibleAfterFirstUnlock
237
+ ```
238
+
239
+ ### Mistake 3: Not handling `ThisDeviceOnly` item loss after device migration
240
+
241
+ Items with `ThisDeviceOnly` are cryptographically bound to the hardware UID. They are excluded from all backups, iCloud sync, and Quick Start device-to-device migration. After restoring to a new device, these items silently disappear — `errSecItemNotFound` (-25300). AI-generated code rarely implements re-authentication flows for this scenario.
242
+
243
+ ### Mistake 4: Biometric flags on background-accessible protection levels
244
+
245
+ Setting `.biometryCurrentSet` with `kSecAttrAccessibleAfterFirstUnlock` is technically valid at the API level but creates a **logical contradiction**: `AfterFirstUnlock` implies background access while locked, but biometric auth requires an interactive prompt. Result: `errSecInteractionNotAllowed` in background contexts, defeating the purpose.
246
+
247
+ ### Mistake 5: Conflicting flags without logical operator
248
+
249
+ Combining `.biometryCurrentSet` and `.devicePasscode` without `.or` or `.and` causes `SecAccessControlCreateWithFlags` to return `nil` / `errSecParam` (-50).
250
+
251
+ ```swift
252
+ // ❌ WRONG — missing logical operator
253
+ let access = SecAccessControlCreateWithFlags(
254
+ nil,
255
+ kSecAttrAccessibleWhenUnlocked,
256
+ [.biometryCurrentSet, .devicePasscode], // Missing .or or .and
257
+ &error
258
+ )
259
+ // Returns nil, error contains errSecParam
260
+ ```
261
+
262
+ ```swift
263
+ // ✅ CORRECT — explicit .or between constraints
264
+ let access = SecAccessControlCreateWithFlags(
265
+ nil,
266
+ kSecAttrAccessibleWhenUnlocked,
267
+ [.biometryCurrentSet, .or, .devicePasscode],
268
+ &error
269
+ )
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Code Patterns
275
+
276
+ ✅ The first two examples are correct patterns for foreground and background access. The third example is intentionally incorrect.
277
+
278
+ ### Biometric protection with highest security
279
+
280
+ ```swift
281
+ func saveBiometricProtectedItem(data: Data, account: String, service: String) throws {
282
+ var error: Unmanaged<CFError>?
283
+ guard let accessControl = SecAccessControlCreateWithFlags(
284
+ nil,
285
+ kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
286
+ [.biometryCurrentSet, .or, .devicePasscode],
287
+ &error
288
+ ) else {
289
+ throw KeychainError.accessControlCreationFailed(error?.takeRetainedValue())
290
+ }
291
+
292
+ let query: [String: Any] = [
293
+ kSecClass as String: kSecClassGenericPassword,
294
+ kSecAttrAccount as String: account,
295
+ kSecAttrService as String: service,
296
+ kSecAttrAccessControl as String: accessControl,
297
+ kSecValueData as String: data
298
+ ]
299
+
300
+ let status = SecItemAdd(query as CFDictionary, nil)
301
+ switch status {
302
+ case errSecSuccess: return
303
+ case errSecDuplicateItem:
304
+ // Must delete + re-add: SecItemUpdate cannot change SecAccessControl
305
+ let searchQuery: [String: Any] = [
306
+ kSecClass as String: kSecClassGenericPassword,
307
+ kSecAttrAccount as String: account,
308
+ kSecAttrService as String: service
309
+ ]
310
+ let deleteStatus = SecItemDelete(searchQuery as CFDictionary)
311
+ guard deleteStatus == errSecSuccess else {
312
+ throw KeychainError.fromStatus(deleteStatus)
313
+ }
314
+ let readdStatus = SecItemAdd(query as CFDictionary, nil)
315
+ guard readdStatus == errSecSuccess else {
316
+ throw KeychainError.fromStatus(readdStatus)
317
+ }
318
+ default:
319
+ throw KeychainError.fromStatus(status)
320
+ }
321
+ }
322
+ ```
323
+
324
+ > **Important:** `SecItemUpdate` **cannot** change a `SecAccessControl` attribute on an existing item. To change access control, you must delete and re-add. Both sources confirm this.
325
+
326
+ ### Background-accessible token (push notifications, VPN, widgets)
327
+
328
+ ```swift
329
+ func saveBackgroundToken(_ token: Data, account: String, service: String) throws {
330
+ let query: [String: Any] = [
331
+ kSecClass as String: kSecClassGenericPassword,
332
+ kSecAttrAccount as String: account,
333
+ kSecAttrService as String: service,
334
+ kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
335
+ kSecValueData as String: token
336
+ ]
337
+
338
+ let status = SecItemAdd(query as CFDictionary, nil)
339
+ switch status {
340
+ case errSecSuccess: return
341
+ case errSecDuplicateItem:
342
+ let updateAttrs: [String: Any] = [kSecValueData as String: token]
343
+ let searchQuery: [String: Any] = [
344
+ kSecClass as String: kSecClassGenericPassword,
345
+ kSecAttrAccount as String: account,
346
+ kSecAttrService as String: service
347
+ ]
348
+ let updateStatus = SecItemUpdate(searchQuery as CFDictionary, updateAttrs as CFDictionary)
349
+ guard updateStatus == errSecSuccess else {
350
+ throw KeychainError.fromStatus(updateStatus)
351
+ }
352
+ default:
353
+ throw KeychainError.fromStatus(status)
354
+ }
355
+ }
356
+ ```
357
+
358
+ ### Accessing a `WhenUnlocked` item from a background extension
359
+
360
+ ```swift
361
+ // Runs in WidgetKit TimelineProvider or NotificationServiceExtension while locked — WILL fail
362
+ func fetchTokenInBackground() -> String? {
363
+ let query: [String: Any] = [
364
+ kSecClass as String: kSecClassGenericPassword,
365
+ kSecAttrAccount as String: "authToken",
366
+ kSecAttrService as String: "com.example.app",
367
+ kSecReturnData as String: true,
368
+ kSecMatchLimit as String: kSecMatchLimitOne
369
+ // Item stored with default WhenUnlocked — inaccessible while locked
370
+ ]
371
+
372
+ var result: AnyObject?
373
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
374
+ // status == errSecInteractionNotAllowed (-25308) when device is locked
375
+ guard status == errSecSuccess, let data = result as? Data else {
376
+ return nil // ❌ Silent failure — no logging, no error propagation
377
+ }
378
+ return String(data: data, encoding: .utf8)
379
+ }
380
+ ```
381
+
382
+ ---
383
+
384
+ ## macOS: `kSecUseDataProtectionKeychain`
385
+
386
+ macOS has **two keychain implementations** (per TN3137): the legacy file-based keychain (`~/Library/Keychains/login.keychain-db`) and the modern Data Protection keychain. The `SecItem` API defaults to the **legacy** keychain on macOS.
387
+
388
+ Set `kSecUseDataProtectionKeychain: true` in every macOS keychain query to target the modern keychain. Without it:
389
+
390
+ - `SecAccessControl` flags fail with `errSecParam` (-50)
391
+ - iCloud Keychain sync doesn't work
392
+ - Secure Enclave integration is unavailable
393
+ - Biometric protection (Touch ID) won't function
394
+
395
+ ```swift
396
+ // ✅ macOS: always include kSecUseDataProtectionKeychain
397
+ let query: [String: Any] = [
398
+ kSecClass as String: kSecClassGenericPassword,
399
+ kSecAttrAccount as String: account,
400
+ kSecAttrService as String: service,
401
+ kSecUseDataProtectionKeychain as String: true, // ← Critical on macOS
402
+ kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
403
+ kSecValueData as String: data
404
+ ]
405
+ ```
406
+
407
+ On iOS, tvOS, and watchOS, this flag is ignored (those platforms always use Data Protection). The Data Protection keychain requires a user login context — `launchd` daemons running outside a user session must use the legacy keychain. Mac Catalyst and iOS-on-Mac apps automatically use Data Protection.
408
+
409
+ ---
410
+
411
+ ## NSFileProtection Sidebar
412
+
413
+ The keychain and file system share the same Data Protection architecture but expose it through different APIs. Use the keychain for small discrete secrets (passwords, tokens, keys). Use `NSFileProtection` for larger data (documents, databases, images).
414
+
415
+ **`NSFileProtectionComplete`** (Class A) = `kSecAttrAccessibleWhenUnlocked`. File inaccessible while locked. Class key discarded ~10 seconds after lock.
416
+
417
+ **`NSFileProtectionCompleteUnlessOpen`** (Class B) = **No keychain equivalent.** Uses asymmetric ECDH (Curve25519) to allow already-opened files to continue being written while locked. Designed for background downloads (e.g., mail attachment download continues writing to an already-open file).
418
+
419
+ **`NSFileProtectionCompleteUntilFirstUserAuthentication`** (Class C) = `kSecAttrAccessibleAfterFirstUnlock`. The default for third-party app files when no explicit protection is set. Available after first unlock.
420
+
421
+ **`NSFileProtectionNone`** (Class D) = deprecated `kSecAttrAccessibleAlways`. Protected only by device UID.
422
+
423
+ **Recommended layered approach:** Store encryption keys in the keychain with `WhenUnlockedThisDeviceOnly`, then use those keys to encrypt larger files on disk with `NSFileProtectionComplete` as an additional layer.
424
+
425
+ ---
426
+
427
+ ## Error Codes Reference
428
+
429
+ | Code | Constant | Meaning | Common Root Cause |
430
+ | ---------- | ----------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
431
+ | **-25308** | `errSecInteractionNotAllowed` | Item not accessible in current state | Device locked + `WhenUnlocked` item; BFU state + `AfterFirstUnlock` item; biometric flag in background |
432
+ | **-50** | `errSecParam` | Invalid parameters | Both `kSecAttrAccessible` and `kSecAttrAccessControl` set; conflicting flags without `.or`/`.and`; missing `kSecUseDataProtectionKeychain` on macOS |
433
+ | **-25293** | `errSecAuthFailed` | Authentication failed | Biometric auth failed; enrollment changed with `.biometryCurrentSet`; no biometrics enrolled |
434
+ | **-25300** | `errSecItemNotFound` | Item not in keychain | Item never stored; `ThisDeviceOnly` lost after migration; `WhenPasscodeSet` deleted on passcode removal |
435
+ | **-25299** | `errSecDuplicateItem` | Item already exists | `SecItemAdd` when matching primary keys exist — use add-or-update pattern |
436
+ | **-128** | `errSecUserCanceled` | User canceled prompt | User tapped Cancel on biometric/passcode dialog |
437
+ | **-34018** | `errSecMissingEntitlement` | Missing entitlement | Keychain access group not in entitlements; common on iOS Simulator |
438
+
439
+ The most insidious is `-25308` — it surfaces in production but rarely during development because developers test with unlocked devices. Always handle it by deferring the operation and retrying when `UIApplication.shared.isProtectedDataAvailable` is `true`.
440
+
441
+ ---
442
+
443
+ ## iOS Version Timeline
444
+
445
+ **iOS 8 (2014):** `WhenPasscodeSetThisDeviceOnly` introduced. `SecAccessControlCreateWithFlags` added. `.userPresence` flag.
446
+
447
+ **iOS 9 (2015):** `.devicePasscode`, `.applicationPassword`, `.privateKeyUsage` flags added. Apple announced intent to deprecate `Always` at WWDC 2015 Session 706.
448
+
449
+ **iOS 11.3 (2018):** `.touchIDAny` → `.biometryAny`; `.touchIDCurrentSet` → `.biometryCurrentSet` (unified naming for Face ID).
450
+
451
+ **iOS 12 (2018):** `kSecAttrAccessibleAlways` and `AlwaysThisDeviceOnly` formally deprecated. Both still compile and run for backward compatibility.
452
+
453
+ **iOS 15 (2021):** MDM-installed keychain items changed default from "always" to "after first unlock, nonmigratory." App pre-warming can launch processes before first unlock, making `AfterFirstUnlock` items temporarily unavailable.
454
+
455
+ **iOS 16 (2022):** Passkeys launched (FIDO2/WebAuthn key pairs synced via E2E encrypted iCloud Keychain). No changes to access control APIs.
456
+
457
+ **iOS 17 (2023):** Enterprise passkey support. No `kSecAttrAccessible` or `SecAccessControl` changes.
458
+
459
+ **iOS 18 (2024):** Standalone Passwords app. No keychain data protection API changes.
460
+
461
+ **iOS 26 (2025):** Stolen Device Protection enabled by default — requires biometric auth (no passcode fallback) for stored passwords when away from familiar locations. Secure passkey import/export via FIDO Alliance standard. No changes to `kSecAttrAccessible` constants.
462
+
463
+ ---
464
+
465
+ ## Testing Requirements
466
+
467
+ All data protection testing **must** use physical devices with passcodes enabled. The iOS Simulator does not enforce `kSecAttrAccessible` or `NSFileProtection`, creating a false sense of security.
468
+
469
+ **Critical test scenarios:**
470
+
471
+ 1. **Reboot / BFU state:** Reboot device, attempt keychain access before unlocking. `AfterFirstUnlock` items should return `-25308` or `-25300`. Unlock once, lock again, test background access — should succeed.
472
+
473
+ 2. **Lock timing:** Store a `WhenUnlocked` item. Lock the device. Attempt read immediately — expect `-25308`.
474
+
475
+ 3. **Passcode removal:** Store a `WhenPasscodeSetThisDeviceOnly` item. Remove passcode in Settings. Verify item is deleted (`-25300`).
476
+
477
+ 4. **Biometric enrollment change:** Store an item with `.biometryCurrentSet`. Add a new fingerprint or Face ID appearance. Verify authentication fails (`-25293`).
478
+
479
+ 5. **Backup/restore migration:** Back up device, restore to a different physical device. Verify all `ThisDeviceOnly` items are absent (`-25300`).
480
+
481
+ 6. **Background extension access:** Trigger a notification service extension or widget timeline update while the device is locked. Verify `AfterFirstUnlock` items are readable and `WhenUnlocked` items are not.
482
+
483
+ ---
484
+
485
+ ## Cross-References
486
+
487
+ - `keychain-fundamentals.md` — SecItem CRUD patterns, add-or-update, OSStatus handling
488
+ - `biometric-authentication.md` — Biometric flag selection (`.biometryCurrentSet`, `.biometryAny`, `.userPresence`) and keychain-bound patterns
489
+ - `secure-enclave.md` — Hardware-backed keys with `SecAccessControl` and `.privateKeyUsage`
490
+ - `keychain-item-classes.md` — Class-specific accessibility considerations and primary key composition
491
+ - `common-anti-patterns.md` — Anti-pattern #5 (missing `kSecAttrAccessible`), #3 (LAContext-only gate)
492
+ - `compliance-owasp-mapping.md` — M9 (Insecure Data Storage) accessibility requirements
493
+
494
+ ---
495
+
496
+ ## Summary Checklist
497
+
498
+ 1. **Always set `kSecAttrAccessible` explicitly** — never rely on the `WhenUnlocked` default; choose the level matching your access context (foreground vs background)
499
+ 2. **Never set both `kSecAttrAccessible` and `kSecAttrAccessControl`** in the same query dictionary — accessibility belongs inside `SecAccessControlCreateWithFlags`
500
+ 3. **Use `AfterFirstUnlockThisDeviceOnly`** for any item accessed by background extensions, widgets, VPN, or push notification handlers
501
+ 4. **Pair `WhenPasscodeSetThisDeviceOnly` with `.biometryCurrentSet`** for highest-security items, and handle item deletion on passcode removal gracefully
502
+ 5. **Include `.or` or `.and`** when combining multiple authentication flags — omitting the operator causes `errSecParam` (-50)
503
+ 6. **Set `kSecUseDataProtectionKeychain: true`** on all macOS keychain queries to target the modern Data Protection keychain
504
+ 7. **Implement re-authentication flows** for `ThisDeviceOnly` items that will be absent after device migration or backup restore
505
+ 8. **Check `isProtectedDataAvailable`** before keychain access in app launch paths — iOS 15+ pre-warming can start your process before first unlock
506
+ 9. **Delete and re-add** (not update) when changing `SecAccessControl` on an existing item — `SecItemUpdate` cannot modify access control attributes
507
+ 10. **Test on physical devices** across lock/unlock, reboot, passcode removal, and biometric enrollment change scenarios — the Simulator does not enforce data protection
508
+ 11. **Block deprecated `kSecAttrAccessibleAlways` constants** in CI/CD linting and migrate existing items to `AfterFirstUnlock` on next foreground authentication