@mmerterden/multi-agent-pipeline 8.6.1 → 10.0.6

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 (928) hide show
  1. package/CHANGELOG.md +544 -2484
  2. package/README.md +117 -138
  3. package/docs/features.md +1 -1
  4. package/index.js +8 -10
  5. package/install/_adapters.mjs +5 -1
  6. package/install/_common.mjs +63 -0
  7. package/install/claude.mjs +14 -14
  8. package/install/copilot.mjs +14 -8
  9. package/install/index.mjs +85 -19
  10. package/install/templates/claude-hooks.json +18 -0
  11. package/install/templates/copilot-instructions.md +3 -3
  12. package/package.json +21 -6
  13. package/pipeline/adapters/_base.mjs +366 -14
  14. package/pipeline/adapters/antigravity.mjs +140 -0
  15. package/pipeline/adapters/codex.mjs +159 -0
  16. package/pipeline/adapters/copilot-chat-orchestration.mjs +148 -0
  17. package/pipeline/adapters/copilot-chat.mjs +34 -68
  18. package/pipeline/adapters/cursor-orchestration.mjs +152 -0
  19. package/pipeline/adapters/cursor.mjs +49 -90
  20. package/pipeline/agents/android-architect.md +5 -5
  21. package/pipeline/agents/backend-architect.md +4 -4
  22. package/pipeline/agents/code-reviewer.md +10 -10
  23. package/pipeline/agents/dev-critic.md +17 -17
  24. package/pipeline/agents/explorer.md +3 -3
  25. package/pipeline/agents/ios-architect.md +4 -4
  26. package/pipeline/agents/security-auditor.md +12 -12
  27. package/pipeline/agents/task-clarifier.md +18 -18
  28. package/pipeline/claude-md-template.md +3 -3
  29. package/pipeline/commands/archive-guard.md +3 -3
  30. package/pipeline/commands/figma-to-swiftui.md +10 -10
  31. package/pipeline/commands/multi-agent/_account-picker.md +13 -9
  32. package/pipeline/commands/multi-agent/_dev-context.md +15 -15
  33. package/pipeline/commands/multi-agent/_input-parser.md +4 -4
  34. package/pipeline/commands/multi-agent/_repo-picker.md +9 -9
  35. package/pipeline/commands/multi-agent/analysis-resolve.md +129 -0
  36. package/pipeline/commands/multi-agent/analysis.md +667 -0
  37. package/pipeline/commands/multi-agent/autopilot.md +22 -22
  38. package/pipeline/commands/multi-agent/build-optimize.md +77 -0
  39. package/pipeline/commands/multi-agent/channels.md +96 -96
  40. package/pipeline/commands/multi-agent/delete.md +19 -17
  41. package/pipeline/commands/multi-agent/dev-autopilot.md +23 -23
  42. package/pipeline/commands/multi-agent/dev-local-autopilot.md +23 -23
  43. package/pipeline/commands/multi-agent/dev-local.md +25 -22
  44. package/pipeline/commands/multi-agent/dev.md +49 -49
  45. package/pipeline/commands/multi-agent/diff-explain.md +4 -4
  46. package/pipeline/commands/multi-agent/garbage-collect.md +58 -0
  47. package/pipeline/commands/multi-agent/help.md +75 -66
  48. package/pipeline/commands/multi-agent/issue.md +3 -3
  49. package/pipeline/commands/multi-agent/jira.md +12 -12
  50. package/pipeline/commands/multi-agent/kill.md +6 -6
  51. package/pipeline/commands/multi-agent/language.md +12 -12
  52. package/pipeline/commands/multi-agent/local-autopilot.md +34 -34
  53. package/pipeline/commands/multi-agent/local.md +24 -25
  54. package/pipeline/commands/multi-agent/log.md +6 -6
  55. package/pipeline/commands/multi-agent/manual-test.md +3 -3
  56. package/pipeline/commands/multi-agent/prune-logs.md +60 -0
  57. package/pipeline/commands/multi-agent/purge.md +10 -7
  58. package/pipeline/commands/multi-agent/refactor.md +9 -9
  59. package/pipeline/commands/multi-agent/refs/analysis-template.md +1062 -0
  60. package/pipeline/commands/multi-agent/refs/android-guide.md +15 -13
  61. package/pipeline/commands/multi-agent/refs/audit-guide.md +20 -20
  62. package/pipeline/commands/multi-agent/refs/backend-guide.md +9 -9
  63. package/pipeline/commands/multi-agent/refs/channels/confluence.md +17 -17
  64. package/pipeline/commands/multi-agent/refs/channels/issue-comment.md +30 -30
  65. package/pipeline/commands/multi-agent/refs/channels/jira.md +15 -15
  66. package/pipeline/commands/multi-agent/refs/channels/pr-review-actions.md +19 -17
  67. package/pipeline/commands/multi-agent/refs/channels/pr.md +22 -22
  68. package/pipeline/commands/multi-agent/refs/channels/wiki.md +19 -19
  69. package/pipeline/commands/multi-agent/refs/component-dispatch.md +11 -11
  70. package/pipeline/commands/multi-agent/refs/conventions-defaults.md +179 -0
  71. package/pipeline/commands/multi-agent/refs/cross-cli-contract.md +35 -33
  72. package/pipeline/commands/multi-agent/refs/features/dev-critic.md +5 -5
  73. package/pipeline/commands/multi-agent/refs/features/external-context-injection.md +6 -6
  74. package/pipeline/commands/multi-agent/refs/features/model-fallback.md +73 -0
  75. package/pipeline/commands/multi-agent/refs/features/plan-todos.md +1 -1
  76. package/pipeline/commands/multi-agent/refs/features/prior-fix-detection.md +4 -4
  77. package/pipeline/commands/multi-agent/refs/features/repo-map.md +6 -6
  78. package/pipeline/commands/multi-agent/refs/features/shadow-git.md +2 -2
  79. package/pipeline/commands/multi-agent/refs/frontend-guide.md +16 -16
  80. package/pipeline/commands/multi-agent/refs/issue-jira-triad.md +18 -18
  81. package/pipeline/commands/multi-agent/refs/keychain.md +18 -8
  82. package/pipeline/commands/multi-agent/refs/knowledge.md +9 -9
  83. package/pipeline/commands/multi-agent/refs/multi-repo-integration-build.md +19 -19
  84. package/pipeline/commands/multi-agent/refs/phases/log-format.md +29 -9
  85. package/pipeline/commands/multi-agent/refs/phases/modes.md +33 -33
  86. package/pipeline/commands/multi-agent/refs/phases/operations.md +11 -11
  87. package/pipeline/commands/multi-agent/refs/phases/phase-0-init.md +93 -57
  88. package/pipeline/commands/multi-agent/refs/phases/phase-1-analysis.md +59 -28
  89. package/pipeline/commands/multi-agent/refs/phases/phase-2-planning.md +115 -63
  90. package/pipeline/commands/multi-agent/refs/phases/phase-3-dev.md +99 -36
  91. package/pipeline/commands/multi-agent/refs/phases/phase-4-review.md +160 -63
  92. package/pipeline/commands/multi-agent/refs/phases/phase-5-test.md +33 -18
  93. package/pipeline/commands/multi-agent/refs/phases/phase-6-commit.md +45 -43
  94. package/pipeline/commands/multi-agent/refs/phases/phase-7-report.md +54 -28
  95. package/pipeline/commands/multi-agent/refs/phases.md +17 -17
  96. package/pipeline/commands/multi-agent/refs/picker-contract.md +65 -0
  97. package/pipeline/commands/multi-agent/refs/progress-contract.md +37 -21
  98. package/pipeline/commands/multi-agent/refs/rules.md +83 -25
  99. package/pipeline/commands/multi-agent/refs/swiftui-guide.md +32 -30
  100. package/pipeline/commands/multi-agent/refs/tracker-contract.md +54 -30
  101. package/pipeline/commands/multi-agent/refs/wiki-capture.md +36 -33
  102. package/pipeline/commands/multi-agent/resume.md +9 -9
  103. package/pipeline/commands/multi-agent/review.md +24 -24
  104. package/pipeline/commands/multi-agent/scan.md +10 -10
  105. package/pipeline/commands/multi-agent/search.md +8 -8
  106. package/pipeline/commands/multi-agent/setup.md +111 -84
  107. package/pipeline/commands/multi-agent/stack.md +5 -5
  108. package/pipeline/commands/multi-agent/status.md +5 -5
  109. package/pipeline/commands/multi-agent/sync.md +123 -111
  110. package/pipeline/commands/multi-agent/test.md +6 -6
  111. package/pipeline/commands/multi-agent/update.md +1 -1
  112. package/pipeline/commands/multi-agent.md +66 -60
  113. package/pipeline/commands/sim-test.md +14 -14
  114. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +1 -1
  115. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +2 -2
  116. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +2 -2
  117. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +1 -1
  118. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +2 -2
  119. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +3 -3
  120. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +4 -4
  121. package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +1 -1
  122. package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +1 -1
  123. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +29 -0
  124. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +42 -0
  125. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +20 -0
  126. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +15 -0
  127. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +14 -0
  128. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +12 -0
  129. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +29 -0
  130. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +40 -0
  131. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +20 -0
  132. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +15 -0
  133. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +14 -0
  134. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +12 -0
  135. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +29 -0
  136. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +42 -0
  137. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +28 -0
  138. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +27 -0
  139. package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +14 -0
  140. package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +12 -0
  141. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +29 -0
  142. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +41 -0
  143. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +12 -0
  144. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +6 -0
  145. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +14 -0
  146. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +12 -0
  147. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +29 -0
  148. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +42 -0
  149. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +28 -0
  150. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +27 -0
  151. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +14 -0
  152. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +12 -0
  153. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +25 -0
  154. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +31 -0
  155. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +12 -0
  156. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +18 -0
  157. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +14 -0
  158. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +12 -0
  159. package/pipeline/eval/golden-tasks/README.md +14 -14
  160. package/pipeline/eval/intent-cases.json +40 -0
  161. package/pipeline/eval/run-metrics-fixture.json +46 -0
  162. package/pipeline/eval/triage/01-empty-findings/notes.md +1 -1
  163. package/pipeline/eval/triage/02-real-blocker/notes.md +2 -2
  164. package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +1 -1
  165. package/pipeline/eval/triage/04-false-positive-reject/notes.md +1 -1
  166. package/pipeline/eval/triage/05-mixed-classification/notes.md +2 -2
  167. package/pipeline/eval/triage/06-severity-mismatch/notes.md +2 -2
  168. package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +1 -1
  169. package/pipeline/eval/triage/08-style-misclassified/notes.md +1 -1
  170. package/pipeline/eval/triage/09-cascading-finding/notes.md +2 -2
  171. package/pipeline/eval/triage/10-deferred-crossref/notes.md +2 -2
  172. package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +3 -3
  173. package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +2 -2
  174. package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +5 -5
  175. package/pipeline/eval/triage/README.md +4 -4
  176. package/pipeline/lib/account-resolver.sh +3 -3
  177. package/pipeline/lib/ask-choice.sh +98 -0
  178. package/pipeline/lib/channels-multi-repo.sh +3 -3
  179. package/pipeline/lib/classify-intent.sh +110 -0
  180. package/pipeline/lib/context-link-extractor.sh +3 -3
  181. package/pipeline/lib/credential-store-resolver.sh +3 -3
  182. package/pipeline/lib/credential-store.sh +9 -5
  183. package/pipeline/lib/extract-conventions.sh +1034 -0
  184. package/pipeline/lib/fetch-confluence.sh +3 -3
  185. package/pipeline/lib/fetch-crashlytics.sh +5 -5
  186. package/pipeline/lib/fetch-fortify.sh +5 -21
  187. package/pipeline/lib/fetch-swagger.sh +5 -5
  188. package/pipeline/lib/figma-screenshot.sh +536 -0
  189. package/pipeline/lib/issue-fetcher.sh +46 -20
  190. package/pipeline/lib/md2confluence-v3.py +1076 -0
  191. package/pipeline/lib/multi-repo-pipeline.sh +13 -22
  192. package/pipeline/lib/plan-todos.sh +7 -7
  193. package/pipeline/lib/post-pr-review.sh +53 -21
  194. package/pipeline/lib/repo-cache.sh +5 -5
  195. package/pipeline/lib/review-watch.sh +17 -13
  196. package/pipeline/lib/shadow-git.sh +7 -7
  197. package/pipeline/lib/submodule-detector.sh +3 -3
  198. package/pipeline/lib/vercel-deploy.sh +28 -15
  199. package/pipeline/preferences-template.json +21 -4
  200. package/pipeline/rules/app-store-guidelines.md +2 -2
  201. package/pipeline/rules/code-style.md +6 -6
  202. package/pipeline/rules/figma-pipeline.md +100 -2
  203. package/pipeline/rules/kotlin-android.md +8 -8
  204. package/pipeline/rules/security.md +4 -4
  205. package/pipeline/rules/tdd.md +1 -1
  206. package/pipeline/rules/testing.md +5 -5
  207. package/pipeline/schemas/agent-state.schema.json +55 -20
  208. package/pipeline/schemas/analysis-output.schema.json +7 -2
  209. package/pipeline/schemas/analysis-spec.schema.json +484 -0
  210. package/pipeline/schemas/clarify-output.schema.json +5 -5
  211. package/pipeline/schemas/conventions-output.schema.json +70 -0
  212. package/pipeline/schemas/dev-critic-output.schema.json +2 -2
  213. package/pipeline/schemas/diff-risk.schema.json +3 -3
  214. package/pipeline/schemas/figma-project-config.schema.json +3 -3
  215. package/pipeline/schemas/learnings-ledger.schema.json +39 -0
  216. package/pipeline/schemas/migrations/README.md +2 -2
  217. package/pipeline/schemas/migrations/figma-config-1.0.0-to-2.0.0.mjs +5 -5
  218. package/pipeline/schemas/migrations/prefs-2.0.0-to-2.1.0.mjs +3 -3
  219. package/pipeline/schemas/migrations/prefs-2.1.0-to-2.2.0.mjs +4 -4
  220. package/pipeline/schemas/migrations/prefs-2.2.0-to-2.3.0.mjs +5 -5
  221. package/pipeline/schemas/migrations/state-2.0.0-to-2.1.0.mjs +3 -3
  222. package/pipeline/schemas/plan-todos.schema.json +4 -4
  223. package/pipeline/schemas/planning-output.schema.json +3 -3
  224. package/pipeline/schemas/prefs.schema.json +97 -13
  225. package/pipeline/schemas/reviewer-output.schema.json +7 -3
  226. package/pipeline/schemas/test-gap.schema.json +1 -1
  227. package/pipeline/schemas/token-budget.json +8 -8
  228. package/pipeline/schemas/triage-corpus.schema.json +1 -1
  229. package/pipeline/schemas/triage-output.schema.json +44 -6
  230. package/pipeline/scripts/README.md +64 -64
  231. package/pipeline/scripts/aggregate-metrics.mjs +55 -16
  232. package/pipeline/scripts/audit-log-rotate.sh +3 -3
  233. package/pipeline/scripts/audit-log.sh +20 -7
  234. package/pipeline/scripts/benchmark-phase-0.sh +6 -6
  235. package/pipeline/scripts/build-skills-index.mjs +15 -15
  236. package/pipeline/scripts/check-md-links.mjs +59 -0
  237. package/pipeline/scripts/classify-plan-safety.mjs +24 -18
  238. package/pipeline/scripts/cost-budget-check.mjs +160 -0
  239. package/pipeline/scripts/cost-table.json +23 -13
  240. package/pipeline/scripts/diff-explain.mjs +12 -12
  241. package/pipeline/scripts/diff-risk-score.mjs +18 -17
  242. package/pipeline/scripts/eval-golden-tasks-live.mjs +13 -10
  243. package/pipeline/scripts/eval-golden-tasks.mjs +3 -14
  244. package/pipeline/scripts/eval-intent.mjs +103 -0
  245. package/pipeline/scripts/eval-triage.mjs +3 -3
  246. package/pipeline/scripts/evidence-gate.mjs +155 -0
  247. package/pipeline/scripts/fixtures/install-layout.tsv +9 -9
  248. package/pipeline/scripts/gc-tmp.sh +102 -0
  249. package/pipeline/scripts/gen-mode-dispatch.mjs +27 -21
  250. package/pipeline/scripts/gen-skills-index.mjs +6 -6
  251. package/pipeline/scripts/github-ssh-setup.sh +1 -1
  252. package/pipeline/scripts/keychain-save.sh +1 -1
  253. package/pipeline/scripts/keychain.py +6 -6
  254. package/pipeline/scripts/learnings-ledger.mjs +284 -0
  255. package/pipeline/scripts/lint-skills.mjs +80 -0
  256. package/pipeline/scripts/log-metric.sh +18 -9
  257. package/pipeline/scripts/match-skills.mjs +13 -8
  258. package/pipeline/scripts/memory-load.sh +3 -3
  259. package/pipeline/scripts/memory-save.sh +5 -5
  260. package/pipeline/scripts/migrate-prefs.mjs +17 -17
  261. package/pipeline/scripts/migrate-state.mjs +12 -12
  262. package/pipeline/scripts/output-quality-check.sh +7 -7
  263. package/pipeline/scripts/phase-banner.sh +5 -5
  264. package/pipeline/scripts/phase-tracker.sh +90 -53
  265. package/pipeline/scripts/pre-commit-check.sh +45 -5
  266. package/pipeline/scripts/pre-push-check.sh +7 -7
  267. package/pipeline/scripts/prune-logs.sh +118 -0
  268. package/pipeline/scripts/render-agent-log-cost.sh +55 -18
  269. package/pipeline/scripts/render-cost-summary.sh +9 -9
  270. package/pipeline/scripts/render-work-summary.sh +4 -4
  271. package/pipeline/scripts/repo-map.mjs +9 -9
  272. package/pipeline/scripts/run-aggregator.mjs +7 -6
  273. package/pipeline/scripts/run-metrics.mjs +129 -0
  274. package/pipeline/scripts/run-smokes.mjs +76 -0
  275. package/pipeline/scripts/scan-skills.sh +11 -11
  276. package/pipeline/scripts/search-logs.sh +8 -8
  277. package/pipeline/scripts/sign-skills.sh +2 -2
  278. package/pipeline/scripts/smoke-adapters.sh +79 -10
  279. package/pipeline/scripts/smoke-add-detail.sh +5 -5
  280. package/pipeline/scripts/smoke-agent-log-cost.sh +85 -6
  281. package/pipeline/scripts/smoke-agent-model-routing.sh +3 -3
  282. package/pipeline/scripts/smoke-ask-choice.sh +42 -0
  283. package/pipeline/scripts/smoke-bitbucket-contract.sh +19 -3
  284. package/pipeline/scripts/smoke-changelog-version.sh +47 -0
  285. package/pipeline/scripts/smoke-channels-flow.sh +1 -1
  286. package/pipeline/scripts/smoke-ci-workflows.sh +5 -5
  287. package/pipeline/scripts/smoke-clarify.sh +3 -3
  288. package/pipeline/scripts/smoke-commands-skills-parity.sh +4 -4
  289. package/pipeline/scripts/smoke-community-gates.sh +75 -0
  290. package/pipeline/scripts/smoke-compliance-skills.sh +5 -5
  291. package/pipeline/scripts/smoke-cost-budget.sh +70 -0
  292. package/pipeline/scripts/smoke-cost-summary.sh +4 -4
  293. package/pipeline/scripts/smoke-cross-cli-behavior.sh +50 -9
  294. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +5 -5
  295. package/pipeline/scripts/smoke-delete-flow.sh +5 -5
  296. package/pipeline/scripts/smoke-dev-critic.sh +2 -2
  297. package/pipeline/scripts/smoke-diff-explain.sh +22 -3
  298. package/pipeline/scripts/smoke-diff-risk.sh +1 -1
  299. package/pipeline/scripts/smoke-dynamic-skill-loading.sh +1 -1
  300. package/pipeline/scripts/smoke-eval-live.sh +4 -4
  301. package/pipeline/scripts/smoke-evidence-gate.sh +93 -0
  302. package/pipeline/scripts/smoke-existing-discovery-gate.sh +1 -1
  303. package/pipeline/scripts/smoke-extract-conventions.sh +163 -0
  304. package/pipeline/scripts/smoke-figma-android-parity.sh +1 -1
  305. package/pipeline/scripts/smoke-figma-credential-store.sh +3 -3
  306. package/pipeline/scripts/smoke-figma-cross-cli-inventory.sh +12 -12
  307. package/pipeline/scripts/smoke-figma-dispatch.sh +5 -5
  308. package/pipeline/scripts/smoke-figma-sync.sh +1 -1
  309. package/pipeline/scripts/smoke-gate-hooks.sh +56 -0
  310. package/pipeline/scripts/smoke-gc-tmp.sh +84 -0
  311. package/pipeline/scripts/smoke-identity-isolation.sh +7 -7
  312. package/pipeline/scripts/smoke-install-layout.sh +10 -10
  313. package/pipeline/scripts/smoke-intent-guard.sh +86 -0
  314. package/pipeline/scripts/smoke-issue-comment-template.sh +3 -3
  315. package/pipeline/scripts/smoke-issue-jira-triad.sh +1 -1
  316. package/pipeline/scripts/smoke-keychain.sh +6 -6
  317. package/pipeline/scripts/smoke-language-axis.sh +2 -2
  318. package/pipeline/scripts/smoke-learnings-ledger.sh +86 -0
  319. package/pipeline/scripts/smoke-lib-scripts.sh +2 -2
  320. package/pipeline/scripts/smoke-mcp-gate.sh +68 -0
  321. package/pipeline/scripts/smoke-md-links.sh +8 -0
  322. package/pipeline/scripts/smoke-md2confluence.sh +126 -0
  323. package/pipeline/scripts/smoke-metrics-cache-ratio.sh +72 -0
  324. package/pipeline/scripts/smoke-migrate-state.sh +10 -10
  325. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +7 -4
  326. package/pipeline/scripts/smoke-model-fallback.sh +80 -0
  327. package/pipeline/scripts/smoke-multi-repo-integration.sh +3 -3
  328. package/pipeline/scripts/smoke-multi-repo-worktree.sh +1 -1
  329. package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +115 -0
  330. package/pipeline/scripts/smoke-no-token-prompt.sh +31 -15
  331. package/pipeline/scripts/smoke-pat-audit.sh +26 -5
  332. package/pipeline/scripts/smoke-per-repo-memory.sh +1 -1
  333. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +1 -1
  334. package/pipeline/scripts/smoke-phase-6-multi.sh +2 -2
  335. package/pipeline/scripts/smoke-phase-banner.sh +1 -1
  336. package/pipeline/scripts/smoke-phase-tracker.sh +1 -1
  337. package/pipeline/scripts/smoke-phase0-bridge-contract.sh +4 -4
  338. package/pipeline/scripts/smoke-phase4-triage.sh +94 -7
  339. package/pipeline/scripts/smoke-plan-approval-gate.sh +3 -3
  340. package/pipeline/scripts/smoke-plan-safety.sh +1 -1
  341. package/pipeline/scripts/smoke-plan-todos.sh +7 -4
  342. package/pipeline/scripts/smoke-pr-review-actions.sh +2 -2
  343. package/pipeline/scripts/smoke-pre-commit.sh +34 -2
  344. package/pipeline/scripts/smoke-pref-migration.sh +1 -1
  345. package/pipeline/scripts/smoke-prefs-language.sh +5 -5
  346. package/pipeline/scripts/smoke-progress-contract.sh +3 -3
  347. package/pipeline/scripts/smoke-prune-logs.sh +87 -0
  348. package/pipeline/scripts/smoke-push-retry.sh +1 -1
  349. package/pipeline/scripts/smoke-readme-counts.sh +1 -1
  350. package/pipeline/scripts/smoke-repo-map.sh +9 -9
  351. package/pipeline/scripts/smoke-review-watch.sh +12 -0
  352. package/pipeline/scripts/smoke-run-aggregator.sh +7 -7
  353. package/pipeline/scripts/smoke-run-metrics.sh +50 -0
  354. package/pipeline/scripts/smoke-schema-validation.sh +18 -11
  355. package/pipeline/scripts/smoke-search.sh +5 -5
  356. package/pipeline/scripts/smoke-shared-runtime.sh +108 -0
  357. package/pipeline/scripts/smoke-skill-authoring.sh +13 -13
  358. package/pipeline/scripts/smoke-skill-language.sh +4 -4
  359. package/pipeline/scripts/smoke-skill-manifest.sh +2 -2
  360. package/pipeline/scripts/smoke-skill-scan.sh +2 -2
  361. package/pipeline/scripts/smoke-stack-swap.sh +2 -2
  362. package/pipeline/scripts/smoke-subagent-validators.sh +8 -5
  363. package/pipeline/scripts/smoke-sync-adapters.sh +1 -1
  364. package/pipeline/scripts/smoke-sync-delegation.sh +7 -7
  365. package/pipeline/scripts/smoke-sync-parity.sh +1 -1
  366. package/pipeline/scripts/smoke-tasklist-ordering.sh +7 -7
  367. package/pipeline/scripts/smoke-telemetry.sh +1 -1
  368. package/pipeline/scripts/smoke-test-gap.sh +5 -5
  369. package/pipeline/scripts/smoke-token-budget.sh +1 -1
  370. package/pipeline/scripts/smoke-tracker-contract.sh +6 -6
  371. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +9 -1
  372. package/pipeline/scripts/smoke-triage-memory.sh +2 -2
  373. package/pipeline/scripts/smoke-url-enrichment.sh +2 -2
  374. package/pipeline/scripts/smoke-validator-contradiction.sh +1 -1
  375. package/pipeline/scripts/smoke-validator-gates.sh +164 -0
  376. package/pipeline/scripts/smoke-vercel-deploy-redact.sh +11 -11
  377. package/pipeline/scripts/smoke-wiki-integration.sh +2 -2
  378. package/pipeline/scripts/smoke-work-summary.sh +3 -3
  379. package/pipeline/scripts/smoke-worktree-path-convention.sh +4 -4
  380. package/pipeline/scripts/smoke-write-state.sh +2 -2
  381. package/pipeline/scripts/stack-swap.sh +3 -3
  382. package/pipeline/scripts/sync-adapters.mjs +37 -10
  383. package/pipeline/scripts/sync-parity-check.sh +6 -6
  384. package/pipeline/scripts/test-gap-scan.mjs +11 -13
  385. package/pipeline/scripts/token-budget-report.mjs +4 -4
  386. package/pipeline/scripts/triage-memory.mjs +6 -6
  387. package/pipeline/scripts/uninstall.mjs +42 -4
  388. package/pipeline/scripts/update-issue-progress.sh +2 -2
  389. package/pipeline/scripts/validate-analysis.mjs +19 -21
  390. package/pipeline/scripts/validate-diff-risk.mjs +4 -4
  391. package/pipeline/scripts/validate-planning.mjs +3 -3
  392. package/pipeline/scripts/validate-reviewer.mjs +4 -4
  393. package/pipeline/scripts/validate-schemas.mjs +4 -4
  394. package/pipeline/scripts/validate-test-gap.mjs +4 -4
  395. package/pipeline/scripts/validate-triage.mjs +68 -9
  396. package/pipeline/scripts/verify-skills.sh +7 -7
  397. package/pipeline/scripts/write-state.mjs +49 -11
  398. package/pipeline/skills/.skill-manifest.json +245 -149
  399. package/pipeline/skills/.skills-index.json +236 -47
  400. package/pipeline/skills/figma-android/README.md +5 -5
  401. package/pipeline/skills/figma-android/figma-component-code-connect/SKILL.md +3 -3
  402. package/pipeline/skills/figma-android/figma-component-implement/SKILL.md +8 -8
  403. package/pipeline/skills/figma-android/figma-component-test/SKILL.md +4 -4
  404. package/pipeline/skills/figma-android/figma-component-wiki/SKILL.md +5 -5
  405. package/pipeline/skills/figma-android/figma-to-component/SKILL.md +14 -14
  406. package/pipeline/skills/figma-common/README.md +29 -29
  407. package/pipeline/skills/figma-common/figma-cli-iterate/SKILL.md +20 -15
  408. package/pipeline/skills/figma-common/figma-cli-iterate-mend/SKILL.md +35 -30
  409. package/pipeline/skills/figma-common/figma-cli-lean-iterate/SKILL.md +35 -30
  410. package/pipeline/skills/figma-common/figma-cli-skip/SKILL.md +20 -20
  411. package/pipeline/skills/figma-common/figma-commit/COMMON_REBASE.md +32 -32
  412. package/pipeline/skills/figma-common/figma-commit/REVIEW.md +9 -9
  413. package/pipeline/skills/figma-common/figma-commit/SKILL.md +25 -20
  414. package/pipeline/skills/figma-common/figma-component-confluence-sync/SKILL.md +11 -6
  415. package/pipeline/skills/figma-common/figma-component-start/SKILL.md +30 -25
  416. package/pipeline/skills/figma-common/figma-component-status-update/SKILL.md +9 -4
  417. package/pipeline/skills/figma-common/figma-fix/SKILL.md +27 -22
  418. package/pipeline/skills/figma-common/figma-form-integration/SKILL.md +38 -38
  419. package/pipeline/skills/figma-common/figma-issue/SKILL.md +39 -34
  420. package/pipeline/skills/figma-common/figma-iterate/SKILL.md +20 -15
  421. package/pipeline/skills/figma-common/figma-iteration-commit/SKILL.md +44 -39
  422. package/pipeline/skills/figma-common/figma-mend/SKILL.md +6 -6
  423. package/pipeline/skills/figma-common/figma-price-integration/SKILL.md +30 -30
  424. package/pipeline/skills/figma-common/figma-remote-mcp-auth/SKILL.md +1 -1
  425. package/pipeline/skills/figma-common/figma-review/SKILL.md +31 -26
  426. package/pipeline/skills/figma-common/figma-setup/SKILL.md +11 -11
  427. package/pipeline/skills/figma-common/figma-setup/scripts/fetch-mcp-token.py +5 -5
  428. package/pipeline/skills/figma-common/figma-skip/SKILL.md +6 -6
  429. package/pipeline/skills/figma-common/figma-ui-patterns/SKILL.md +12 -12
  430. package/pipeline/skills/figma-common/figma-utility/SKILL.md +4 -4
  431. package/pipeline/skills/figma-common/figma-utility/scripts/figma-utility.py +1 -1
  432. package/pipeline/skills/figma-common/figma-validate/SKILL.md +48 -48
  433. package/pipeline/skills/figma-common/performance-iteration-commit-all/SKILL.md +42 -37
  434. package/pipeline/skills/figma-common/performance-review-next/SKILL.md +23 -18
  435. package/pipeline/skills/figma-common/performance-start/SKILL.md +52 -47
  436. package/pipeline/skills/figma-common/performance-swiftui/SKILL.md +68 -68
  437. package/pipeline/skills/figma-common/performance-tour/SKILL.md +42 -37
  438. package/pipeline/skills/figma-ios/REVIEW_CHECKLIST.md +16 -16
  439. package/pipeline/skills/figma-ios/figma-component-code-connect/SKILL.md +15 -15
  440. package/pipeline/skills/figma-ios/figma-component-implement/SKILL.md +9 -9
  441. package/pipeline/skills/figma-ios/figma-component-test/SKILL.md +15 -15
  442. package/pipeline/skills/figma-ios/figma-component-wiki/SKILL.md +18 -18
  443. package/pipeline/skills/figma-ios/figma-to-component/SKILL.md +38 -38
  444. package/pipeline/skills/figma-ios/figma-to-component/halt-return-protocol.md +2 -2
  445. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-0-init.md +12 -12
  446. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1-gathering.md +5 -5
  447. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1.5-existing-discovery.md +19 -19
  448. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2-orchestrator.md +25 -25
  449. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2a-testing-identifiers.md +7 -7
  450. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2b-localization.md +6 -6
  451. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2c-accessibility.md +38 -38
  452. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2d-analytics.md +3 -3
  453. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3-orchestrator.md +29 -29
  454. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3a-location.md +6 -6
  455. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3b-tokens.md +3 -3
  456. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3c-nested.md +12 -12
  457. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3d-patterns.md +57 -57
  458. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3e-assets.md +5 -5
  459. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3f-utilities.md +6 -6
  460. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3g-property-coverage.md +10 -10
  461. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3h-variant-config.md +16 -16
  462. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4-orchestrator.md +23 -23
  463. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4a-configuration.md +26 -26
  464. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4b-view.md +43 -43
  465. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4c-documentation.md +17 -17
  466. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4d-preview.md +19 -19
  467. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4e-modifiers.md +15 -15
  468. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5-orchestrator.md +39 -39
  469. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5a-viewinspector.md +7 -7
  470. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5b-snapshot.md +29 -29
  471. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5c-unit.md +9 -9
  472. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-6-code-connect.md +31 -31
  473. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7-wiki.md +5 -5
  474. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-confluence-generate.md +18 -18
  475. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-wiki-generate.md +16 -16
  476. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-8-cleanup.md +2 -2
  477. package/pipeline/skills/figma-ios/figma-to-component/reference/accessibility.md +1 -1
  478. package/pipeline/skills/figma-ios/figma-to-component/reference/code-connect.md +49 -49
  479. package/pipeline/skills/figma-ios/figma-to-component/reference/figma-to-swiftui-effects.md +8 -8
  480. package/pipeline/skills/figma-ios/figma-to-component/reference/halt-return-protocol.md +2 -2
  481. package/pipeline/skills/figma-ios/figma-to-component/reference/macros.md +9 -9
  482. package/pipeline/skills/figma-ios/figma-to-component/reference/missing-tokens.md +4 -4
  483. package/pipeline/skills/figma-ios/figma-to-component/reference/orchestrator-discipline.md +10 -10
  484. package/pipeline/skills/figma-ios/figma-to-component/reference/remote-mcp-script.md +5 -5
  485. package/pipeline/skills/figma-ios/figma-to-component/reference/rest-api-script.md +11 -11
  486. package/pipeline/skills/figma-ios/figma-to-component/reference/scripts-inventory.md +14 -14
  487. package/pipeline/skills/figma-ios/figma-to-component/reference/snapshot-testing.md +2 -2
  488. package/pipeline/skills/figma-ios/figma-to-component/reference/subcomponent-graph.md +4 -4
  489. package/pipeline/skills/figma-ios/figma-to-component/reference/testing-identifiers-naming.md +6 -6
  490. package/pipeline/skills/figma-ios/figma-to-component/reference/tools.md +9 -9
  491. package/pipeline/skills/figma-ios/figma-to-component/reference/viewinspector.md +1 -1
  492. package/pipeline/skills/figma-ios/figma-to-component/reference/wiki-to-confluence-mapping.md +1 -1
  493. package/pipeline/skills/figma-ios/figma-to-component/scripts/apply-author-login-map.py +5 -5
  494. package/pipeline/skills/figma-ios/figma-to-component/scripts/backfill-status.py +18 -18
  495. package/pipeline/skills/figma-ios/figma-to-component/scripts/build-author-registry.py +4 -4
  496. package/pipeline/skills/figma-ios/figma-to-component/scripts/bulk-sync-issues.py +4 -4
  497. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-data-gather.py +1 -1
  498. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-publish.sh +3 -3
  499. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status-upload.py +18 -18
  500. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status.py +4 -4
  501. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-data-gather.py +5 -5
  502. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-page-ids.example.json +9 -0
  503. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-publish.py +3 -3
  504. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-subcomponent-graph.py +1 -1
  505. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-update.py +5 -5
  506. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/issue_sync_propagate.py +1 -1
  507. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/registry_writer.py +4 -4
  508. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update.py +1 -1
  509. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_registry_writer.py +3 -3
  510. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_issue.py +1 -1
  511. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue_gh.py +1 -1
  512. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase1-gather.py +12 -12
  513. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase2-finalize.py +3 -3
  514. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase3-scripts.py +26 -26
  515. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase4-finalize.py +4 -4
  516. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase5-finalize.py +4 -4
  517. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase6-finalize.py +5 -5
  518. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase7-finalize.py +4 -4
  519. package/pipeline/skills/figma-ios/figma-to-component/scripts/register-icons-codeconnect.py +4 -4
  520. package/pipeline/skills/figma-ios/figma-to-component/scripts/remote-mcp-fetch.py +5 -5
  521. package/pipeline/skills/figma-ios/figma-to-component/scripts/resolve-author-logins.py +2 -2
  522. package/pipeline/skills/figma-ios/figma-to-component/scripts/run-uicomponents-tests.sh +1 -1
  523. package/pipeline/skills/figma-ios/figma-to-component/scripts/sidebar-generator.py +5 -5
  524. package/pipeline/skills/figma-ios/figma-to-component/scripts/update-issue-from-registry.py +41 -41
  525. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase4.sh +8 -8
  526. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase6.sh +7 -7
  527. package/pipeline/skills/shared/README.md +62 -41
  528. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +39 -39
  529. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +44 -44
  530. package/pipeline/skills/shared/core/multi-agent/SKILL.md +182 -176
  531. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +55 -0
  532. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +48 -0
  533. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +16 -16
  534. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +48 -0
  535. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +40 -40
  536. package/pipeline/skills/shared/core/multi-agent-delete/SKILL.md +33 -30
  537. package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +26 -26
  538. package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +22 -22
  539. package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +6 -6
  540. package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +12 -12
  541. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +20 -20
  542. package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +61 -0
  543. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +22 -22
  544. package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +15 -15
  545. package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +12 -12
  546. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +14 -14
  547. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +12 -12
  548. package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +10 -10
  549. package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +18 -18
  550. package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +9 -9
  551. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +20 -20
  552. package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +63 -0
  553. package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +16 -13
  554. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +110 -110
  555. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +13 -13
  556. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +22 -22
  557. package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +18 -18
  558. package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +13 -13
  559. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +33 -30
  560. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +14 -14
  561. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +9 -9
  562. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +79 -79
  563. package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +5 -5
  564. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +10 -10
  565. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +41 -0
  566. package/pipeline/skills/shared/external/NOTICE-xcode-build-skills.md +53 -0
  567. package/pipeline/skills/shared/external/agentflow/SKILL.md +9 -9
  568. package/pipeline/skills/shared/external/alarmkit/SKILL.md +113 -52
  569. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +41 -0
  570. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +23 -16
  571. package/pipeline/skills/shared/external/app-clips/SKILL.md +85 -354
  572. package/pipeline/skills/shared/external/app-clips/evals/evals.json +50 -0
  573. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +135 -0
  574. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +125 -0
  575. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +113 -0
  576. package/pipeline/skills/shared/external/app-intents/SKILL.md +152 -59
  577. package/pipeline/skills/shared/external/app-intents/evals/evals.json +47 -0
  578. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +161 -118
  579. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +289 -392
  580. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +46 -0
  581. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +174 -0
  582. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +191 -0
  583. package/pipeline/skills/shared/external/app-store-review/SKILL.md +57 -107
  584. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +44 -0
  585. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +35 -12
  586. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +28 -26
  587. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +53 -62
  588. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +47 -0
  589. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +7 -1
  590. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +4 -1
  591. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +32 -12
  592. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +34 -30
  593. package/pipeline/skills/shared/external/authentication/SKILL.md +134 -138
  594. package/pipeline/skills/shared/external/authentication/evals/evals.json +48 -0
  595. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +56 -29
  596. package/pipeline/skills/shared/external/authentication/references/passkeys.md +183 -0
  597. package/pipeline/skills/shared/external/avkit/SKILL.md +497 -0
  598. package/pipeline/skills/shared/external/avkit/evals/evals.json +55 -0
  599. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +668 -0
  600. package/pipeline/skills/shared/external/background-processing/SKILL.md +29 -29
  601. package/pipeline/skills/shared/external/background-processing/evals/evals.json +44 -0
  602. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +44 -19
  603. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +136 -99
  604. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +47 -0
  605. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +27 -8
  606. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +7 -6
  607. package/pipeline/skills/shared/external/clean-code/SKILL.md +2 -2
  608. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +63 -56
  609. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +47 -0
  610. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +7 -4
  611. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +31 -11
  612. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +41 -0
  613. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +51 -51
  614. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +70 -65
  615. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +44 -0
  616. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +25 -1
  617. package/pipeline/skills/shared/external/core-data/SKILL.md +496 -0
  618. package/pipeline/skills/shared/external/core-data/evals/evals.json +44 -0
  619. package/pipeline/skills/shared/external/core-motion/SKILL.md +47 -14
  620. package/pipeline/skills/shared/external/core-motion/evals/evals.json +49 -0
  621. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +47 -16
  622. package/pipeline/skills/shared/external/core-nfc/SKILL.md +43 -54
  623. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +49 -0
  624. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +32 -2
  625. package/pipeline/skills/shared/external/coreml/SKILL.md +89 -48
  626. package/pipeline/skills/shared/external/coreml/evals/evals.json +44 -0
  627. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +82 -37
  628. package/pipeline/skills/shared/external/cryptokit/SKILL.md +493 -0
  629. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +44 -0
  630. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +602 -0
  631. package/pipeline/skills/shared/external/css-modern/SKILL.md +3 -2
  632. package/pipeline/skills/shared/external/database-patterns/SKILL.md +6 -5
  633. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +77 -47
  634. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +47 -0
  635. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +42 -34
  636. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +2 -2
  637. package/pipeline/skills/shared/external/device-integrity/SKILL.md +136 -176
  638. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +45 -0
  639. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +240 -0
  640. package/pipeline/skills/shared/external/energykit/SKILL.md +73 -34
  641. package/pipeline/skills/shared/external/energykit/evals/evals.json +45 -0
  642. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +80 -38
  643. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +67 -53
  644. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +44 -0
  645. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +53 -3
  646. package/pipeline/skills/shared/external/healthkit/SKILL.md +57 -124
  647. package/pipeline/skills/shared/external/healthkit/evals/evals.json +46 -0
  648. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +82 -1
  649. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +43 -41
  650. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +45 -0
  651. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +13 -8
  652. package/pipeline/skills/shared/external/html-semantic/SKILL.md +5 -4
  653. package/pipeline/skills/shared/external/humanizer/SKILL.md +4 -4
  654. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +174 -18
  655. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +49 -0
  656. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +262 -4
  657. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +117 -0
  658. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +141 -0
  659. package/pipeline/skills/shared/external/ios-localization/SKILL.md +67 -14
  660. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +49 -0
  661. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +20 -3
  662. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +131 -22
  663. package/pipeline/skills/shared/external/ios-networking/SKILL.md +69 -22
  664. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +50 -0
  665. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +28 -16
  666. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +354 -0
  667. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +69 -44
  668. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +35 -69
  669. package/pipeline/skills/shared/external/ios-security/references/file-storage-patterns.md +8 -8
  670. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +485 -0
  671. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +44 -0
  672. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +316 -0
  673. package/pipeline/skills/shared/external/live-activities/SKILL.md +120 -131
  674. package/pipeline/skills/shared/external/live-activities/evals/evals.json +44 -0
  675. package/pipeline/skills/shared/external/live-activities/references/{live-activity-patterns.md → activitykit-patterns.md} +148 -63
  676. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +40 -21
  677. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +47 -0
  678. package/pipeline/skills/shared/external/mapkit-location/references/{corelocation-patterns.md → mapkit-corelocation-patterns.md} +88 -41
  679. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +27 -24
  680. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +129 -172
  681. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +46 -0
  682. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +180 -0
  683. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +45 -18
  684. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +44 -0
  685. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +26 -6
  686. package/pipeline/skills/shared/external/natural-language/SKILL.md +48 -18
  687. package/pipeline/skills/shared/external/natural-language/evals/evals.json +47 -0
  688. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +20 -7
  689. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +4 -3
  690. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +156 -66
  691. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +51 -0
  692. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +69 -19
  693. package/pipeline/skills/shared/external/pdfkit/SKILL.md +499 -0
  694. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +42 -0
  695. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +844 -0
  696. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +122 -28
  697. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +44 -0
  698. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +49 -18
  699. package/pipeline/skills/shared/external/permissionkit/SKILL.md +100 -51
  700. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +47 -0
  701. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +48 -8
  702. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +13 -15
  703. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +4 -4
  704. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +2 -2
  705. package/pipeline/skills/shared/external/photos-camera-media/references/{photospicker-patterns.md → photokit-patterns.md} +3 -3
  706. package/pipeline/skills/shared/external/push-notifications/SKILL.md +45 -48
  707. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +46 -0
  708. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +22 -33
  709. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +56 -37
  710. package/pipeline/skills/shared/external/python-patterns/SKILL.md +4 -3
  711. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
  712. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +74 -53
  713. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +47 -0
  714. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +10 -10
  715. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +21 -20
  716. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +81 -64
  717. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +47 -0
  718. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +48 -9
  719. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +118 -104
  720. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +49 -0
  721. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +171 -0
  722. package/pipeline/skills/shared/external/spm-build-analysis/SKILL.md +93 -0
  723. package/pipeline/skills/shared/external/spm-build-analysis/references/build-optimization-sources.md +155 -0
  724. package/pipeline/skills/shared/external/spm-build-analysis/references/recommendation-format.md +85 -0
  725. package/pipeline/skills/shared/external/spm-build-analysis/references/spm-analysis-checks.md +105 -0
  726. package/pipeline/skills/shared/external/spm-build-analysis/scripts/check_spm_pins.py +118 -0
  727. package/pipeline/skills/shared/external/storekit/SKILL.md +110 -44
  728. package/pipeline/skills/shared/external/storekit/evals/evals.json +44 -0
  729. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +94 -43
  730. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +82 -33
  731. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +449 -0
  732. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +50 -0
  733. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +164 -0
  734. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +219 -0
  735. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +184 -0
  736. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +158 -0
  737. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +499 -0
  738. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +45 -0
  739. package/pipeline/skills/shared/external/swift-charts/SKILL.md +52 -40
  740. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +47 -0
  741. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +92 -11
  742. package/pipeline/skills/shared/external/swift-codable/SKILL.md +43 -16
  743. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +43 -0
  744. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +50 -30
  745. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +44 -0
  746. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +11 -4
  747. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +113 -0
  748. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +150 -0
  749. package/pipeline/skills/shared/external/swift-concurrency/references/{swift-6-2-concurrency.md → concurrency-patterns.md} +22 -11
  750. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +52 -0
  751. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +2 -2
  752. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +21 -15
  753. package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +3 -3
  754. package/pipeline/skills/shared/external/swift-concurrency-pro/SKILL.md +2 -2
  755. package/pipeline/skills/shared/external/swift-concurrency-pro/references/actors.md +3 -3
  756. package/pipeline/skills/shared/external/swift-concurrency-pro/references/async-streams.md +1 -1
  757. package/pipeline/skills/shared/external/swift-concurrency-pro/references/bridging.md +3 -3
  758. package/pipeline/skills/shared/external/swift-concurrency-pro/references/bug-patterns.md +3 -3
  759. package/pipeline/skills/shared/external/swift-concurrency-pro/references/cancellation.md +8 -8
  760. package/pipeline/skills/shared/external/swift-concurrency-pro/references/diagnostics.md +1 -1
  761. package/pipeline/skills/shared/external/swift-concurrency-pro/references/hotspots.md +2 -2
  762. package/pipeline/skills/shared/external/swift-concurrency-pro/references/interop.md +4 -4
  763. package/pipeline/skills/shared/external/swift-concurrency-pro/references/new-features.md +1 -1
  764. package/pipeline/skills/shared/external/swift-concurrency-pro/references/structured.md +2 -2
  765. package/pipeline/skills/shared/external/swift-concurrency-pro/references/testing.md +2 -2
  766. package/pipeline/skills/shared/external/swift-concurrency-pro/references/unstructured.md +3 -3
  767. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +339 -0
  768. package/pipeline/skills/shared/external/swift-language/SKILL.md +33 -34
  769. package/pipeline/skills/shared/external/swift-language/evals/evals.json +47 -0
  770. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +97 -0
  771. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +19 -6
  772. package/pipeline/skills/shared/external/swift-security/SKILL.md +195 -0
  773. package/pipeline/skills/shared/external/swift-security/evals/evals.json +48 -0
  774. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +595 -0
  775. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +611 -0
  776. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +708 -0
  777. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +573 -0
  778. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +752 -0
  779. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +538 -0
  780. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +530 -0
  781. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +543 -0
  782. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +620 -0
  783. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +515 -0
  784. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +496 -0
  785. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +747 -0
  786. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +566 -0
  787. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +813 -0
  788. package/pipeline/skills/shared/external/swift-testing/SKILL.md +97 -297
  789. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +44 -0
  790. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +123 -0
  791. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +162 -34
  792. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +2 -2
  793. package/pipeline/skills/shared/external/swift-testing-pro/references/async-tests.md +3 -3
  794. package/pipeline/skills/shared/external/swift-testing-pro/references/core-rules.md +2 -2
  795. package/pipeline/skills/shared/external/swift-testing-pro/references/migrating-from-xctest.md +5 -5
  796. package/pipeline/skills/shared/external/swift-testing-pro/references/new-features.md +3 -3
  797. package/pipeline/skills/shared/external/swift-testing-pro/references/writing-better-tests.md +5 -5
  798. package/pipeline/skills/shared/external/swiftdata/SKILL.md +44 -23
  799. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +47 -0
  800. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +3 -3
  801. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +75 -0
  802. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +54 -0
  803. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +14 -10
  804. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +5 -5
  805. package/pipeline/skills/shared/external/swiftdata-pro/SKILL.md +2 -2
  806. package/pipeline/skills/shared/external/swiftdata-pro/references/class-inheritance.md +2 -2
  807. package/pipeline/skills/shared/external/swiftdata-pro/references/cloudkit.md +1 -1
  808. package/pipeline/skills/shared/external/swiftdata-pro/references/core-rules.md +6 -6
  809. package/pipeline/skills/shared/external/swiftlint/SKILL.md +337 -0
  810. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +297 -0
  811. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +170 -0
  812. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +307 -0
  813. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +35 -0
  814. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +306 -0
  815. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +56 -65
  816. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +48 -44
  817. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +6 -6
  818. package/pipeline/skills/shared/external/swiftui-expert-skill/references/charts-accessibility.md +13 -13
  819. package/pipeline/skills/shared/external/swiftui-expert-skill/references/charts.md +3 -3
  820. package/pipeline/skills/shared/external/swiftui-expert-skill/references/image-optimization.md +1 -1
  821. package/pipeline/skills/shared/external/swiftui-expert-skill/references/latest-apis.md +4 -4
  822. package/pipeline/skills/shared/external/swiftui-expert-skill/references/layout-best-practices.md +2 -2
  823. package/pipeline/skills/shared/external/swiftui-expert-skill/references/list-patterns.md +1 -1
  824. package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-scenes.md +16 -16
  825. package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-views.md +11 -11
  826. package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-window-styling.md +7 -7
  827. package/pipeline/skills/shared/external/swiftui-expert-skill/references/state-management.md +5 -5
  828. package/pipeline/skills/shared/external/swiftui-expert-skill/references/view-structure.md +6 -6
  829. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +38 -16
  830. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +13 -3
  831. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +32 -28
  832. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +1 -1
  833. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +202 -41
  834. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +16 -25
  835. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +71 -26
  836. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +284 -65
  837. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +387 -0
  838. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +10 -10
  839. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +15 -3
  840. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +2 -2
  841. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +1 -1
  842. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +51 -25
  843. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +78 -6
  844. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +161 -16
  845. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +85 -27
  846. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +37 -33
  847. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +39 -51
  848. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +204 -30
  849. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +226 -21
  850. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +220 -20
  851. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +159 -34
  852. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +27 -0
  853. package/pipeline/skills/shared/external/swiftui-pro/SKILL.md +2 -2
  854. package/pipeline/skills/shared/external/swiftui-pro/references/accessibility.md +4 -4
  855. package/pipeline/skills/shared/external/swiftui-pro/references/api.md +1 -1
  856. package/pipeline/skills/shared/external/swiftui-pro/references/data.md +2 -2
  857. package/pipeline/skills/shared/external/swiftui-pro/references/design.md +4 -4
  858. package/pipeline/skills/shared/external/swiftui-pro/references/hygiene.md +2 -2
  859. package/pipeline/skills/shared/external/swiftui-pro/references/navigation.md +1 -1
  860. package/pipeline/skills/shared/external/swiftui-pro/references/performance.md +1 -1
  861. package/pipeline/skills/shared/external/swiftui-pro/references/swift.md +2 -2
  862. package/pipeline/skills/shared/external/swiftui-pro/references/views.md +2 -2
  863. package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +1 -1
  864. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +12 -12
  865. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +3 -3
  866. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +1 -1
  867. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +11 -11
  868. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +124 -10
  869. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +3 -2
  870. package/pipeline/skills/shared/external/testing-backend/SKILL.md +2 -1
  871. package/pipeline/skills/shared/external/tipkit/SKILL.md +3 -3
  872. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +9 -9
  873. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +17 -16
  874. package/pipeline/skills/shared/external/vision-framework/SKILL.md +11 -11
  875. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +1 -1
  876. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +5 -5
  877. package/pipeline/skills/shared/external/vue-composition/SKILL.md +7 -6
  878. package/pipeline/skills/shared/external/weatherkit/SKILL.md +3 -3
  879. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +9 -9
  880. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
  881. package/pipeline/skills/shared/external/web-performance/SKILL.md +8 -7
  882. package/pipeline/skills/shared/external/web-testing/SKILL.md +7 -6
  883. package/pipeline/skills/shared/external/widgetkit/SKILL.md +23 -17
  884. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +99 -0
  885. package/pipeline/skills/shared/external/xcode-build-benchmark/SKILL.md +89 -0
  886. package/pipeline/skills/shared/external/xcode-build-benchmark/references/benchmark-artifacts.md +94 -0
  887. package/pipeline/skills/shared/external/xcode-build-benchmark/references/benchmarking-workflow.md +67 -0
  888. package/pipeline/skills/shared/external/xcode-build-benchmark/schemas/build-benchmark.schema.json +230 -0
  889. package/pipeline/skills/shared/external/xcode-build-benchmark/scripts/benchmark_builds.py +308 -0
  890. package/pipeline/skills/shared/external/xcode-build-fixer/SKILL.md +219 -0
  891. package/pipeline/skills/shared/external/xcode-build-fixer/references/build-settings-best-practices.md +216 -0
  892. package/pipeline/skills/shared/external/xcode-build-fixer/references/fix-patterns.md +290 -0
  893. package/pipeline/skills/shared/external/xcode-build-fixer/references/recommendation-format.md +85 -0
  894. package/pipeline/skills/shared/external/xcode-build-fixer/scripts/benchmark_builds.py +308 -0
  895. package/pipeline/skills/shared/external/xcode-build-orchestrator/SKILL.md +157 -0
  896. package/pipeline/skills/shared/external/xcode-build-orchestrator/references/benchmark-artifacts.md +94 -0
  897. package/pipeline/skills/shared/external/xcode-build-orchestrator/references/build-settings-best-practices.md +216 -0
  898. package/pipeline/skills/shared/external/xcode-build-orchestrator/references/orchestration-report-template.md +143 -0
  899. package/pipeline/skills/shared/external/xcode-build-orchestrator/references/recommendation-format.md +85 -0
  900. package/pipeline/skills/shared/external/xcode-build-orchestrator/scripts/benchmark_builds.py +308 -0
  901. package/pipeline/skills/shared/external/xcode-build-orchestrator/scripts/diagnose_compilation.py +273 -0
  902. package/pipeline/skills/shared/external/xcode-build-orchestrator/scripts/generate_optimization_report.py +533 -0
  903. package/pipeline/skills/shared/external/xcode-compilation-analyzer/SKILL.md +90 -0
  904. package/pipeline/skills/shared/external/xcode-compilation-analyzer/references/build-optimization-sources.md +155 -0
  905. package/pipeline/skills/shared/external/xcode-compilation-analyzer/references/code-compilation-checks.md +106 -0
  906. package/pipeline/skills/shared/external/xcode-compilation-analyzer/references/recommendation-format.md +85 -0
  907. package/pipeline/skills/shared/external/xcode-compilation-analyzer/scripts/diagnose_compilation.py +273 -0
  908. package/pipeline/skills/shared/external/xcode-project-analyzer/SKILL.md +77 -0
  909. package/pipeline/skills/shared/external/xcode-project-analyzer/references/build-optimization-sources.md +155 -0
  910. package/pipeline/skills/shared/external/xcode-project-analyzer/references/build-settings-best-practices.md +216 -0
  911. package/pipeline/skills/shared/external/xcode-project-analyzer/references/project-audit-checks.md +101 -0
  912. package/pipeline/skills/shared/external/xcode-project-analyzer/references/recommendation-format.md +85 -0
  913. package/pipeline/skills/skills-index.md +213 -192
  914. package/docs/GENERICITY-REVIEW.md +0 -277
  915. package/docs/STABILITY-FIX-PLAN.md +0 -168
  916. package/pipeline/scripts/.last-figma-sync-plan.json +0 -23
  917. package/pipeline/scripts/README-figma-smokes.md +0 -34
  918. package/pipeline/scripts/figma-placeholder-map.json +0 -191
  919. package/pipeline/scripts/import-figma-skills.sh +0 -253
  920. package/pipeline/scripts/smoke-figma-config-schema.sh +0 -144
  921. package/pipeline/scripts/smoke-figma-skill-import.sh +0 -174
  922. package/pipeline/scripts/smoke-install-leak-gate.sh +0 -125
  923. package/pipeline/scripts/smoke-personal-data.sh +0 -82
  924. package/pipeline/scripts/sync-figma-source.sh +0 -228
  925. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-page-ids.json +0 -94
  926. package/pipeline/skills/shared/external/app-store-review/references/code-signing.md +0 -259
  927. package/pipeline/skills/shared/external/app-store-review/references/rejection-patterns.md +0 -152
  928. package/pipeline/skills/shared/external/pencilkit-drawing/references/paperkit-integration.md +0 -376
