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,565 @@
1
+ # Biometric Authentication
2
+
3
+ > **Domain scope:** SecAccessControl + LAContext integration, the LAContext-only bypass vulnerability, hardware-bound biometric gating, fallback behavior, UI customization, enrollment change detection, thread safety.
4
+ >
5
+ > **Risk level:** CRITICAL — #1 most dangerous AI-generated pattern. `LAContext.evaluatePolicy()` used alone is trivially bypassable at runtime.
6
+
7
+ ---
8
+
9
+ ## The Boolean Gate Vulnerability
10
+
11
+ The most dangerous pattern AI coding assistants generate for iOS biometric authentication is `LAContext.evaluatePolicy()` used as a standalone authentication gate. This pattern appears in virtually every tutorial, Stack Overflow answer, and AI training corpus — and it is **trivially bypassable**.
12
+
13
+ The attack requires no exploit. An attacker uses Frida or objection to hook the Objective-C callback and force `success = true`, bypassing Face ID or Touch ID entirely. The formal weakness classification is CWE-288: Authentication Bypass Using an Alternate Path or Channel.
14
+
15
+ OWASP MASTG explicitly fails any app relying solely on `evaluatePolicy` (test MASTG-TEST-0266, requirements MSTG-AUTH-8 and MSTG-AUTH-12). The standard states: biometric authentication must not be event-bound (returning `true`/`false`); it must be based on unlocking the keychain/keystore.
16
+
17
+ ### The Dangerous Pattern — Boolean Gate
18
+
19
+ ```swift
20
+ // ❌ DANGEROUS: Trivially bypassable with Frida — do NOT use for security
21
+ import LocalAuthentication
22
+
23
+ func authenticateUser() {
24
+ let context = LAContext()
25
+ var error: NSError?
26
+
27
+ if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
28
+ context.evaluatePolicy(
29
+ .deviceOwnerAuthenticationWithBiometrics,
30
+ localizedReason: "Authenticate to access your account"
31
+ ) { success, authError in
32
+ DispatchQueue.main.async {
33
+ if success {
34
+ self.isAuthenticated = true // ← Just a boolean in hookable memory
35
+ self.showProtectedContent() // ← No secret unlocked, no key released
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ **Why this fails:** `evaluatePolicy()` asks the OS "did the user authenticate?" and receives a boolean answer in user-space. No cryptographic material is involved. No secret is decrypted. The entire security model rests on a boolean that exists in hookable memory.
44
+
45
+ ### How Attackers Bypass It
46
+
47
+ The objection tool (built on Frida) provides a one-command bypass:
48
+
49
+ ```bash
50
+ objection -g "com.example.targetapp" explore
51
+ ios ui biometrics_bypass
52
+ ```
53
+
54
+ The hook listens for invocations of `-[LAContext evaluatePolicy:localizedReason:reply:]`, intercepts the reply block, and replaces the `success` boolean with `true`. The equivalent raw Frida script:
55
+
56
+ ```javascript
57
+ // Frida script — forces evaluatePolicy success = true
58
+ if (ObjC.available) {
59
+ var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
60
+ Interceptor.attach(hook.implementation, {
61
+ onEnter: function (args) {
62
+ var block = new ObjC.Block(args[4]);
63
+ const callback = block.implementation;
64
+ block.implementation = function (error, value) {
65
+ const result = callback(1, null); // 1 = true, null = no error
66
+ return result;
67
+ };
68
+ },
69
+ });
70
+ }
71
+ ```
72
+
73
+ The objection wiki confirms the attack boundary: this bypass **does not work** against keychain items protected with access control flags like `.biometryCurrentSet` or `.biometryAny`. That boundary is the entire basis of the secure pattern.
74
+
75
+ ✅ Correct pattern in this threat model: use biometrics only to unlock keychain-protected secrets (`SecAccessControl` + `SecItemCopyMatching`), never as a standalone boolean gate.
76
+
77
+ ---
78
+
79
+ ## The Secure Pattern — Hardware-Bound Secrets
80
+
81
+ The correct architecture stores a secret in the iOS keychain with biometric access control. The secret's encryption key is held by the Secure Enclave — a dedicated processor running its own microkernel (sepOS), with its own encrypted memory, completely isolated from the application processor.
82
+
83
+ When the app requests the secret, the Secure Enclave independently verifies the biometric match and only then releases the decryption key. There is no boolean to hook. The data physically cannot be read without valid biometric authentication.
84
+
85
+ WWDC 2014 Session 711 ("Keychain and Authentication with Touch ID") drew the critical distinction:
86
+
87
+ - **`evaluatePolicy`**: "Trust the OS" — vulnerable if runtime is compromised
88
+ - **Keychain + SecAccessControl**: "Trust the Secure Enclave" — ACLs evaluated inside hardware
89
+
90
+ ### Step 1 — Create the Access Control Object
91
+
92
+ ```swift
93
+ import LocalAuthentication
94
+ import Security
95
+
96
+ enum BiometricKeychainError: Error {
97
+ case accessControlCreationFailed
98
+ case keychainOperationFailed(status: OSStatus)
99
+ case dataConversionFailed
100
+ case biometryNotAvailable(reason: String)
101
+ }
102
+
103
+ func createBiometricAccessControl() throws -> SecAccessControl {
104
+ var error: Unmanaged<CFError>?
105
+ guard let accessControl = SecAccessControlCreateWithFlags(
106
+ kCFAllocatorDefault,
107
+ kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Strongest: requires passcode, device-only
108
+ .biometryCurrentSet, // Invalidates on enrollment change
109
+ &error
110
+ ) else {
111
+ throw BiometricKeychainError.accessControlCreationFailed
112
+ }
113
+ return accessControl
114
+ }
115
+ ```
116
+
117
+ ### Step 2 — Store a Secret Bound to Biometric Auth
118
+
119
+ ```swift
120
+ // ✅ SECURE: Secret is encrypted by Secure Enclave, released only on biometric match
121
+ func storeSecretWithBiometric(secret: Data, account: String, service: String) throws {
122
+ let accessControl = try createBiometricAccessControl()
123
+
124
+ // Delete any existing item first (add-or-update pattern)
125
+ let deleteQuery: [String: Any] = [
126
+ kSecClass as String: kSecClassGenericPassword,
127
+ kSecAttrAccount as String: account,
128
+ kSecAttrService as String: service
129
+ ]
130
+ SecItemDelete(deleteQuery as CFDictionary)
131
+
132
+ let addQuery: [String: Any] = [
133
+ kSecClass as String: kSecClassGenericPassword,
134
+ kSecAttrAccount as String: account,
135
+ kSecAttrService as String: service,
136
+ kSecValueData as String: secret,
137
+ kSecAttrAccessControl as String: accessControl,
138
+ kSecAttrSynchronizable as String: kCFBooleanFalse // Never sync biometric-gated secrets
139
+ // NOTE: Do NOT set kSecAttrAccessible — it conflicts with kSecAttrAccessControl
140
+ ]
141
+
142
+ let status = SecItemAdd(addQuery as CFDictionary, nil)
143
+ guard status == errSecSuccess else {
144
+ throw BiometricKeychainError.keychainOperationFailed(status: status)
145
+ }
146
+ }
147
+ ```
148
+
149
+ **Critical detail:** Do NOT set both `kSecAttrAccessible` and `kSecAttrAccessControl` in the same query. They conflict — `SecAccessControl` already encodes the accessibility level. Setting both causes `errSecParam`.
150
+
151
+ **Critical detail:** Always use `ThisDeviceOnly` accessibility for biometric-gated secrets. The `ThisDeviceOnly` suffix ensures the secret is hardware-bound and excluded from iCloud backups. Syncing biometric-gated secrets across devices expands the attack surface.
152
+
153
+ ### Step 3 — Retrieve the Secret (Biometric Prompt Appears Automatically)
154
+
155
+ ```swift
156
+ // ✅ SECURE: System presents biometric prompt; Secure Enclave gates decryption
157
+ func retrieveSecretWithBiometric(account: String, service: String) throws -> Data {
158
+ let context = LAContext()
159
+ context.localizedReason = "Authenticate to access your credentials"
160
+
161
+ let query: [String: Any] = [
162
+ kSecClass as String: kSecClassGenericPassword,
163
+ kSecAttrAccount as String: account,
164
+ kSecAttrService as String: service,
165
+ kSecReturnData as String: true,
166
+ kSecMatchLimit as String: kSecMatchLimitOne,
167
+ kSecUseAuthenticationContext as String: context
168
+ ]
169
+
170
+ var result: AnyObject?
171
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
172
+
173
+ switch status {
174
+ case errSecSuccess:
175
+ guard let data = result as? Data else {
176
+ throw BiometricKeychainError.dataConversionFailed
177
+ }
178
+ return data // Secret returned ONLY after Secure Enclave validates biometric
179
+ case errSecItemNotFound:
180
+ throw BiometricKeychainError.keychainOperationFailed(status: status)
181
+ case errSecUserCanceled:
182
+ throw BiometricKeychainError.keychainOperationFailed(status: status)
183
+ case errSecAuthFailed:
184
+ throw BiometricKeychainError.keychainOperationFailed(status: status)
185
+ default:
186
+ throw BiometricKeychainError.keychainOperationFailed(status: status)
187
+ }
188
+ }
189
+ ```
190
+
191
+ **Key insight:** Authentication and data protection are the same operation, not sequential ones. When `SecItemCopyMatching` encounters an item with biometric access control, the system presents the biometric prompt automatically. The Secure Enclave verifies the match internally and only then unwraps the AES-256-GCM decryption key. There is no callback to intercept.
192
+
193
+ ---
194
+
195
+ ## `evaluatePolicy` vs `evaluateAccessControl`
196
+
197
+ These two `LAContext` methods represent the two trust models from WWDC 2014 Session 711:
198
+
199
+ **`evaluatePolicy(_:localizedReason:reply:)`** triggers biometric authentication and returns a boolean. The Secure Enclave validates the biometric correctly, but the result is communicated to user-space as `true`/`false`. No key is released. The app branches on a boolean in hookable memory. This is "trust the OS."
200
+
201
+ **`evaluateAccessControl(_:operation:localizedReason:reply:)`** evaluates a `SecAccessControl` object for a specific cryptographic operation (`.useItem`, `.useKeySign`, `.useKeyDecrypt`). When used with keychain items, the authenticated `LAContext` is passed to `SecItemCopyMatching` via `kSecUseAuthenticationContext`, and the Secure Enclave recognizes the prior authentication. This is "trust the Secure Enclave."
202
+
203
+ **In practice, you rarely call `evaluateAccessControl` directly.** The recommended flow: store data with `SecAccessControl` via `SecItemAdd`, then retrieve with `SecItemCopyMatching`. The system handles the biometric prompt automatically when the query encounters an ACL-protected item.
204
+
205
+ The only legitimate use of `evaluatePolicy` is **non-security-critical UI gating** — deciding whether to show a "Sign in with Face ID" button. It must never protect sensitive data or gate access to secrets.
206
+
207
+ ---
208
+
209
+ ## Biometric Flag Selection
210
+
211
+ `SecAccessControlCreateFlags` provides three biometric-related flags. Choosing the wrong one is a common mistake even in otherwise-correct implementations.
212
+
213
+ ### `.biometryCurrentSet` — Banking, Payments, Credential Storage
214
+
215
+ Ties the keychain item to the **exact biometric enrollment** at time of storage. If the user adds a fingerprint, re-enrolls Face ID, or removes a biometric entry, the item becomes **permanently inaccessible**.
216
+
217
+ ```swift
218
+ // ✅ Strongest biometric binding — invalidates on enrollment change
219
+ let access = SecAccessControlCreateWithFlags(
220
+ nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
221
+ .biometryCurrentSet, nil
222
+ )
223
+ ```
224
+
225
+ **Tradeoff:** Users who change biometrics must re-authenticate via your app's password flow. Detect enrollment changes via `LAContext.evaluationPolicyDomainState` (see Enrollment Change Detection below) and present graceful re-enrollment.
226
+
227
+ ### `.biometryAny` — Convenience Features, Moderate Sensitivity
228
+
229
+ Survives biometric enrollment changes. An attacker who enrolls their own biometrics on a compromised device can access the data.
230
+
231
+ ```swift
232
+ // Survives re-enrollment — better UX, weaker security
233
+ let access = SecAccessControlCreateWithFlags(
234
+ nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
235
+ .biometryAny, nil
236
+ )
237
+ ```
238
+
239
+ **Use case:** "Remember me" features, non-critical app locks, preferences that benefit from biometric convenience without protecting financial data.
240
+
241
+ ### `.userPresence` — Maximum Device Compatibility
242
+
243
+ Allows passcode fallback when biometrics are unavailable. Weaker because passcodes are susceptible to shoulder-surfing.
244
+
245
+ ```swift
246
+ // Broadest compatibility — biometric or passcode
247
+ let access = SecAccessControlCreateWithFlags(
248
+ nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
249
+ .userPresence, nil
250
+ )
251
+ ```
252
+
253
+ **Use case:** Accessibility-first apps, devices without biometric hardware, or as a `.biometryCurrentSet` degradation path.
254
+
255
+ ### Combining Flags
256
+
257
+ Flags can be combined with `.or` and `.and` conjunctions:
258
+
259
+ ```swift
260
+ // ✅ Strong biometric binding WITH passcode escape hatch
261
+ let access = SecAccessControlCreateWithFlags(
262
+ nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
263
+ [.biometryCurrentSet, .or, .devicePasscode], nil
264
+ )
265
+ ```
266
+
267
+ This combination is practical for most production apps — strong biometric security with a recovery path when biometrics become unavailable.
268
+
269
+ ---
270
+
271
+ ## Biometric Availability Checks and Graceful Degradation
272
+
273
+ ### Incomplete Availability Check
274
+
275
+ ```swift
276
+ // ❌ WRONG: Ignores WHY biometrics failed — user gets no guidance
277
+ func checkBiometrics() -> Bool {
278
+ let context = LAContext()
279
+ var error: NSError?
280
+ return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
281
+ }
282
+ ```
283
+
284
+ ### Complete Availability Evaluation
285
+
286
+ ```swift
287
+ // ✅ CORRECT: Evaluates every failure reason with actionable guidance
288
+ enum BiometricAvailability {
289
+ case available(type: LABiometryType)
290
+ case notEnrolled // Hardware exists, no biometrics registered
291
+ case lockedOut // Too many failed attempts — passcode required
292
+ case notAvailable // No hardware or restricted by MDM
293
+ case passcodeNotSet // No device passcode — biometrics require one
294
+ }
295
+
296
+ func evaluateBiometricAvailability() -> BiometricAvailability {
297
+ let context = LAContext()
298
+ var error: NSError?
299
+
300
+ if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
301
+ return .available(type: context.biometryType)
302
+ }
303
+
304
+ guard let laError = error as? LAError else { return .notAvailable }
305
+
306
+ switch laError.code {
307
+ case .biometryNotEnrolled:
308
+ return .notEnrolled // → "Enable Face ID in Settings"
309
+ case .biometryLockout:
310
+ return .lockedOut // → Prompt passcode to reset sensor
311
+ case .biometryNotAvailable:
312
+ return .notAvailable // → Hide biometric UI entirely
313
+ case .passcodeNotSet:
314
+ return .passcodeNotSet // → "Set a passcode to use Face ID"
315
+ default:
316
+ return .notAvailable
317
+ }
318
+ }
319
+ ```
320
+
321
+ ### Graceful Degradation Flow
322
+
323
+ ```swift
324
+ // ✅ Degrades from biometric → passcode → password login
325
+ func authenticateWithGracefulDegradation() async throws -> Data {
326
+ let availability = evaluateBiometricAvailability()
327
+
328
+ switch availability {
329
+ case .available:
330
+ return try retrieveSecretWithBiometric(account: "user", service: "com.app.auth")
331
+
332
+ case .lockedOut:
333
+ // Biometrics locked — use .userPresence item for passcode fallback
334
+ return try retrieveSecretWithPasscodeFallback(account: "user", service: "com.app.auth")
335
+
336
+ case .notEnrolled:
337
+ throw BiometricKeychainError.biometryNotAvailable(
338
+ reason: "Please enable Face ID in Settings > Face ID & Passcode"
339
+ )
340
+
341
+ case .notAvailable, .passcodeNotSet:
342
+ throw BiometricKeychainError.biometryNotAvailable(
343
+ reason: "Biometric authentication is not available on this device"
344
+ )
345
+ }
346
+ }
347
+ ```
348
+
349
+ **Critical:** Failing to handle `.biometryLockout` strands users. The app cannot bypass this lockout — the user must successfully enter their device passcode to re-enable the biometric sensor. If your app has no fallback, users are permanently locked out until they leave your app and unlock with passcode.
350
+
351
+ **Important:** `canEvaluatePolicy()` is strictly for pre-flight UI decisions (showing or hiding a "Sign in with Face ID" button). It must never be used as a security control.
352
+
353
+ ---
354
+
355
+ ## Enrollment Change Detection
356
+
357
+ When using `.biometryCurrentSet`, detect enrollment changes proactively so your app can guide the user through re-enrollment rather than presenting a cryptic keychain error.
358
+
359
+ ```swift
360
+ // ✅ Detect biometric enrollment changes via domainState
361
+ class BiometricEnrollmentMonitor {
362
+ private let domainStateKey = "com.app.biometric.domainState"
363
+
364
+ /// Call after successful biometric setup to snapshot current enrollment
365
+ func saveCurrentEnrollment() {
366
+ let context = LAContext()
367
+ guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) else { return }
368
+
369
+ // domainState changes whenever biometric enrollment changes
370
+ if let domainState = context.evaluatedPolicyDomainState {
371
+ UserDefaults.standard.set(domainState, forKey: domainStateKey)
372
+ }
373
+ }
374
+
375
+ /// Call on app launch or before biometric retrieval
376
+ func hasEnrollmentChanged() -> Bool {
377
+ let context = LAContext()
378
+ guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) else {
379
+ return true // Can't evaluate — treat as changed
380
+ }
381
+
382
+ guard let currentState = context.evaluatedPolicyDomainState,
383
+ let savedState = UserDefaults.standard.data(forKey: domainStateKey) else {
384
+ return true // No saved state — first run or data cleared
385
+ }
386
+
387
+ return currentState != savedState
388
+ }
389
+ }
390
+ ```
391
+
392
+ **Note:** `evaluatedPolicyDomainState` is an opaque `Data` blob. It changes whenever biometric enrollment changes but reveals no information about the biometrics themselves. Store it in `UserDefaults` (not keychain) since it is not sensitive — it's only used for change detection.
393
+
394
+ ---
395
+
396
+ ## Thread Safety and async/await
397
+
398
+ `SecItemCopyMatching` with biometric access control **blocks the calling thread** until the user completes authentication. Never run it on `@MainActor` or the main thread.
399
+
400
+ `LAContext.evaluatePolicy`'s legacy completion handler executes on a private queue in an unspecified threading context. Direct UI updates from this callback cause crashes, especially on iOS 18 where threading strictness increased.
401
+
402
+ ### Actor-Isolated Biometric Keychain (iOS 15+)
403
+
404
+ ```swift
405
+ @available(iOS 15.0, *)
406
+ actor BiometricKeychain {
407
+
408
+ func retrieveSecret(account: String, service: String) async throws -> Data {
409
+ return try await withCheckedThrowingContinuation { continuation in
410
+ DispatchQueue.global(qos: .userInitiated).async {
411
+ let context = LAContext()
412
+ context.localizedReason = "Authenticate to access your account"
413
+
414
+ let query: [String: Any] = [
415
+ kSecClass as String: kSecClassGenericPassword,
416
+ kSecAttrAccount as String: account,
417
+ kSecAttrService as String: service,
418
+ kSecReturnData as String: true,
419
+ kSecMatchLimit as String: kSecMatchLimitOne,
420
+ kSecUseAuthenticationContext as String: context
421
+ ]
422
+
423
+ var result: AnyObject?
424
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
425
+
426
+ switch status {
427
+ case errSecSuccess:
428
+ if let data = result as? Data {
429
+ continuation.resume(returning: data)
430
+ } else {
431
+ continuation.resume(throwing: BiometricKeychainError.dataConversionFailed)
432
+ }
433
+ case errSecUserCanceled, errSecAuthFailed:
434
+ continuation.resume(throwing: BiometricKeychainError.keychainOperationFailed(status: status))
435
+ default:
436
+ continuation.resume(throwing: BiometricKeychainError.keychainOperationFailed(status: status))
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ ```
443
+
444
+ ### SwiftUI ViewModel Integration
445
+
446
+ ```swift
447
+ @MainActor
448
+ class AuthViewModel: ObservableObject {
449
+ @Published var isAuthenticated = false
450
+ @Published var errorMessage: String?
451
+
452
+ private let keychain = BiometricKeychain()
453
+
454
+ func authenticate() {
455
+ Task {
456
+ do {
457
+ let secret = try await keychain.retrieveSecret(
458
+ account: "user_token",
459
+ service: "com.myapp.auth"
460
+ )
461
+ self.isAuthenticated = true
462
+ self.processToken(secret)
463
+ } catch {
464
+ self.errorMessage = error.localizedDescription
465
+ }
466
+ }
467
+ }
468
+ }
469
+ ```
470
+
471
+ **Note on native async:** `LAContext` gained `evaluatePolicy(_:localizedReason:) async throws -> Bool` in iOS 15. However, this is only relevant for the non-security-critical UI gating use case. For the secure keychain pattern, you wrap `SecItemCopyMatching` as shown above — there is no native async overload for SecItem\* APIs.
472
+
473
+ ---
474
+
475
+ ## Secure Enclave-Backed Keys with Biometric Protection
476
+
477
+ For asymmetric key operations (signing, key agreement), combine Secure Enclave key generation with biometric access control via CryptoKit. The private key **never leaves the Secure Enclave** — all operations happen in hardware.
478
+
479
+ ```swift
480
+ // ✅ Secure Enclave P-256 key with biometric protection (WWDC 2019-709)
481
+ let accessControl = SecAccessControlCreateWithFlags(
482
+ nil,
483
+ kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
484
+ [.privateKeyUsage, .biometryCurrentSet],
485
+ nil
486
+ )!
487
+
488
+ let privateKey = try SecureEnclave.P256.Signing.PrivateKey(
489
+ accessControl: accessControl
490
+ )
491
+
492
+ // Signing triggers biometric prompt automatically
493
+ let signature = try privateKey.signature(for: dataToSign)
494
+ ```
495
+
496
+ Frida operates in user-space on the application processor and has zero access to the Secure Enclave's internal state. The Secure Enclave's memory is encrypted with its own AES engine. Even a kernel-level compromise cannot extract the keys.
497
+
498
+ ---
499
+
500
+ ## SDLC Controls — Catching the Anti-Pattern in CI
501
+
502
+ Because AI coding assistants frequently generate the vulnerable `evaluatePolicy` pattern, teams should implement automated detection:
503
+
504
+ **Conceptual SAST rule (`INSECURE_BIOMETRIC_GATE`):** Identify all calls to `LAContext.evaluatePolicy`. If the `success` boolean directly gates access to a resource AND there is no corresponding `SecItemCopyMatching` using a `SecAccessControl` object in the same flow, flag the code.
505
+
506
+ **Security review sign-off criteria:**
507
+
508
+ 1. Zero instances of standalone `LAContext.evaluatePolicy` gating sensitive operations
509
+ 2. Evidence of `SecItemAdd` with `kSecAttrAccessControl` using `ThisDeviceOnly` accessibility
510
+ 3. Documented proof that objection bypass (`ios ui biometrics_bypass`) fails to unlock protected data
511
+ 4. All `LAError` cases handled with graceful degradation
512
+ 5. If `.biometryCurrentSet` is used, a tested re-enrollment recovery flow exists
513
+
514
+ ---
515
+
516
+ ## Dynamic Verification — Proving Bypass Resistance
517
+
518
+ Static code review alone is insufficient. Verification requires dynamic testing:
519
+
520
+ **Test procedure:** On a jailbroken or instrumented device, inject a Frida script to hook `-[LAContext evaluatePolicy:localizedReason:reply:]` and force `success = true`.
521
+
522
+ **Pass criteria:** The app prevents access to protected data despite the manipulated callback. The secret remains locked because `SecAccessControl` + Secure Enclave enforcement is independent of the boolean.
523
+
524
+ **Fail criteria:** The app grants access after the hook forces success. This proves reliance on the vulnerable boolean gate.
525
+
526
+ ---
527
+
528
+ ## Key References
529
+
530
+ - **WWDC 2014 Session 711** — "Keychain and Authentication with Touch ID": Introduced the two trust models (evaluatePolicy vs keychain+ACL)
531
+ - **WWDC 2019 Session 709** — "Cryptography and Your Apps": CryptoKit + Secure Enclave key generation with access control
532
+ - **Apple Platform Security Guide** — Secure Enclave architecture, keychain encryption chain (metadata key + secret key), ACL evaluation in hardware
533
+ - **OWASP MASTG MSTG-AUTH-8** — Biometric authentication must not be event-bound
534
+ - **OWASP MASTG MSTG-AUTH-12** — Integrity of biometric mechanism must be verified
535
+ - **OWASP MASTG MASTG-TEST-0266** — Test for local authentication bypass
536
+ - **objection wiki** — "Understanding the iOS Biometrics Bypass": Confirms attack boundary at SecAccessControl
537
+ - **TN3137** — "On Mac Keychain APIs and implementations" (macOS keychain unification)
538
+
539
+ ---
540
+
541
+ ## Cross-References
542
+
543
+ - `keychain-fundamentals.md` — SecItem CRUD patterns used by the keychain-bound biometric flow
544
+ - `keychain-access-control.md` — `SecAccessControlCreateWithFlags`, accessibility constants, and flag composition rules
545
+ - `secure-enclave.md` — Hardware-backed keys with biometric gating via `SecAccessControl`
546
+ - `common-anti-patterns.md` — Anti-pattern #3 (LAContext-only biometric gate)
547
+ - `credential-storage-patterns.md` — Biometric protection for high-value credentials (OAuth tokens, API keys)
548
+ - `testing-security-code.md` — Protocol-based mocking for biometric flows, LAContext test strategies
549
+ - `compliance-owasp-mapping.md` — M3 (Insecure Authentication/Authorization) biometric requirements
550
+
551
+ ---
552
+
553
+ ## Summary Checklist
554
+
555
+ 1. **No standalone boolean gates** — `LAContext.evaluatePolicy()` is NEVER the sole authentication mechanism for sensitive data; secrets are always bound to keychain + `SecAccessControl`
556
+ 2. **Hardware-gated secrets** — All sensitive data protected by biometrics uses `SecAccessControlCreateWithFlags` with the Secure Enclave enforcing the ACL
557
+ 3. **Correct flag selection** — `.biometryCurrentSet` for high-security (banking, payments); `.biometryAny` for convenience; `.userPresence` for broad compatibility or fallback
558
+ 4. **No kSecAttrAccessible conflict** — `kSecAttrAccessible` and `kSecAttrAccessControl` are never set on the same keychain item
559
+ 5. **ThisDeviceOnly accessibility** — Biometric-gated secrets use `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` or `WhenUnlockedThisDeviceOnly`; never syncable
560
+ 6. **Complete error handling** — All `LAError` codes handled: `.biometryNotEnrolled`, `.biometryLockout`, `.biometryNotAvailable`, `.passcodeNotSet`, `.userCancel`, `.userFallback`
561
+ 7. **Graceful degradation** — App provides fallback path (passcode or password) when biometrics are unavailable or locked out
562
+ 8. **Enrollment change detection** — `evaluatedPolicyDomainState` monitored when using `.biometryCurrentSet`; re-enrollment flow implemented
563
+ 9. **Thread safety** — `SecItemCopyMatching` with biometric ACL never runs on `@MainActor`; actor-isolated or dispatched to background queue
564
+ 10. **Dynamic verification** — objection/Frida bypass test confirms protected data remains inaccessible when `evaluatePolicy` callback is hooked
565
+ 11. **SAST/linting** — CI pipeline includes rule to flag standalone `evaluatePolicy` without corresponding `SecAccessControl` keychain operations