@@ -0,0 +1,813 @@
1
+ # Testing Keychain, CryptoKit, and Biometric Code
2
+
3
+ > Scope: Unit, integration, and CI patterns for validating keychain, CryptoKit, and biometric security code across simulator, CI runners, and physical devices.
4
+
5
+ **Protocol-based abstraction is the single most important pattern for testable security code.** Wrapping Security framework calls behind a Swift protocol lets you inject an in-memory mock for unit tests while reserving real keychain integration tests for physical devices. The core challenge is that keychain behavior differs dramatically across three environments - Xcode simulator, CI runner, and physical device - and tests that ignore these differences produce flaky failures, crashes, or false confidence.
6
+
7
+ This reference covers mock design, CryptoKit round-trip tests, Secure Enclave guards, biometric mocking, CI/CD keychain creation, simulator limitations, Swift Testing framework patterns, mutation testing, and OWASP MASTG validation. All code targets Swift 5.9+/6.0, iOS 17-18+, with iOS 26 post-quantum notes where applicable.
8
+
9
+ Key sources: Apple TN3137 "On Mac keychain APIs and implementations," WWDC19-413 "Testing in Xcode," WWDC24-10179/10195 "Meet/Go further with Swift Testing," Apple Platform Security Guide, OWASP MASTG.
10
+
11
+ ---
12
+
13
+ ## Contents
14
+
15
+ - [Protocol-Based Keychain Abstraction](#protocol-based-keychain-abstraction)
16
+ - [KeychainServiceProtocol with Real and Mock Implementations](#keychainserviceprotocol-with-real-and-mock-implementations)
17
+ - [Seven Mistakes AI Generators Make in Keychain Tests](#seven-mistakes-ai-generators-make-in-keychain-tests)
18
+ - [Simulator vs. Device Testing Matrix](#simulator-vs-device-testing-matrix)
19
+ - [Conditional Compilation and Runtime Guards](#conditional-compilation-and-runtime-guards)
20
+ - [Essential Testing Patterns](#essential-testing-patterns)
21
+ - [setUp/tearDown Cleanup for Real Keychain Tests](#setupteardown-cleanup-for-real-keychain-tests)
22
+ - [No Cleanup - Flaky Across Runs](#no-cleanup-flaky-across-runs)
23
+ - [Testing Error Paths with Injected Failures](#testing-error-paths-with-injected-failures)
24
+ - [CryptoKit Round-Trip Tests (Simulator-Safe)](#cryptokit-round-trip-tests-simulator-safe)
25
+ - [Secure Enclave Test Strategy - Protocol Fallback](#secure-enclave-test-strategy-protocol-fallback)
26
+ - [SigningKeyProvider Protocol with SE/Software Implementations](#signingkeyprovider-protocol-with-sesoftware-implementations)
27
+ - [Testing Secure Enclave Code](#testing-secure-enclave-code)
28
+ - [Biometric Flow Testing - LAContext Mocking](#biometric-flow-testing-lacontext-mocking)
29
+ - [Protocol-Based Approach (Preferred)](#protocol-based-approach-preferred)
30
+ - [Biometric Scenarios to Cover](#biometric-scenarios-to-cover)
31
+ - [CI/CD Pipeline Configuration](#cicd-pipeline-configuration)
32
+ - [GitHub Actions](#github-actions)
33
+ - [Common CI Error Reference](#common-ci-error-reference)
34
+ - [Test Host App Requirement](#test-host-app-requirement)
35
+ - [Xcode Test Plans - Separating Simulator from Device](#xcode-test-plans-separating-simulator-from-device)
36
+ - [Swift Testing Framework Patterns](#swift-testing-framework-patterns)
37
+ - [Advanced Patterns](#advanced-patterns)
38
+ - [Migration Testing: UserDefaults to Keychain](#migration-testing-userdefaults-to-keychain)
39
+ - [Performance Testing](#performance-testing)
40
+ - [Mutation Testing](#mutation-testing)
41
+ - [OWASP MASTG Keychain Validation](#owasp-mastg-keychain-validation)
42
+ - [Conclusion](#conclusion)
43
+ - [Summary Checklist](#summary-checklist)
44
+
45
+ ## Protocol-Based Keychain Abstraction
46
+
47
+ The foundation of testable keychain code is a protocol abstracting the four Security framework operations. Every view model, service, or manager that touches the keychain depends on this protocol, never on the Security framework directly.
48
+
49
+ ### KeychainServiceProtocol with Real and Mock Implementations
50
+
51
+ ```swift
52
+ import Foundation
53
+ import Security
54
+
55
+ enum KeychainError: Error, Equatable {
56
+ case duplicateItem
57
+ case itemNotFound
58
+ case authFailed
59
+ case interactionNotAllowed
60
+ case unexpectedData
61
+ case unhandledError(status: OSStatus)
62
+
63
+ init(status: OSStatus) {
64
+ switch status {
65
+ case errSecDuplicateItem: self = .duplicateItem
66
+ case errSecItemNotFound: self = .itemNotFound
67
+ case errSecAuthFailed: self = .authFailed
68
+ case errSecInteractionNotAllowed: self = .interactionNotAllowed
69
+ default: self = .unhandledError(status: status)
70
+ }
71
+ }
72
+ }
73
+
74
+ protocol KeychainServiceProtocol: Sendable {
75
+ func save(_ data: Data, forKey key: String) throws
76
+ func read(forKey key: String) throws -> Data?
77
+ func update(_ data: Data, forKey key: String) throws
78
+ func delete(forKey key: String) throws
79
+ func deleteAll() throws
80
+ }
81
+ ```
82
+
83
+ The real `KeychainService` implementation wraps `SecItem*` calls with the add-or-update pattern and proper `OSStatus` mapping (see `keychain-fundamentals.md` for the full implementation). Key points: `save` attempts update first to avoid `errSecDuplicateItem`; `delete` treats `errSecItemNotFound` as success; the class conforms to `@unchecked Sendable` with immutable stored properties.
84
+
85
+ The mock replaces Security framework with a dictionary. Runs everywhere - simulator, CI, even Linux - with zero entitlement requirements. Supports injectable errors and call counting:
86
+
87
+ ```swift
88
+ final class MockKeychainService: KeychainServiceProtocol, @unchecked Sendable {
89
+ var storage: [String: Data] = [:]
90
+ var saveCallCount = 0
91
+ var readCallCount = 0
92
+ var deleteCallCount = 0
93
+ var errorToThrow: KeychainError?
94
+
95
+ func save(_ data: Data, forKey key: String) throws {
96
+ if let error = errorToThrow { throw error }
97
+ saveCallCount += 1
98
+ storage[key] = data
99
+ }
100
+
101
+ func read(forKey key: String) throws -> Data? {
102
+ if let error = errorToThrow { throw error }
103
+ readCallCount += 1
104
+ return storage[key]
105
+ }
106
+
107
+ func update(_ data: Data, forKey key: String) throws {
108
+ if let error = errorToThrow { throw error }
109
+ guard storage[key] != nil else { throw KeychainError.itemNotFound }
110
+ storage[key] = data
111
+ }
112
+
113
+ func delete(forKey key: String) throws {
114
+ if let error = errorToThrow { throw error }
115
+ storage.removeValue(forKey: key)
116
+ deleteCallCount += 1
117
+ }
118
+
119
+ func deleteAll() throws {
120
+ if let error = errorToThrow { throw error }
121
+ storage.removeAll()
122
+ }
123
+ }
124
+ ```
125
+
126
+ Business logic depends only on the protocol - never on `SecItem*` directly:
127
+
128
+ ```swift
129
+ final class AuthenticationManager {
130
+ private let keychain: KeychainServiceProtocol
131
+
132
+ init(keychain: KeychainServiceProtocol) {
133
+ self.keychain = keychain
134
+ }
135
+
136
+ func storeToken(_ token: String) throws {
137
+ guard let data = token.data(using: .utf8) else {
138
+ throw KeychainError.unexpectedData
139
+ }
140
+ try keychain.save(data, forKey: "auth_token")
141
+ }
142
+
143
+ func retrieveToken() throws -> String? {
144
+ guard let data = try keychain.read(forKey: "auth_token") else { return nil }
145
+ return String(data: data, encoding: .utf8)
146
+ }
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Seven Mistakes AI Generators Make in Keychain Tests
153
+
154
+ Both research providers independently identified overlapping anti-patterns. This merged list covers the full set:
155
+
156
+ **1. Tests that use the real keychain without cleanup.** Tests calling `SecItemAdd` directly leave state across runs. Second run fails with `errSecDuplicateItem` (-25299). AI generators rarely include `setUp`/`tearDown` cleanup.
157
+
158
+ **2. Assuming Secure Enclave exists on simulator.** `SecureEnclave.isAvailable` returns `false` on every simulator. Tests calling `SecureEnclave.P256.Signing.PrivateKey()` directly throw `CryptoKitError` on simulator and crash CI.
159
+
160
+ **3. Not testing error paths.** Real keychain code must handle `errSecDuplicateItem` (-25299), `errSecItemNotFound` (-25300), `errSecAuthFailed` (-25293), and `errSecInteractionNotAllowed` (-25308). AI generators almost never test these failure modes.
161
+
162
+ **4. Assuming biometric hardware.** Tests instantiating a real `LAContext` and asserting `canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics)` returns `true` fail on simulator where no biometric hardware exists.
163
+
164
+ **5. Missing test host app.** Since Xcode 9, test bundles on iOS simulator require a host app to access the keychain. Without one, `SecItemAdd` returns `-25300` or `-34018`. AI generators never mention this requirement.
165
+
166
+ **6. No service/account scoping.** Tests omitting `kSecAttrService` match items from other tests or even other apps. Every keychain operation in tests must use a unique, test-specific service identifier.
167
+
168
+ **7. Confusing data protection keychain with file-based keychain.** Per Apple TN3137, macOS has two keychain implementations. The `security` CLI works with the file-based keychain; iOS apps use the data protection keychain. CI scripts using `security create-keychain` create the wrong type for `SecItemAdd` targets.
169
+
170
+ ---
171
+
172
+ ## Simulator vs. Device Testing Matrix
173
+
174
+ Understanding exactly what works where prevents entire categories of test failures:
175
+
176
+ | Feature | Simulator | Physical Device |
177
+ | ------------------------------------------------------------- | ------------------------------------- | ---------------------------- |
178
+ | Keychain CRUD (`SecItemAdd`, etc.) | ✅ Works | ✅ Works |
179
+ | CryptoKit software crypto (AES-GCM, ChaChaPoly, P256, SHA256) | ✅ Software | ✅ Hardware-accelerated |
180
+ | `kSecAttrAccessible` values | ✅ Accepted but not hardware-enforced | ✅ Hardware-enforced |
181
+ | `SecureEnclave.isAvailable` | Returns **false** | Returns **true** (A7+) |
182
+ | `SecureEnclave.P256.Signing.PrivateKey()` | ❌ Throws | ✅ Works |
183
+ | Biometric prompt on protected items | ❌ Skipped - value returned silently | ✅ Shows prompt |
184
+ | `LAContext.canEvaluatePolicy(.biometrics)` | Returns **false** | Returns **true** if enrolled |
185
+ | Face ID simulation via Xcode menu | ✅ Manual only | N/A (real hardware) |
186
+ | Post-quantum (ML-KEM, ML-DSA) iOS 26+ | ✅ Software (iOS 26 runtime) | ✅ Works |
187
+
188
+ **Critical subtlety:** On simulator, keychain items protected with `kSecAttrAccessControl` and biometric flags return their value without showing a biometric prompt. Simulator tests that store biometric-protected items and read them succeed silently, giving false confidence the biometric gate works.
189
+
190
+ ### Conditional Compilation and Runtime Guards
191
+
192
+ ```swift
193
+ // Compile-time: exclude SE code on simulator
194
+ #if targetEnvironment(simulator)
195
+ let signingKey = SoftwareSigningKey()
196
+ #else
197
+ let signingKey = SecureEnclave.isAvailable
198
+ ? try SecureEnclaveSigningKey()
199
+ : SoftwareSigningKey()
200
+ #endif
201
+
202
+ // Runtime skip in XCTest
203
+ func testDeviceOnlyFeature() throws {
204
+ #if targetEnvironment(simulator)
205
+ throw XCTSkip("Requires physical device")
206
+ #endif
207
+ // Device-only test code here
208
+ }
209
+
210
+ // Runtime detection via ProcessInfo
211
+ struct EnvironmentDetector {
212
+ static var isSimulator: Bool {
213
+ ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
214
+ }
215
+ static var isRunningTests: Bool {
216
+ ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil
217
+ }
218
+ }
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Essential Testing Patterns
224
+
225
+ ### setUp/tearDown Cleanup for Real Keychain Tests
226
+
227
+ ```swift
228
+ final class KeychainIntegrationTests: XCTestCase {
229
+ private let testService = "com.tests.keychain-integration"
230
+ private var keychain: KeychainService!
231
+
232
+ override func setUp() {
233
+ super.setUp()
234
+ keychain = KeychainService(service: testService)
235
+ try? keychain.deleteAll() // Clean slate
236
+ }
237
+
238
+ override func tearDown() {
239
+ try? keychain.deleteAll() // Leave no trace
240
+ super.tearDown()
241
+ }
242
+
243
+ func testSaveAndRetrieveToken() throws {
244
+ let token = "test-jwt-token-12345"
245
+ try keychain.save(token.data(using: .utf8)!, forKey: "access_token")
246
+ let retrieved = try keychain.read(forKey: "access_token")
247
+ XCTAssertEqual(String(data: retrieved!, encoding: .utf8), token)
248
+ }
249
+ }
250
+ ```
251
+
252
+ ### No Cleanup - Flaky Across Runs
253
+
254
+ ```swift
255
+ // ❌ INCORRECT: No cleanup, no isolation
256
+ final class BadKeychainTests: XCTestCase {
257
+ func testSaveToken() {
258
+ let query: [String: Any] = [
259
+ kSecClass as String: kSecClassGenericPassword,
260
+ kSecAttrAccount as String: "token",
261
+ kSecValueData as String: "secret".data(using: .utf8)!
262
+ ]
263
+ let status = SecItemAdd(query as CFDictionary, nil)
264
+ XCTAssertEqual(status, errSecSuccess)
265
+ // First run: passes ✅
266
+ // Second run: FAILS with errSecDuplicateItem (-25299) ❌
267
+ }
268
+ }
269
+ ```
270
+
271
+ ### Testing Error Paths with Injected Failures
272
+
273
+ ```swift
274
+ final class KeychainErrorPathTests: XCTestCase {
275
+ var mockKeychain: MockKeychainService!
276
+ var authManager: AuthenticationManager!
277
+
278
+ override func setUp() {
279
+ mockKeychain = MockKeychainService()
280
+ authManager = AuthenticationManager(keychain: mockKeychain)
281
+ }
282
+
283
+ func testStoreToken_whenDuplicateItem_throwsExpectedError() {
284
+ mockKeychain.errorToThrow = .duplicateItem
285
+ XCTAssertThrowsError(try authManager.storeToken("token")) { error in
286
+ XCTAssertEqual(error as? KeychainError, .duplicateItem)
287
+ }
288
+ }
289
+
290
+ func testRetrieveToken_whenAuthFailed_throwsError() {
291
+ mockKeychain.errorToThrow = .authFailed
292
+ XCTAssertThrowsError(try authManager.retrieveToken()) { error in
293
+ XCTAssertEqual(error as? KeychainError, .authFailed)
294
+ }
295
+ }
296
+
297
+ func testRetrieveToken_whenInteractionNotAllowed_throwsError() {
298
+ // Simulates the most common CI failure scenario
299
+ mockKeychain.errorToThrow = .interactionNotAllowed
300
+ XCTAssertThrowsError(try authManager.retrieveToken()) { error in
301
+ XCTAssertEqual(error as? KeychainError, .interactionNotAllowed)
302
+ }
303
+ }
304
+ }
305
+ ```
306
+
307
+ ### CryptoKit Round-Trip Tests (Simulator-Safe)
308
+
309
+ All CryptoKit software operations work on simulator. These tests run everywhere:
310
+
311
+ ```swift
312
+ import XCTest
313
+ import CryptoKit
314
+
315
+ final class CryptoKitTests: XCTestCase {
316
+
317
+ func testAESGCMRoundTrip() throws {
318
+ let key = SymmetricKey(size: .bits256)
319
+ let plaintext = "Sensitive credentials".data(using: .utf8)!
320
+ let sealedBox = try AES.GCM.seal(plaintext, using: key)
321
+ let ciphertext = sealedBox.combined!
322
+ XCTAssertNotEqual(ciphertext, plaintext)
323
+
324
+ let reopened = try AES.GCM.SealedBox(combined: ciphertext)
325
+ let decrypted = try AES.GCM.open(reopened, using: key)
326
+ XCTAssertEqual(decrypted, plaintext)
327
+ }
328
+
329
+ func testAESGCMWrongKeyFails() throws {
330
+ let correctKey = SymmetricKey(size: .bits256)
331
+ let wrongKey = SymmetricKey(size: .bits256)
332
+ let sealed = try AES.GCM.seal("secret".data(using: .utf8)!, using: correctKey)
333
+ XCTAssertThrowsError(try AES.GCM.open(sealed, using: wrongKey))
334
+ }
335
+
336
+ func testP256SignVerify() throws {
337
+ let privateKey = P256.Signing.PrivateKey()
338
+ let data = "Message to authenticate".data(using: .utf8)!
339
+ let signature = try privateKey.signature(for: data)
340
+ XCTAssertTrue(privateKey.publicKey.isValidSignature(signature, for: data))
341
+
342
+ let tampered = "Tampered message".data(using: .utf8)!
343
+ XCTAssertFalse(privateKey.publicKey.isValidSignature(signature, for: tampered))
344
+ }
345
+
346
+ func testCurve25519KeyAgreement() throws {
347
+ let alice = Curve25519.KeyAgreement.PrivateKey()
348
+ let bob = Curve25519.KeyAgreement.PrivateKey()
349
+ let aliceShared = try alice.sharedSecretFromKeyAgreement(with: bob.publicKey)
350
+ let bobShared = try bob.sharedSecretFromKeyAgreement(with: alice.publicKey)
351
+
352
+ let aliceKey = aliceShared.hkdfDerivedSymmetricKey(
353
+ using: SHA256.self, salt: Data(), sharedInfo: Data(), outputByteCount: 32)
354
+ let bobKey = bobShared.hkdfDerivedSymmetricKey(
355
+ using: SHA256.self, salt: Data(), sharedInfo: Data(), outputByteCount: 32)
356
+
357
+ // Both parties can decrypt each other's messages
358
+ let sealed = try AES.GCM.seal("test".data(using: .utf8)!, using: aliceKey)
359
+ XCTAssertEqual(try AES.GCM.open(sealed, using: bobKey), "test".data(using: .utf8)!)
360
+ }
361
+ }
362
+ ```
363
+
364
+ **iOS 26 note:** Post-quantum cryptography (ML-KEM, ML-DSA) is available via CryptoKit starting iOS 26. Gate these tests with `@available(iOS 26, *)` and use the same round-trip pattern. Software-based PQC works on simulator (see `cryptokit-public-key.md`).
365
+
366
+ ---
367
+
368
+ ## Secure Enclave Test Strategy - Protocol Fallback
369
+
370
+ `SecureEnclave.P256.Signing.PrivateKey` and `P256.Signing.PrivateKey` are distinct types, so a single function should not promise to return one concrete type for both SE and software paths. Use a protocol-based abstraction:
371
+
372
+ ### SigningKeyProvider Protocol with SE/Software Implementations
373
+
374
+ ```swift
375
+ import CryptoKit
376
+
377
+ protocol SigningKeyProvider {
378
+ func sign(_ data: Data) throws -> Data
379
+ func publicKeyData() -> Data
380
+ }
381
+
382
+ final class SecureEnclaveSigningKey: SigningKeyProvider {
383
+ private let key: SecureEnclave.P256.Signing.PrivateKey
384
+
385
+ init() throws {
386
+ guard SecureEnclave.isAvailable else {
387
+ throw KeychainError.unhandledError(status: errSecUnimplemented)
388
+ }
389
+ self.key = try SecureEnclave.P256.Signing.PrivateKey()
390
+ }
391
+
392
+ func sign(_ data: Data) throws -> Data {
393
+ try key.signature(for: data).derRepresentation
394
+ }
395
+
396
+ func publicKeyData() -> Data { key.publicKey.derRepresentation }
397
+ }
398
+
399
+ final class SoftwareSigningKey: SigningKeyProvider {
400
+ private let key = P256.Signing.PrivateKey()
401
+
402
+ func sign(_ data: Data) throws -> Data {
403
+ try key.signature(for: data).derRepresentation
404
+ }
405
+
406
+ func publicKeyData() -> Data { key.publicKey.derRepresentation }
407
+ }
408
+
409
+ struct SigningKeyFactory {
410
+ static func make() -> SigningKeyProvider {
411
+ if SecureEnclave.isAvailable,
412
+ let seKey = try? SecureEnclaveSigningKey() {
413
+ return seKey
414
+ }
415
+ return SoftwareSigningKey()
416
+ }
417
+ }
418
+ ```
419
+
420
+ ### Testing Secure Enclave Code
421
+
422
+ ```swift
423
+ // ❌ INCORRECT: Crashes on simulator and CI
424
+ func testSecureEnclaveSigning_BROKEN() throws {
425
+ let key = try SecureEnclave.P256.Signing.PrivateKey() // throws on simulator
426
+ let sig = try key.signature(for: "data".data(using: .utf8)!)
427
+ XCTAssertTrue(key.publicKey.isValidSignature(sig, for: "data".data(using: .utf8)!))
428
+ }
429
+
430
+ // ✅ CORRECT: Skip gracefully when SE unavailable
431
+ func testSecureEnclaveSigning_withGuard() throws {
432
+ try XCTSkipUnless(SecureEnclave.isAvailable,
433
+ "Secure Enclave not available - skipping on simulator")
434
+ let key = try SecureEnclave.P256.Signing.PrivateKey()
435
+ let data = "authenticated payload".data(using: .utf8)!
436
+ let sig = try key.signature(for: data)
437
+ XCTAssertTrue(key.publicKey.isValidSignature(sig, for: data))
438
+ }
439
+
440
+ // ✅ CORRECT: Protocol-based test runs everywhere
441
+ func testSigningWithFallback() throws {
442
+ let signer = SigningKeyFactory.make()
443
+ let data = "payload".data(using: .utf8)!
444
+ let sigBytes = try signer.sign(data)
445
+ XCTAssertFalse(sigBytes.isEmpty)
446
+
447
+ let publicKey = try P256.Signing.PublicKey(derRepresentation: signer.publicKeyData())
448
+ let signature = try P256.Signing.ECDSASignature(derRepresentation: sigBytes)
449
+ XCTAssertTrue(publicKey.isValidSignature(signature, for: data))
450
+ }
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Biometric Flow Testing - LAContext Mocking
456
+
457
+ Wrap `LAContext` behind a protocol for full control over biometric outcomes in tests. Alternatively, subclass `LAContext` directly (simpler but tighter coupling).
458
+
459
+ ### Protocol-Based Approach (Preferred)
460
+
461
+ ```swift
462
+ import LocalAuthentication
463
+
464
+ protocol BiometricAuthContext {
465
+ func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool
466
+ func evaluatePolicy(_ policy: LAPolicy, localizedReason: String,
467
+ reply: @escaping (Bool, Error?) -> Void)
468
+ }
469
+
470
+ extension LAContext: BiometricAuthContext {}
471
+
472
+ final class BiometricAuthManager {
473
+ private let context: BiometricAuthContext
474
+
475
+ init(context: BiometricAuthContext = LAContext()) {
476
+ self.context = context
477
+ }
478
+
479
+ var isBiometricsAvailable: Bool {
480
+ context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
481
+ }
482
+
483
+ func authenticate(reason: String,
484
+ completion: @escaping (Result<Void, Error>) -> Void) {
485
+ guard isBiometricsAvailable else {
486
+ completion(.failure(LAError(.biometryNotAvailable)))
487
+ return
488
+ }
489
+ context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
490
+ localizedReason: reason) { success, error in
491
+ completion(success ? .success(()) : .failure(error ?? LAError(.authenticationFailed)))
492
+ }
493
+ }
494
+ }
495
+
496
+ final class MockBiometricContext: BiometricAuthContext {
497
+ var canEvaluateResult = true
498
+ var evaluateResult = true
499
+ var evaluateError: Error?
500
+ var evaluateCalled = false
501
+
502
+ func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool {
503
+ canEvaluateResult
504
+ }
505
+
506
+ func evaluatePolicy(_ policy: LAPolicy, localizedReason: String,
507
+ reply: @escaping (Bool, Error?) -> Void) {
508
+ evaluateCalled = true
509
+ reply(evaluateResult, evaluateError)
510
+ }
511
+ }
512
+ ```
513
+
514
+ ### Biometric Scenarios to Cover
515
+
516
+ | Scenario | canEvaluate | evaluatePolicy | Error | Expected App Behavior |
517
+ | ------------ | ----------- | -------------- | ---------------------- | ------------------------- |
518
+ | Success | true | true | nil | Proceed |
519
+ | User cancel | true | false | `.userCancel` | Retry or abort gracefully |
520
+ | Lockout | true | false | `.biometryLockout` | Fallback to passcode |
521
+ | Not enrolled | false | n/a | `.biometryNotEnrolled` | Show enrollment guidance |
522
+
523
+ ```swift
524
+ func testBiometricAuthSuccess() {
525
+ let mock = MockBiometricContext()
526
+ mock.canEvaluateResult = true
527
+ mock.evaluateResult = true
528
+ let manager = BiometricAuthManager(context: mock)
529
+
530
+ let exp = expectation(description: "auth")
531
+ manager.authenticate(reason: "Test") { result in
532
+ if case .failure = result { XCTFail("Expected success") }
533
+ exp.fulfill()
534
+ }
535
+ waitForExpectations(timeout: 1)
536
+ XCTAssertTrue(mock.evaluateCalled)
537
+ }
538
+
539
+ func testBiometricAuthUnavailable() {
540
+ let mock = MockBiometricContext()
541
+ mock.canEvaluateResult = false
542
+ let manager = BiometricAuthManager(context: mock)
543
+
544
+ let exp = expectation(description: "unavailable")
545
+ manager.authenticate(reason: "Test") { result in
546
+ if case .success = result { XCTFail("Expected failure") }
547
+ exp.fulfill()
548
+ }
549
+ waitForExpectations(timeout: 1)
550
+ XCTAssertFalse(mock.evaluateCalled) // Should not attempt auth
551
+ }
552
+ ```
553
+
554
+ ---
555
+
556
+ ## CI/CD Pipeline Configuration
557
+
558
+ Running keychain tests in CI is the most error-prone part. The `-25308` (`errSecInteractionNotAllowed`) error is the most common CI failure - keychain locked or requires GUI interaction in a headless environment.
559
+
560
+ ### GitHub Actions
561
+
562
+ ```yaml
563
+ name: iOS CI
564
+ on: [push, pull_request]
565
+ jobs:
566
+ test:
567
+ runs-on: macos-latest
568
+ steps:
569
+ - uses: actions/checkout@v5
570
+ - name: Create temporary keychain
571
+ env:
572
+ KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
573
+ run: |
574
+ KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
575
+ security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
576
+ security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
577
+ security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
578
+ security list-keychain -d user -s $KEYCHAIN_PATH
579
+ # Import cert + CRITICAL partition list step
580
+ echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $RUNNER_TEMP/cert.p12
581
+ security import $RUNNER_TEMP/cert.p12 -P "$P12_PASSWORD" \
582
+ -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
583
+ security set-key-partition-list -S apple-tool:,apple: \
584
+ -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
585
+ - name: Run simulator-safe tests
586
+ run: |
587
+ xcodebuild test -scheme MyApp \
588
+ -destination 'platform=iOS Simulator,name=iPhone 16' \
589
+ -testPlan CITests
590
+ - name: Cleanup
591
+ if: always()
592
+ run: security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
593
+ ```
594
+
595
+ **`security set-key-partition-list` must be called after importing certificates** - this is the step most people miss. Without it, `codesign` hangs indefinitely waiting for a GUI prompt. The `-A` flag on import grants access to all applications, necessary in CI.
596
+
597
+ **Xcode Cloud:** Uses ephemeral environments - no manual `security create-keychain`. Apple manages signing automatically. Ensure Keychain Sharing capability is enabled. The `-25308` error is common when SPM tries to save credentials.
598
+
599
+ **Fastlane:** `setup_ci` creates a temporary `fastlane_tmp_keychain` and sets it as default. On self-hosted runners, this can interfere with the host machine's keychain.
600
+
601
+ ```ruby
602
+ lane :ci_test do
603
+ setup_ci(timeout: 3600)
604
+ sync_code_signing(type: "development", readonly: is_ci)
605
+ run_tests(scheme: "MyApp", testplan: "CITests", device: "iPhone 16")
606
+ end
607
+ ```
608
+
609
+ ### Common CI Error Reference
610
+
611
+ | Error | OSStatus | Cause | Fix |
612
+ | ----------------------------- | -------- | ------------------------------------- | ----------------------------------------------- |
613
+ | `errSecInteractionNotAllowed` | -25308 | Keychain locked / needs GUI | Unlock keychain + `set-key-partition-list` |
614
+ | `errSecMissingEntitlement` | -34018 | No keychain-access-groups entitlement | Add entitlements to test host app |
615
+ | `errSecItemNotFound` | -25300 | No test host or missing entitlement | Use test host app with keychain capability |
616
+ | `errSecInternalComponent` | -67585 | Partition list not set after import | Call `set-key-partition-list` after cert import |
617
+ | Default keychain not found | -25307 | No default keychain on CI runner | Create and set default keychain |
618
+
619
+ ### Test Host App Requirement
620
+
621
+ Since Xcode 9, test bundles on iOS simulator require a host app to access the keychain. Without one, `SecItemAdd` returns `-25300` or `-34018`. Create a minimal iOS app target, enable the Keychain Sharing capability, and set the test target's **Test Host** and **Bundle Loader** build settings to point at it.
622
+
623
+ ---
624
+
625
+ ## Xcode Test Plans - Separating Simulator from Device
626
+
627
+ Create two test plans for CI/device split:
628
+
629
+ - **CITests.xctestplan**: Only tests using `MockKeychainService` and simulator-safe CryptoKit. Skips integration, biometric, and SE tests.
630
+ - **DeviceTests.xctestplan**: Real keychain integration, Secure Enclave, and biometric hardware tests. Requires physical device.
631
+
632
+ ```bash
633
+ # CI: simulator-safe tests on every push
634
+ xcodebuild test -scheme MyApp \
635
+ -destination 'platform=iOS Simulator,name=iPhone 16' \
636
+ -testPlan CITests
637
+
638
+ # Nightly: device farm runs everything
639
+ xcodebuild test -scheme MyApp \
640
+ -destination 'platform=iOS,id=DEVICE_UDID' \
641
+ -testPlan DeviceTests
642
+ ```
643
+
644
+ ---
645
+
646
+ ## Swift Testing Framework Patterns
647
+
648
+ Swift Testing (WWDC24) introduces tags, traits, and parameterized tests that map well to security test organization:
649
+
650
+ ```swift
651
+ import Testing
652
+ @testable import MyApp
653
+
654
+ extension Tag {
655
+ @Tag static var keychain: Self
656
+ @Tag static var deviceOnly: Self
657
+ @Tag static var ciSafe: Self
658
+ }
659
+
660
+ @Suite(.serialized, .tags(.keychain))
661
+ struct KeychainTests {
662
+
663
+ @Test("Save and retrieve round-trip", .tags(.ciSafe))
664
+ func saveAndRetrieve() throws {
665
+ let mock = MockKeychainService()
666
+ let manager = AuthenticationManager(keychain: mock)
667
+ try manager.storeToken("test-token")
668
+ let result = try #require(try manager.retrieveToken())
669
+ #expect(result == "test-token")
670
+ }
671
+
672
+ @Test("Device-only: real keychain integration",
673
+ .enabled(if: ProcessInfo.processInfo.environment["CI"] == nil),
674
+ .tags(.deviceOnly))
675
+ func realKeychainIntegration() throws {
676
+ let keychain = KeychainService(service: "com.test.swift-testing")
677
+ try keychain.deleteAll()
678
+ defer { try? keychain.deleteAll() }
679
+ try keychain.save("token".data(using: .utf8)!, forKey: "key")
680
+ let data = try #require(try keychain.read(forKey: "key"))
681
+ #expect(String(data: data, encoding: .utf8) == "token")
682
+ }
683
+
684
+ @Test("Parameterized error paths",
685
+ arguments: [
686
+ KeychainError.duplicateItem,
687
+ KeychainError.itemNotFound,
688
+ KeychainError.authFailed,
689
+ KeychainError.interactionNotAllowed
690
+ ])
691
+ func errorPathHandling(expectedError: KeychainError) {
692
+ let mock = MockKeychainService()
693
+ mock.errorToThrow = expectedError
694
+ #expect(throws: KeychainError.self) {
695
+ try mock.read(forKey: "any-key")
696
+ }
697
+ }
698
+ }
699
+ ```
700
+
701
+ The `.serialized` trait ensures keychain tests modifying shared state run sequentially. Tags integrate with test plans for filtering - `.ciSafe` tests run in CI, `.deviceOnly` tests run on device farms.
702
+
703
+ ---
704
+
705
+ ## Advanced Patterns
706
+
707
+ ### Migration Testing: UserDefaults to Keychain
708
+
709
+ Migration code is security-critical - silent failure leaves credentials in UserDefaults (see `migration-legacy-stores.md`). The class under test accepts injected dependencies for both stores:
710
+
711
+ ```swift
712
+ final class StorageMigrationManager {
713
+ private let defaults: UserDefaults
714
+ private let keychain: KeychainServiceProtocol
715
+
716
+ init(defaults: UserDefaults = .standard,
717
+ keychain: KeychainServiceProtocol) {
718
+ self.defaults = defaults
719
+ self.keychain = keychain
720
+ }
721
+
722
+ func migrateIfNeeded() throws {
723
+ let version = defaults.integer(forKey: "migration_version")
724
+ if version < 1 {
725
+ if let token = defaults.string(forKey: "auth_token"),
726
+ let data = token.data(using: .utf8) {
727
+ try keychain.save(data, forKey: "auth_token")
728
+ defaults.removeObject(forKey: "auth_token")
729
+ }
730
+ }
731
+ defaults.set(1, forKey: "migration_version")
732
+ }
733
+ }
734
+ ```
735
+
736
+ Test with isolated `UserDefaults(suiteName:)` and mock keychain:
737
+
738
+ ```swift
739
+ func testMigrationMovesTokenToKeychain() throws {
740
+ let defaults = UserDefaults(suiteName: "migration-test")!
741
+ defaults.removePersistentDomain(forName: "migration-test")
742
+ defaults.set("my-secret", forKey: "auth_token")
743
+ defaults.set(0, forKey: "migration_version")
744
+
745
+ let mock = MockKeychainService()
746
+ let migrator = StorageMigrationManager(defaults: defaults, keychain: mock)
747
+ try migrator.migrateIfNeeded()
748
+
749
+ // Token moved to keychain, removed from UserDefaults
750
+ XCTAssertEqual(String(data: mock.storage["auth_token"]!, encoding: .utf8), "my-secret")
751
+ XCTAssertNil(defaults.string(forKey: "auth_token"))
752
+ }
753
+ ```
754
+
755
+ ### Performance Testing
756
+
757
+ ```swift
758
+ func testKeychainWritePerformance() {
759
+ let keychain = KeychainService(service: "com.test.perf")
760
+ let options = XCTMeasureOptions()
761
+ options.iterationCount = 20
762
+
763
+ measure(metrics: [XCTClockMetric(), XCTCPUMetric()], options: options) {
764
+ let data = UUID().uuidString.data(using: .utf8)!
765
+ try? keychain.save(data, forKey: "perf-key")
766
+ try? keychain.delete(forKey: "perf-key")
767
+ }
768
+ }
769
+ ```
770
+
771
+ ### Mutation Testing
772
+
773
+ Mutation testing introduces deliberate bugs (flipping `==` to `!=`, removing `SecItemDelete` calls, swapping `&&` to `||`) and checks whether your tests catch them. A project can have 81% code coverage but only 16% mutation score - tests execute security code without validating it does the right thing.
774
+
775
+ **Muter** (`brew install muter-mutation-testing/muter/muter`) is the primary Swift mutation testing tool. Its `RelationalOperatorReplacement` operator catches authentication bypasses; `RemoveSideEffects` catches missing `SecItemDelete` calls in logout flows. For security code, target mutation score above **80%**.
776
+
777
+ ### OWASP MASTG Keychain Validation
778
+
779
+ MASTG-TEST-0052 requires that sensitive data use the Keychain, not `NSUserDefaults` or `.plist` files. OWASP also documents that keychain data persists after app uninstallation - the app sandbox is wiped but keychain items remain. Standard mitigation is a fresh-install detector (see `common-anti-patterns.md`):
780
+
781
+ ```swift
782
+ static func handleFreshInstall(keychain: KeychainServiceProtocol) {
783
+ let hasLaunched = UserDefaults.standard.bool(forKey: "has_launched")
784
+ if !hasLaunched {
785
+ try? keychain.deleteAll()
786
+ UserDefaults.standard.set(true, forKey: "has_launched")
787
+ }
788
+ }
789
+ ```
790
+
791
+ ---
792
+
793
+ ## Conclusion
794
+
795
+ Protocol-abstraction is non-negotiable for testable keychain code. Every `SecItem` call should be behind `KeychainServiceProtocol` so that 95%+ of your test suite runs against `MockKeychainService` with zero entitlement requirements and zero CI flakiness. Reserve real-keychain integration tests for a dedicated test plan on physical devices.
796
+
797
+ Three insights most guides miss: (1) the simulator silently returns biometric-protected items without prompting - tests appear to validate biometric gates but test nothing; (2) TN3137's distinction between file-based and data protection keychains means `security create-keychain` in CI creates the wrong keychain type; (3) mutation testing reveals that even high-coverage suites fail to catch inverted conditionals and removed side effects - the exact mutations that create real vulnerabilities.
798
+
799
+ ---
800
+
801
+ ## Summary Checklist
802
+
803
+ 1. **Protocol abstraction** - All keychain access goes through `KeychainServiceProtocol`; no direct `SecItem*` calls in business logic
804
+ 2. **Mock with injectable errors** - `MockKeychainService` supports `errorToThrow` for testing `errSecDuplicateItem`, `errSecAuthFailed`, `errSecInteractionNotAllowed`, and `errSecItemNotFound` paths
805
+ 3. **setUp/tearDown cleanup** - Every integration test using real keychain has both pre-test and post-test cleanup with a test-specific `kSecAttrService`
806
+ 4. **Secure Enclave guard** - All SE tests use `try XCTSkipUnless(SecureEnclave.isAvailable, ...)` or protocol-based fallback; never call `SecureEnclave.P256.*` unconditionally
807
+ 5. **Biometric mock** - `LAContext` wrapped behind protocol or subclass mock; tests cover success, user cancel, lockout, and not-enrolled scenarios
808
+ 6. **Simulator/device split** - Two Xcode test plans: `CITests` (mock-based, simulator-safe) and `DeviceTests` (real keychain, SE, biometrics on physical device)
809
+ 7. **CI keychain setup** - GitHub Actions calls `security set-key-partition-list` after cert import; test target has host app with Keychain Sharing capability enabled
810
+ 8. **CryptoKit round-trips** - Encrypt→decrypt and sign→verify tests for AES-GCM, ChaChaPoly, P256, Curve25519; wrong-key failure tests included
811
+ 9. **Error path coverage** - Every `OSStatus` code the app can encounter has a corresponding test with injected mock failure
812
+ 10. **Migration testing** - UserDefaults→Keychain migration tested with isolated `UserDefaults(suiteName:)` and mock keychain; verifies source cleared after migration
813
+ 11. **Mutation testing baseline** - Muter mutation score ≥80% for security-critical code paths; `RelationalOperatorReplacement` and `RemoveSideEffects` operators enabled