@mmerterden/multi-agent-pipeline 20.2.1 → 20.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (621) hide show
  1. package/CHANGELOG.md +912 -1
  2. package/README.md +104 -81
  3. package/README.tr.md +103 -62
  4. package/docs/FIGMA_PIPELINE.md +35 -35
  5. package/docs/adr/0006-skills-core-external-split.md +1 -1
  6. package/docs/adr/0007-multi-tool-adapter-framework.md +6 -0
  7. package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +7 -0
  8. package/docs/architecture.md +50 -14
  9. package/docs/best-practices.md +1 -1
  10. package/docs/ecosystem.md +56 -32
  11. package/docs/facts.json +10 -10
  12. package/docs/features.md +97 -5
  13. package/docs/recovery-guide.md +7 -14
  14. package/docs/server-readiness.md +31 -24
  15. package/index.js +1 -1
  16. package/install/_common.mjs +3 -5
  17. package/install/_platform-filter.mjs +23 -1
  18. package/install/_unattended-profile.mjs +321 -75
  19. package/install/claude.mjs +51 -10
  20. package/install/codex.mjs +2 -0
  21. package/install/copilot.mjs +2 -0
  22. package/install/index.mjs +30 -17
  23. package/install/templates/claude-hooks.json +16 -5
  24. package/install/templates/copilot-instructions.md +1 -1
  25. package/install/templates/multi-agent-autopilot-awake.plist.template +48 -0
  26. package/install/templates/multi-agent-autopilot.plist.template +12 -5
  27. package/install/unattended-profile-legacy.json +80 -0
  28. package/manifest.json +616 -483
  29. package/package.json +8 -3
  30. package/pipeline/agents/code-reviewer.md +10 -0
  31. package/pipeline/agents/plan-critic.md +98 -0
  32. package/pipeline/agents/security-auditor.md +10 -0
  33. package/pipeline/agents/task-clarifier.md +10 -0
  34. package/pipeline/commands/multi-agent/SKILL.md +2 -2
  35. package/pipeline/commands/multi-agent/analysis/SKILL.md +6 -2
  36. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +12 -1
  37. package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +4 -0
  38. package/pipeline/commands/multi-agent/autopilot/SKILL.md +6 -2
  39. package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +36 -6
  40. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +77 -12
  41. package/pipeline/commands/multi-agent/autopilot-status/SKILL.md +29 -8
  42. package/pipeline/commands/multi-agent/build-optimize/SKILL.md +4 -0
  43. package/pipeline/commands/multi-agent/channels/SKILL.md +9 -9
  44. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +5 -1
  45. package/pipeline/commands/multi-agent/create-jira/SKILL.md +4 -0
  46. package/pipeline/commands/multi-agent/design-check/SKILL.md +16 -11
  47. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +4 -0
  48. package/pipeline/commands/multi-agent/doctor/SKILL.md +4 -0
  49. package/pipeline/commands/multi-agent/feedback/SKILL.md +5 -1
  50. package/pipeline/commands/multi-agent/forget/SKILL.md +4 -0
  51. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +4 -0
  52. package/pipeline/commands/multi-agent/graph/SKILL.md +4 -0
  53. package/pipeline/commands/multi-agent/help/SKILL.md +37 -39
  54. package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +4 -0
  55. package/pipeline/commands/multi-agent/issue/SKILL.md +7 -1
  56. package/pipeline/commands/multi-agent/jira/SKILL.md +7 -1
  57. package/pipeline/commands/multi-agent/kill/SKILL.md +9 -3
  58. package/pipeline/commands/multi-agent/language/SKILL.md +4 -0
  59. package/pipeline/commands/multi-agent/log/SKILL.md +4 -0
  60. package/pipeline/commands/multi-agent/manual-test/SKILL.md +5 -0
  61. package/pipeline/commands/multi-agent/model/SKILL.md +4 -0
  62. package/pipeline/commands/multi-agent/prune-logs/SKILL.md +4 -0
  63. package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +4 -0
  64. package/pipeline/commands/multi-agent/purge/SKILL.md +4 -0
  65. package/pipeline/commands/multi-agent/refactor/SKILL.md +5 -0
  66. package/pipeline/commands/multi-agent/research/SKILL.md +49 -0
  67. package/pipeline/commands/multi-agent/resume/SKILL.md +29 -6
  68. package/pipeline/commands/multi-agent/review/SKILL.md +28 -9
  69. package/pipeline/commands/multi-agent/review-analysis/SKILL.md +5 -1
  70. package/pipeline/commands/multi-agent/review-issue/SKILL.md +4 -0
  71. package/pipeline/commands/multi-agent/review-jira/SKILL.md +4 -0
  72. package/pipeline/commands/multi-agent/route-off/SKILL.md +4 -0
  73. package/pipeline/commands/multi-agent/route-on/SKILL.md +4 -0
  74. package/pipeline/commands/multi-agent/route-status/SKILL.md +4 -0
  75. package/pipeline/commands/multi-agent/routines/SKILL.md +4 -0
  76. package/pipeline/commands/multi-agent/save/SKILL.md +6 -2
  77. package/pipeline/commands/multi-agent/scaffold/SKILL.md +47 -0
  78. package/pipeline/commands/multi-agent/scan/SKILL.md +4 -0
  79. package/pipeline/commands/multi-agent/search/SKILL.md +12 -8
  80. package/pipeline/commands/multi-agent/security-review/SKILL.md +4 -0
  81. package/pipeline/commands/multi-agent/serve/SKILL.md +62 -0
  82. package/pipeline/commands/multi-agent/setup/SKILL.md +27 -36
  83. package/pipeline/commands/multi-agent/stack/SKILL.md +4 -0
  84. package/pipeline/commands/multi-agent/status/SKILL.md +10 -9
  85. package/pipeline/commands/multi-agent/steer/SKILL.md +5 -1
  86. package/pipeline/commands/multi-agent/store-ready/SKILL.md +4 -0
  87. package/pipeline/commands/multi-agent/sync/SKILL.md +13 -13
  88. package/pipeline/commands/multi-agent/test/SKILL.md +4 -0
  89. package/pipeline/commands/multi-agent/test-accessibility/SKILL.md +4 -0
  90. package/pipeline/commands/multi-agent/test-dark-mode/SKILL.md +4 -0
  91. package/pipeline/commands/multi-agent/test-dynamic-type/SKILL.md +4 -0
  92. package/pipeline/commands/multi-agent/test-screenshots/SKILL.md +5 -1
  93. package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +4 -0
  94. package/pipeline/commands/multi-agent/uninstall/SKILL.md +5 -1
  95. package/pipeline/commands/multi-agent/update/SKILL.md +4 -0
  96. package/pipeline/contract/CHANGELOG.md +74 -0
  97. package/pipeline/contract/README.md +126 -0
  98. package/pipeline/contract/build.mjs +427 -0
  99. package/pipeline/contract/fixtures/answer-result.json +11 -0
  100. package/pipeline/contract/fixtures/error-invalid-request.json +8 -0
  101. package/pipeline/contract/fixtures/error-unauthorized.json +5 -0
  102. package/pipeline/contract/fixtures/error-unsigned.json +5 -0
  103. package/pipeline/contract/fixtures/issues-empty.json +18 -0
  104. package/pipeline/contract/fixtures/launch-plan.json +31 -0
  105. package/pipeline/contract/fixtures/runs-awaiting-question.json +70 -0
  106. package/pipeline/contract/fixtures/runs-empty.json +6 -0
  107. package/pipeline/contract/fixtures/runs-failed.json +84 -0
  108. package/pipeline/contract/fixtures/runs-old-schema.json +70 -0
  109. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +101 -0
  110. package/pipeline/contract/fixtures/runs-pr-opened.json +106 -0
  111. package/pipeline/contract/fixtures/runs-running.json +84 -0
  112. package/pipeline/contract/fixtures/worktrees-empty.json +4 -0
  113. package/pipeline/contract/frozen/toolbox.json +107 -0
  114. package/pipeline/contract/manifest.json +263 -0
  115. package/pipeline/contract/types/index.d.ts +343 -0
  116. package/pipeline/lib/_jira-auth.sh +6 -2
  117. package/pipeline/lib/account-resolver.sh +1 -1
  118. package/pipeline/lib/autopilot-state.sh +19 -0
  119. package/pipeline/lib/context-link-extractor.sh +12 -5
  120. package/pipeline/lib/credential-inventory.sh +12 -5
  121. package/pipeline/lib/credential-store.sh +116 -185
  122. package/pipeline/lib/fetch-confluence.sh +44 -3
  123. package/pipeline/lib/fetch-document.sh +3 -4
  124. package/pipeline/lib/fetch-fortify.sh +1 -1
  125. package/pipeline/lib/figma-mcp-refresh.sh +2 -2
  126. package/pipeline/lib/figma-token.sh +5 -1
  127. package/pipeline/lib/issue-fetcher.sh +233 -16
  128. package/pipeline/lib/json-file-lock.mjs +172 -0
  129. package/pipeline/lib/model-dispatch.sh +21 -12
  130. package/pipeline/lib/model-rung.sh +6 -1
  131. package/pipeline/lib/multi-repo-pipeline.sh +1 -1
  132. package/pipeline/lib/outbound-gate.mjs +46 -16
  133. package/pipeline/lib/parse-complaints.sh +14 -7
  134. package/pipeline/lib/plan-todos.sh +3 -3
  135. package/pipeline/lib/post-pr-review.sh +9 -9
  136. package/pipeline/lib/pr-request-location.mjs +85 -0
  137. package/pipeline/lib/regular-file.mjs +153 -0
  138. package/pipeline/lib/repo-hygiene.sh +17 -0
  139. package/pipeline/lib/route-state.sh +5 -1
  140. package/pipeline/lib/run-paths.sh +3 -2
  141. package/pipeline/lib/stack-detect.sh +19 -1
  142. package/pipeline/lib/unattended-profile-check.mjs +178 -0
  143. package/pipeline/lib/unattended-settings-location.mjs +28 -0
  144. package/pipeline/lib/unattended.mjs +76 -0
  145. package/pipeline/lib/unattended.sh +32 -0
  146. package/pipeline/lib/untrusted.mjs +76 -0
  147. package/pipeline/lib/user-facing.mjs +82 -0
  148. package/pipeline/lib/user-facing.sh +58 -0
  149. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  150. package/pipeline/multi-agent-refs/analysis/evidence.md +4 -0
  151. package/pipeline/multi-agent-refs/analysis/locked.md +2 -2
  152. package/pipeline/multi-agent-refs/analysis/render.md +4 -3
  153. package/pipeline/multi-agent-refs/analysis/resolve.md +3 -1
  154. package/pipeline/multi-agent-refs/analysis/synthesis.md +4 -5
  155. package/pipeline/multi-agent-refs/analysis-template.md +10 -17
  156. package/pipeline/multi-agent-refs/channels/jira.md +1 -1
  157. package/pipeline/multi-agent-refs/component-dispatch.md +3 -3
  158. package/pipeline/multi-agent-refs/conventions-defaults.md +32 -32
  159. package/pipeline/multi-agent-refs/cross-cli-contract.md +10 -17
  160. package/pipeline/multi-agent-refs/features/autopilot-circuit-breaker.md +37 -9
  161. package/pipeline/multi-agent-refs/features/autopilot-operations.md +277 -0
  162. package/pipeline/multi-agent-refs/features/constitution.md +196 -0
  163. package/pipeline/multi-agent-refs/features/doctor.md +6 -3
  164. package/pipeline/multi-agent-refs/features/external-context-injection.md +6 -1
  165. package/pipeline/multi-agent-refs/features/jira-context.md +1 -1
  166. package/pipeline/multi-agent-refs/features/maturity-followup.md +43 -23
  167. package/pipeline/multi-agent-refs/features/model-fallback.md +9 -0
  168. package/pipeline/multi-agent-refs/features/phone-api.md +306 -0
  169. package/pipeline/multi-agent-refs/features/plan-critic.md +159 -0
  170. package/pipeline/multi-agent-refs/features/research.md +150 -0
  171. package/pipeline/multi-agent-refs/features/review-decision.md +185 -0
  172. package/pipeline/multi-agent-refs/features/scaffold.md +160 -0
  173. package/pipeline/multi-agent-refs/features/security-audit.md +6 -2
  174. package/pipeline/multi-agent-refs/features/skill-conformance.md +4 -1
  175. package/pipeline/multi-agent-refs/features/stack-adapters.md +116 -0
  176. package/pipeline/multi-agent-refs/features/unattended-gates.md +316 -0
  177. package/pipeline/multi-agent-refs/features/unattended-security.md +731 -0
  178. package/pipeline/multi-agent-refs/features/url-enrichment.md +2 -2
  179. package/pipeline/multi-agent-refs/features/usage-reporting.md +127 -35
  180. package/pipeline/multi-agent-refs/features/verify-by-test.md +1 -1
  181. package/pipeline/multi-agent-refs/features/visual-evidence.md +7 -7
  182. package/pipeline/multi-agent-refs/keychain.md +6 -11
  183. package/pipeline/multi-agent-refs/payload-contracts.md +2 -2
  184. package/pipeline/multi-agent-refs/phases/log-format.md +2 -3
  185. package/pipeline/multi-agent-refs/phases/modes.md +10 -12
  186. package/pipeline/multi-agent-refs/phases/operations.md +11 -5
  187. package/pipeline/multi-agent-refs/phases/phase-0-init.md +73 -81
  188. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +22 -22
  189. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +42 -66
  190. package/pipeline/multi-agent-refs/phases/phase-3-review.md +45 -79
  191. package/pipeline/multi-agent-refs/phases/phase-4-commit.md +28 -38
  192. package/pipeline/multi-agent-refs/phases/phase-5-report.md +27 -25
  193. package/pipeline/multi-agent-refs/phases.md +1 -1
  194. package/pipeline/multi-agent-refs/picker-contract.md +1 -1
  195. package/pipeline/multi-agent-refs/progress-contract.md +13 -16
  196. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  197. package/pipeline/multi-agent-refs/research/engine.md +91 -0
  198. package/pipeline/multi-agent-refs/rules.md +6 -4
  199. package/pipeline/multi-agent-refs/setup/repo-discovery.md +2 -2
  200. package/pipeline/multi-agent-refs/tracker-contract.md +2 -2
  201. package/pipeline/multi-agent-refs/unattended-contract.md +68 -16
  202. package/pipeline/rules/figma-pipeline.md +12 -12
  203. package/pipeline/schemas/agent-state.schema.json +480 -18
  204. package/pipeline/schemas/analysis-spec.schema.json +4 -4
  205. package/pipeline/schemas/answer-request.schema.json +24 -0
  206. package/pipeline/schemas/answer-result.schema.json +28 -0
  207. package/pipeline/schemas/autopilot-config.schema.json +111 -13
  208. package/pipeline/schemas/command-parameters.schema.json +99 -0
  209. package/pipeline/schemas/constitution.schema.json +56 -0
  210. package/pipeline/schemas/contract-error.schema.json +52 -0
  211. package/pipeline/schemas/design-check-config.schema.json +5 -1
  212. package/pipeline/schemas/issues.schema.json +61 -0
  213. package/pipeline/schemas/launch-plan.schema.json +46 -0
  214. package/pipeline/schemas/launch-request.schema.json +45 -0
  215. package/pipeline/schemas/launch.json +61 -0
  216. package/pipeline/schemas/launch.schema.json +84 -0
  217. package/pipeline/schemas/phases.json +2 -2
  218. package/pipeline/schemas/phases.schema.json +68 -0
  219. package/pipeline/schemas/phone-devices.schema.json +61 -0
  220. package/pipeline/schemas/phone-signed-request.schema.json +67 -0
  221. package/pipeline/schemas/plan-critique.schema.json +99 -0
  222. package/pipeline/schemas/plan-todos.schema.json +7 -7
  223. package/pipeline/schemas/planning-output.schema.json +5 -0
  224. package/pipeline/schemas/pr-request.schema.json +46 -0
  225. package/pipeline/schemas/prefs.schema.json +79 -8
  226. package/pipeline/schemas/research-output.schema.json +118 -0
  227. package/pipeline/schemas/review-file-exclusions.schema.json +25 -0
  228. package/pipeline/schemas/reviewer-output.schema.json +40 -4
  229. package/pipeline/schemas/run-questions.json +392 -0
  230. package/pipeline/schemas/run-questions.schema.json +118 -0
  231. package/pipeline/schemas/runs-index.schema.json +189 -0
  232. package/pipeline/schemas/scaffold-manifest.schema.json +43 -0
  233. package/pipeline/schemas/secret-patterns.schema.json +28 -0
  234. package/pipeline/schemas/stack-adapters.json +527 -0
  235. package/pipeline/schemas/stack-adapters.schema.json +184 -0
  236. package/pipeline/schemas/token-budget.json +1 -1
  237. package/pipeline/schemas/token-budget.schema.json +26 -0
  238. package/pipeline/schemas/triage-output.schema.json +64 -3
  239. package/pipeline/schemas/unattended-policy.json +139 -0
  240. package/pipeline/schemas/unattended-policy.schema.json +73 -0
  241. package/pipeline/schemas/unattended-profile.json +248 -0
  242. package/pipeline/schemas/unattended-profile.schema.json +198 -0
  243. package/pipeline/schemas/worktrees.schema.json +51 -0
  244. package/pipeline/scripts/README.md +1 -0
  245. package/pipeline/scripts/_autopilot-config.mjs +130 -0
  246. package/pipeline/scripts/_autopilot-ops.mjs +567 -0
  247. package/pipeline/scripts/_autopilot-outcomes.mjs +174 -0
  248. package/pipeline/scripts/_command-contract.mjs +384 -0
  249. package/pipeline/scripts/_cost.mjs +40 -0
  250. package/pipeline/scripts/_notices.mjs +160 -0
  251. package/pipeline/scripts/_phone-auth.mjs +485 -0
  252. package/pipeline/scripts/_pre-existing.mjs +294 -0
  253. package/pipeline/scripts/_redact.mjs +77 -0
  254. package/pipeline/scripts/_run-paths.mjs +4 -2
  255. package/pipeline/scripts/_stack-adapter.mjs +678 -0
  256. package/pipeline/scripts/_stack-routing.mjs +1 -1
  257. package/pipeline/scripts/agent-guard.py +348 -37
  258. package/pipeline/scripts/agent-guard.sh +41 -13
  259. package/pipeline/scripts/analysis-story-tree.mjs +79 -3
  260. package/pipeline/scripts/answer-question.mjs +181 -0
  261. package/pipeline/scripts/audit-log-rotate.sh +1 -4
  262. package/pipeline/scripts/audit-log.sh +4 -4
  263. package/pipeline/scripts/autopilot-arming.mjs +389 -21
  264. package/pipeline/scripts/autopilot-awake.mjs +255 -0
  265. package/pipeline/scripts/autopilot-intake.mjs +137 -36
  266. package/pipeline/scripts/autopilot-menubar.swift +156 -44
  267. package/pipeline/scripts/autopilot-publish.mjs +1625 -0
  268. package/pipeline/scripts/autopilot-runner.mjs +1678 -222
  269. package/pipeline/scripts/autopilot-status.sh +198 -33
  270. package/pipeline/scripts/build-lock.sh +120 -0
  271. package/pipeline/scripts/build-references.mjs +4 -1
  272. package/pipeline/scripts/build-stack-plugins.mjs +59 -22
  273. package/pipeline/scripts/capture-flush.sh +1 -1
  274. package/pipeline/scripts/capture-resume.sh +13 -9
  275. package/pipeline/scripts/check-derived-drift.mjs +52 -11
  276. package/pipeline/scripts/commands.mjs +88 -0
  277. package/pipeline/scripts/constitution.mjs +362 -0
  278. package/pipeline/scripts/contract-server.mjs +776 -0
  279. package/pipeline/scripts/cost-analyze.mjs +89 -39
  280. package/pipeline/scripts/diff-explain.mjs +12 -1
  281. package/pipeline/scripts/doctor.mjs +77 -28
  282. package/pipeline/scripts/evidence-gate.mjs +192 -12
  283. package/pipeline/scripts/feedback-send.mjs +4 -2
  284. package/pipeline/scripts/gate-ledger.mjs +449 -0
  285. package/pipeline/scripts/gc-abandoned.sh +132 -13
  286. package/pipeline/scripts/gen-facts.mjs +31 -15
  287. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
  288. package/pipeline/scripts/github-ssh-setup.sh +140 -29
  289. package/pipeline/scripts/graph-mermaid.mjs +4 -1
  290. package/pipeline/scripts/issues.mjs +236 -0
  291. package/pipeline/scripts/jira-attach.sh +6 -2
  292. package/pipeline/scripts/jira-search.sh +4 -3
  293. package/pipeline/scripts/keychain-save.sh +125 -24
  294. package/pipeline/scripts/keychain.py +63 -93
  295. package/pipeline/scripts/launch-request.mjs +747 -0
  296. package/pipeline/scripts/localize-commands.mjs +4 -10
  297. package/pipeline/scripts/log-metric.sh +6 -5
  298. package/pipeline/scripts/maturity-followup.mjs +13 -4
  299. package/pipeline/scripts/memory-save.sh +25 -0
  300. package/pipeline/scripts/migrate-prefs.mjs +4 -3
  301. package/pipeline/scripts/open-questions-gate.mjs +276 -0
  302. package/pipeline/scripts/phase-tracker.sh +41 -27
  303. package/pipeline/scripts/phase0-exit-gate.mjs +22 -4
  304. package/pipeline/scripts/phone-devices.mjs +224 -0
  305. package/pipeline/scripts/plan-coverage-gate.mjs +200 -66
  306. package/pipeline/scripts/plan-critique-gate.mjs +591 -0
  307. package/pipeline/scripts/pr-request.mjs +188 -0
  308. package/pipeline/scripts/pre-commit-check.sh +115 -4
  309. package/pipeline/scripts/probe-evidence-capability.sh +44 -5
  310. package/pipeline/scripts/record-phase.mjs +71 -0
  311. package/pipeline/scripts/render-agent-log-cost.sh +17 -2
  312. package/pipeline/scripts/render-cost-summary.sh +1 -1
  313. package/pipeline/scripts/render-work-summary.sh +1 -1
  314. package/pipeline/scripts/require-supported-version.sh +4 -1
  315. package/pipeline/scripts/research-gate.mjs +704 -0
  316. package/pipeline/scripts/review-decision-gate.mjs +403 -0
  317. package/pipeline/scripts/routine-registry.mjs +5 -2
  318. package/pipeline/scripts/runs-index.mjs +135 -27
  319. package/pipeline/scripts/scaffold-gate.mjs +393 -0
  320. package/pipeline/scripts/skill-conformance.mjs +25 -8
  321. package/pipeline/scripts/skill-siblings.mjs +2 -1
  322. package/pipeline/scripts/smoke-cross-cli-behavior.sh +32 -6
  323. package/pipeline/scripts/smoke-schema-validation.sh +6 -2
  324. package/pipeline/scripts/spec-consistency-gate.mjs +469 -0
  325. package/pipeline/scripts/symbol-existence-gate.mjs +450 -0
  326. package/pipeline/scripts/test-gap-scan.mjs +40 -2
  327. package/pipeline/scripts/test-integrity-gate.mjs +20 -4
  328. package/pipeline/scripts/test-strength.mjs +484 -0
  329. package/pipeline/scripts/test-summary.mjs +651 -0
  330. package/pipeline/scripts/triage-memory.mjs +49 -9
  331. package/pipeline/scripts/unattended_policy.py +2786 -0
  332. package/pipeline/scripts/uninstall.mjs +10 -10
  333. package/pipeline/scripts/update-issue-progress.sh +1 -1
  334. package/pipeline/scripts/usage-identity.mjs +288 -0
  335. package/pipeline/scripts/usage-register.mjs +185 -65
  336. package/pipeline/scripts/usage-report.mjs +230 -66
  337. package/pipeline/scripts/validate-complaint-doc.mjs +28 -10
  338. package/pipeline/scripts/validate-planning.mjs +6 -0
  339. package/pipeline/scripts/verify-citations.mjs +151 -38
  340. package/pipeline/scripts/verify.mjs +58 -18
  341. package/pipeline/scripts/worktree-prepare.sh +126 -0
  342. package/pipeline/scripts/worktrees.mjs +124 -0
  343. package/pipeline/scripts/write-state.mjs +48 -17
  344. package/pipeline/skills/.skill-manifest.json +222 -226
  345. package/pipeline/skills/.skills-index.json +77 -88
  346. package/pipeline/skills/shared/README.md +44 -45
  347. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +3 -2
  348. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +3 -2
  349. package/pipeline/skills/shared/core/multi-agent/SKILL.md +10 -9
  350. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +6 -5
  351. package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +11 -3
  352. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +2 -1
  353. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +4 -3
  354. package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +32 -6
  355. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +66 -8
  356. package/pipeline/skills/shared/core/multi-agent-autopilot-status/SKILL.md +27 -9
  357. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +2 -1
  358. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +7 -4
  359. package/pipeline/skills/shared/core/multi-agent-complaint-analysis/SKILL.md +3 -2
  360. package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +2 -1
  361. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +7 -5
  362. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +2 -1
  363. package/pipeline/skills/shared/core/multi-agent-doctor/SKILL.md +3 -2
  364. package/pipeline/skills/shared/core/multi-agent-feedback/SKILL.md +2 -1
  365. package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +2 -1
  366. package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +2 -1
  367. package/pipeline/skills/shared/core/multi-agent-graph/SKILL.md +2 -1
  368. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +2 -1
  369. package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -1
  370. package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +3 -2
  371. package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +2 -1
  372. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +7 -4
  373. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -1
  374. package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +2 -1
  375. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +2 -1
  376. package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +2 -1
  377. package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +2 -1
  378. package/pipeline/skills/shared/core/multi-agent-prune-prompts/SKILL.md +2 -1
  379. package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +2 -1
  380. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +2 -1
  381. package/pipeline/skills/shared/core/multi-agent-research/SKILL.md +35 -0
  382. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +7 -3
  383. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +7 -5
  384. package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +2 -1
  385. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +3 -2
  386. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +2 -1
  387. package/pipeline/skills/shared/core/multi-agent-route-off/SKILL.md +2 -1
  388. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +2 -1
  389. package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +2 -1
  390. package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +2 -1
  391. package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +3 -2
  392. package/pipeline/skills/shared/core/multi-agent-scaffold/SKILL.md +30 -0
  393. package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +2 -1
  394. package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +4 -3
  395. package/pipeline/skills/shared/core/multi-agent-security-review/SKILL.md +2 -1
  396. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +60 -0
  397. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +8 -8
  398. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +2 -1
  399. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +7 -8
  400. package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +2 -1
  401. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +2 -1
  402. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +10 -10
  403. package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +2 -1
  404. package/pipeline/skills/shared/core/multi-agent-test-accessibility/SKILL.md +2 -1
  405. package/pipeline/skills/shared/core/multi-agent-test-dark-mode/SKILL.md +2 -1
  406. package/pipeline/skills/shared/core/multi-agent-test-dynamic-type/SKILL.md +2 -1
  407. package/pipeline/skills/shared/core/multi-agent-test-screenshots/SKILL.md +2 -1
  408. package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +2 -1
  409. package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +3 -2
  410. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +2 -1
  411. package/pipeline/skills/shared/external/NOTICE-avdlee-swiftui-agent-skill.md +46 -0
  412. package/pipeline/skills/shared/external/NOTICE-dimillian-skills.md +9 -3
  413. package/pipeline/skills/shared/external/NOTICE-paul-hudson-skills.md +54 -0
  414. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +9 -11
  415. package/pipeline/skills/shared/external/NOTICE-vibeship-spawner-skills.md +203 -0
  416. package/pipeline/skills/shared/external/NOTICE-xcode-build-skills.md +10 -3
  417. package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +131 -25
  418. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -3
  419. package/pipeline/skills/shared/external/alarmkit/SKILL.md +2 -1
  420. package/pipeline/skills/shared/external/android-architecture/SKILL.md +85 -76
  421. package/pipeline/skills/shared/external/android-build-quality-gates/SKILL.md +51 -3
  422. package/pipeline/skills/shared/external/android-build-quality-gates/references/patterns.md +9 -0
  423. package/pipeline/skills/shared/external/android-datastore/SKILL.md +4 -3
  424. package/pipeline/skills/shared/external/android-design-tokens-codegen/SKILL.md +4 -3
  425. package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +106 -181
  426. package/pipeline/skills/shared/external/android-jetpack-compose-expert/references/patterns.md +147 -0
  427. package/pipeline/skills/shared/external/android-mvi-viewmodel/SKILL.md +45 -4
  428. package/pipeline/skills/shared/external/android-performance/SKILL.md +27 -2
  429. package/pipeline/skills/shared/external/android-performance/references/patterns.md +37 -37
  430. package/pipeline/skills/shared/external/api-patterns/SKILL.md +111 -67
  431. package/pipeline/skills/shared/external/api-patterns/references/contract-details.md +128 -0
  432. package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +136 -186
  433. package/pipeline/skills/shared/external/api-security-best-practices/references/abuse-controls.md +140 -0
  434. package/pipeline/skills/shared/external/api-security-best-practices/references/identity-and-access.md +207 -0
  435. package/pipeline/skills/shared/external/api-security-best-practices/references/operations.md +66 -0
  436. package/pipeline/skills/shared/external/api-security-best-practices/references/request-handling.md +175 -0
  437. package/pipeline/skills/shared/external/app-clips/SKILL.md +2 -0
  438. package/pipeline/skills/shared/external/app-intents/SKILL.md +2 -0
  439. package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +4 -3
  440. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +2 -0
  441. package/pipeline/skills/shared/external/app-store-review/SKILL.md +2 -0
  442. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +2 -0
  443. package/pipeline/skills/shared/external/architecture/SKILL.md +106 -39
  444. package/pipeline/skills/shared/external/architecture/references/adr-and-review.md +76 -0
  445. package/pipeline/skills/shared/external/authentication/SKILL.md +2 -0
  446. package/pipeline/skills/shared/external/avkit/SKILL.md +2 -0
  447. package/pipeline/skills/shared/external/background-processing/SKILL.md +2 -1
  448. package/pipeline/skills/shared/external/backlog/SKILL.md +3 -2
  449. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +2 -0
  450. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +1 -1
  451. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +3 -2
  452. package/pipeline/skills/shared/external/clean-code/SKILL.md +192 -90
  453. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +2 -1
  454. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +1 -1
  455. package/pipeline/skills/shared/external/compose-components/SKILL.md +4 -4
  456. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +22 -22
  457. package/pipeline/skills/shared/external/compose-navigation/references/patterns.md +10 -10
  458. package/pipeline/skills/shared/external/compose-testing/SKILL.md +13 -6
  459. package/pipeline/skills/shared/external/compose-testing/references/patterns.md +59 -59
  460. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +2 -0
  461. package/pipeline/skills/shared/external/context-compression/SKILL.md +118 -250
  462. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +2 -0
  463. package/pipeline/skills/shared/external/core-data/SKILL.md +2 -0
  464. package/pipeline/skills/shared/external/core-motion/SKILL.md +2 -0
  465. package/pipeline/skills/shared/external/core-nfc/SKILL.md +2 -0
  466. package/pipeline/skills/shared/external/coreml/SKILL.md +2 -1
  467. package/pipeline/skills/shared/external/council/SKILL.md +2 -1
  468. package/pipeline/skills/shared/external/cryptokit/SKILL.md +2 -0
  469. package/pipeline/skills/shared/external/css-modern/SKILL.md +3 -2
  470. package/pipeline/skills/shared/external/database-patterns/SKILL.md +3 -2
  471. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +2 -0
  472. package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +130 -20
  473. package/pipeline/skills/shared/external/debugging-strategies/references/hard-cases.md +54 -0
  474. package/pipeline/skills/shared/external/device-integrity/SKILL.md +2 -0
  475. package/pipeline/skills/shared/external/docker-expert/SKILL.md +137 -381
  476. package/pipeline/skills/shared/external/docker-expert/references/patterns.md +98 -0
  477. package/pipeline/skills/shared/external/energykit/SKILL.md +2 -1
  478. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +3 -1
  479. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +2 -2
  480. package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +116 -185
  481. package/pipeline/skills/shared/external/fastapi-pro/references/app-structure.md +235 -0
  482. package/pipeline/skills/shared/external/fastapi-pro/references/testing-and-deployment.md +69 -0
  483. package/pipeline/skills/shared/external/firebase/SKILL.md +4 -3
  484. package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +151 -293
  485. package/pipeline/skills/shared/external/github-actions-templates/references/patterns.md +96 -0
  486. package/pipeline/skills/shared/external/healthkit/SKILL.md +2 -0
  487. package/pipeline/skills/shared/external/hig-components-content/SKILL.md +69 -72
  488. package/pipeline/skills/shared/external/hig-components-content/references/content-views.md +111 -0
  489. package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +77 -86
  490. package/pipeline/skills/shared/external/hig-components-layout/references/containers.md +98 -0
  491. package/pipeline/skills/shared/external/hig-components-status/SKILL.md +150 -78
  492. package/pipeline/skills/shared/external/hig-components-system/SKILL.md +76 -97
  493. package/pipeline/skills/shared/external/hig-components-system/references/surfaces.md +98 -0
  494. package/pipeline/skills/shared/external/hig-foundations/SKILL.md +48 -76
  495. package/pipeline/skills/shared/external/hig-foundations/references/foundations-detail.md +132 -0
  496. package/pipeline/skills/shared/external/hig-inputs/SKILL.md +147 -106
  497. package/pipeline/skills/shared/external/hig-patterns/SKILL.md +61 -77
  498. package/pipeline/skills/shared/external/hig-patterns/references/patterns.md +92 -0
  499. package/pipeline/skills/shared/external/hig-platforms/SKILL.md +147 -77
  500. package/pipeline/skills/shared/external/hig-technologies/SKILL.md +61 -121
  501. package/pipeline/skills/shared/external/hig-technologies/references/technologies.md +108 -0
  502. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +2 -0
  503. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +1 -1
  504. package/pipeline/skills/shared/external/html-semantic/SKILL.md +3 -2
  505. package/pipeline/skills/shared/external/humanizer/SKILL.md +2 -1
  506. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +2 -0
  507. package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +2 -1
  508. package/pipeline/skills/shared/external/ios-coding-standard/references/STANDARD.md +14 -2
  509. package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +2 -2
  510. package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +4 -3
  511. package/pipeline/skills/shared/external/ios-localization/SKILL.md +8 -6
  512. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +2 -2
  513. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +11 -11
  514. package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +2 -1
  515. package/pipeline/skills/shared/external/ios-networking/SKILL.md +2 -0
  516. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +2 -0
  517. package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +102 -193
  518. package/pipeline/skills/shared/external/kotlin-coroutines-expert/references/patterns.md +103 -0
  519. package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -2
  520. package/pipeline/skills/shared/external/live-activities/evals/evals.json +2 -2
  521. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +7 -9
  522. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +3 -3
  523. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +2 -2
  524. package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +4 -3
  525. package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +5 -3
  526. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +2 -0
  527. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +1 -1
  528. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +2 -0
  529. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +1 -1
  530. package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +149 -46
  531. package/pipeline/skills/shared/external/monorepo-architect/references/patterns.md +70 -0
  532. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +2 -0
  533. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +1 -1
  534. package/pipeline/skills/shared/external/natural-language/SKILL.md +2 -0
  535. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +3 -2
  536. package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +91 -21
  537. package/pipeline/skills/shared/external/nodejs-backend-patterns/references/runtime-patterns.md +247 -0
  538. package/pipeline/skills/shared/external/nodejs-backend-patterns/references/testing-and-frameworks.md +57 -0
  539. package/pipeline/skills/shared/external/observability-engineer/SKILL.md +155 -232
  540. package/pipeline/skills/shared/external/observability-engineer/references/patterns.md +75 -0
  541. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +2 -0
  542. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +2 -2
  543. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +18 -18
  544. package/pipeline/skills/shared/external/pdfkit/SKILL.md +2 -1
  545. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +2 -0
  546. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +1 -1
  547. package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -0
  548. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +2 -1
  549. package/pipeline/skills/shared/external/push-notifications/SKILL.md +2 -0
  550. package/pipeline/skills/shared/external/python-patterns/SKILL.md +3 -2
  551. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +3 -2
  552. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +2 -2
  553. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +1 -1
  554. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +3 -2
  555. package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +7 -7
  556. package/pipeline/skills/shared/external/retrofit-networking/references/patterns.md +69 -69
  557. package/pipeline/skills/shared/external/room-database/references/patterns.md +126 -126
  558. package/pipeline/skills/shared/external/search-first/SKILL.md +2 -1
  559. package/pipeline/skills/shared/external/security-review/SKILL.md +4 -3
  560. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +2 -2
  561. package/pipeline/skills/shared/external/signal-community/SKILL.md +1 -1
  562. package/pipeline/skills/shared/external/skill-creator/SKILL.md +2 -1
  563. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +2 -1
  564. package/pipeline/skills/shared/external/spm-build-analysis/SKILL.md +2 -0
  565. package/pipeline/skills/shared/external/storekit/SKILL.md +2 -0
  566. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +2 -0
  567. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +2 -1
  568. package/pipeline/skills/shared/external/swift-charts/SKILL.md +2 -1
  569. package/pipeline/skills/shared/external/swift-codable/SKILL.md +2 -0
  570. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +3 -1
  571. package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +5 -4
  572. package/pipeline/skills/shared/external/swift-concurrency-pro/SKILL.md +2 -1
  573. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +2 -0
  574. package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -1
  575. package/pipeline/skills/shared/external/swift-security/SKILL.md +2 -1
  576. package/pipeline/skills/shared/external/swift-testing/SKILL.md +2 -0
  577. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +2 -1
  578. package/pipeline/skills/shared/external/swift-testing-pro/references/new-features.md +10 -0
  579. package/pipeline/skills/shared/external/swiftdata/SKILL.md +2 -0
  580. package/pipeline/skills/shared/external/swiftdata-pro/SKILL.md +2 -1
  581. package/pipeline/skills/shared/external/swiftlint/SKILL.md +2 -0
  582. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +2 -0
  583. package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +3 -1
  584. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +2 -0
  585. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +2 -0
  586. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +2 -0
  587. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +2 -0
  588. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +3 -1
  589. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +3 -1
  590. package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +5 -4
  591. package/pipeline/skills/shared/external/swiftui-pro/SKILL.md +2 -1
  592. package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +5 -4
  593. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +2 -0
  594. package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +4 -3
  595. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +2 -0
  596. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +3 -2
  597. package/pipeline/skills/shared/external/testing-backend/SKILL.md +3 -2
  598. package/pipeline/skills/shared/external/tipkit/SKILL.md +2 -0
  599. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +3 -2
  600. package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -0
  601. package/pipeline/skills/shared/external/vue-composition/SKILL.md +3 -2
  602. package/pipeline/skills/shared/external/weatherkit/SKILL.md +2 -0
  603. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +3 -2
  604. package/pipeline/skills/shared/external/web-performance/SKILL.md +3 -2
  605. package/pipeline/skills/shared/external/web-testing/SKILL.md +3 -2
  606. package/pipeline/skills/shared/external/widgetkit/SKILL.md +2 -0
  607. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +1 -1
  608. package/pipeline/skills/shared/external/xcode-build-benchmark/SKILL.md +2 -0
  609. package/pipeline/skills/shared/external/xcode-build-fixer/SKILL.md +2 -0
  610. package/pipeline/skills/shared/external/xcode-build-orchestrator/SKILL.md +2 -0
  611. package/pipeline/skills/shared/external/xcode-compilation-analyzer/SKILL.md +2 -0
  612. package/pipeline/skills/shared/external/xcode-project-analyzer/SKILL.md +2 -0
  613. package/pipeline/skills/skills-index.md +40 -41
  614. package/docs/token-budget-history.md +0 -24
  615. package/pipeline/skills/shared/external/agentflow/SKILL.md +0 -199
  616. package/pipeline/skills/shared/external/android-ui-verification/SKILL.md +0 -66
  617. package/pipeline/skills/shared/external/api-security-best-practices/references/auth.md +0 -299
  618. package/pipeline/skills/shared/external/api-security-best-practices/references/input-validation.md +0 -255
  619. package/pipeline/skills/shared/external/api-security-best-practices/references/rate-limiting.md +0 -167
  620. package/pipeline/skills/shared/external/closed-loop-delivery/SKILL.md +0 -116
  621. package/pipeline/skills/shared/external/ios-developer/SKILL.md +0 -216
@@ -79,10 +79,10 @@ class BaselineProfileGenerator {
79
79
  device.findObject(By.text("Search")).click()
80
80
  device.waitForIdle()
81
81
 
82
- device.findObject(By.res("search_field")).text = "Istanbul"
82
+ device.findObject(By.res("search_field")).text = "London"
83
83
  device.waitForIdle()
84
84
 
85
- device.findObject(By.res("flight_card")).click()
85
+ device.findObject(By.res("order_card")).click()
86
86
  device.waitForIdle()
87
87
  }
88
88
  }
@@ -106,7 +106,7 @@ class BaselineProfileGenerator {
106
106
  ```kotlin
107
107
  // Mark a class as truly immutable (all properties never change after construction)
108
108
  @Immutable
109
- data class FlightUiModel(
109
+ data class OrderUiModel(
110
110
  val id: String,
111
111
  val route: String,
112
112
  val price: String,
@@ -116,8 +116,8 @@ data class FlightUiModel(
116
116
  // Mark a class as stable (Compose can track changes via equals)
117
117
  @Stable
118
118
  data class FilterState(
119
- val origin: String = "",
120
- val destination: String = "",
119
+ val store: String = "",
120
+ val region: String = "",
121
121
  val date: LocalDate? = null,
122
122
  )
123
123
  ```
@@ -132,19 +132,19 @@ implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8")
132
132
 
133
133
  // Usage
134
134
  @Immutable
135
- data class FlightListUiState(
136
- val flights: ImmutableList<FlightUiModel> = persistentListOf(),
135
+ data class OrderListUiState(
136
+ val orders: ImmutableList<OrderUiModel> = persistentListOf(),
137
137
  val isLoading: Boolean = false,
138
138
  )
139
139
 
140
140
  // Convert in ViewModel
141
- val uiState: StateFlow<FlightListUiState> = repository.getFlights()
142
- .map { flights ->
143
- FlightListUiState(
144
- flights = flights.map(::toUiModel).toImmutableList(),
141
+ val uiState: StateFlow<OrderListUiState> = repository.getOrders()
142
+ .map { orders ->
143
+ OrderListUiState(
144
+ orders = orders.map(::toUiModel).toImmutableList(),
145
145
  )
146
146
  }
147
- .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), FlightListUiState())
147
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), OrderListUiState())
148
148
  ```
149
149
 
150
150
  ### Strong Skipping Mode (Kotlin 2.0+)
@@ -224,17 +224,17 @@ efficiently diff items.
224
224
  // CORRECT: stable key from item ID
225
225
  LazyColumn {
226
226
  items(
227
- items = flights,
228
- key = { flight -> flight.id },
229
- ) { flight ->
230
- FlightCard(flight = flight)
227
+ items = orders,
228
+ key = { order -> order.id },
229
+ ) { order ->
230
+ OrderCard(order = order)
231
231
  }
232
232
  }
233
233
 
234
234
  // WRONG: no key -- full list diff on every change
235
235
  LazyColumn {
236
- items(flights) { flight ->
237
- FlightCard(flight = flight)
236
+ items(orders) { order ->
237
+ OrderCard(order = order)
238
238
  }
239
239
  }
240
240
  ```
@@ -248,14 +248,14 @@ LazyColumn {
248
248
  key = { it.id },
249
249
  contentType = { item ->
250
250
  when (item) {
251
- is FeedItem.Flight -> "flight"
251
+ is FeedItem.Order -> "order"
252
252
  is FeedItem.Hotel -> "hotel"
253
253
  is FeedItem.Ad -> "ad"
254
254
  }
255
255
  },
256
256
  ) { item ->
257
257
  when (item) {
258
- is FeedItem.Flight -> FlightCard(item)
258
+ is FeedItem.Order -> OrderCard(item)
259
259
  is FeedItem.Hotel -> HotelCard(item)
260
260
  is FeedItem.Ad -> AdBanner(item)
261
261
  }
@@ -270,16 +270,16 @@ similar to RecyclerView's view type system.
270
270
 
271
271
  ```kotlin
272
272
  // WRONG: formatting on every recomposition
273
- items(flights, key = { it.id }) { flight ->
273
+ items(orders, key = { it.id }) { order ->
274
274
  val formatted = SimpleDateFormat("HH:mm", Locale.getDefault())
275
- .format(Date(flight.departureTime))
275
+ .format(Date(order.placedAt))
276
276
  Text(formatted)
277
277
  }
278
278
 
279
279
  // CORRECT: precompute in ViewModel or UiModel
280
- data class FlightUiModel(
280
+ data class OrderUiModel(
281
281
  val id: String,
282
- val formattedDeparture: String, // precomputed
282
+ val formattedPlacedAt: String, // precomputed
283
283
  )
284
284
  ```
285
285
 
@@ -292,8 +292,8 @@ LazyColumn(
292
292
  // For custom behavior:
293
293
  flingBehavior = ScrollableDefaults.flingBehavior(),
294
294
  ) {
295
- items(flights, key = { it.id }) { flight ->
296
- FlightCard(flight = flight)
295
+ items(orders, key = { it.id }) { order ->
296
+ OrderCard(order = order)
297
297
  }
298
298
  }
299
299
  ```
@@ -448,7 +448,7 @@ class StartupBenchmark {
448
448
  pressHome()
449
449
  startActivityAndWait()
450
450
 
451
- val list = device.findObject(By.res("flight_list"))
451
+ val list = device.findObject(By.res("order_list"))
452
452
  list.setGestureMargin(device.displayWidth / 5)
453
453
  list.fling(Direction.DOWN)
454
454
  device.waitForIdle()
@@ -516,7 +516,7 @@ implementation("io.coil-kt:coil-compose:2.7.0")
516
516
 
517
517
  // Composable
518
518
  @Composable
519
- fun FlightImage(imageUrl: String, modifier: Modifier = Modifier) {
519
+ fun OrderImage(imageUrl: String, modifier: Modifier = Modifier) {
520
520
  AsyncImage(
521
521
  model = ImageRequest.Builder(LocalContext.current)
522
522
  .data(imageUrl)
@@ -524,7 +524,7 @@ fun FlightImage(imageUrl: String, modifier: Modifier = Modifier) {
524
524
  .memoryCacheKey(imageUrl)
525
525
  .diskCacheKey(imageUrl)
526
526
  .build(),
527
- contentDescription = "Flight image",
527
+ contentDescription = "Order image",
528
528
  modifier = modifier,
529
529
  contentScale = ContentScale.Crop,
530
530
  )
@@ -576,10 +576,10 @@ AsyncImage(
576
576
  ```kotlin
577
577
  AsyncImage(
578
578
  model = imageUrl,
579
- contentDescription = "Airline logo",
580
- placeholder = painterResource(R.drawable.placeholder_airline),
581
- error = painterResource(R.drawable.error_airline),
582
- fallback = painterResource(R.drawable.default_airline),
579
+ contentDescription = "Brand logo",
580
+ placeholder = painterResource(R.drawable.placeholder_brand),
581
+ error = painterResource(R.drawable.error_brand),
582
+ fallback = painterResource(R.drawable.default_brand),
583
583
  modifier = Modifier
584
584
  .size(48.dp)
585
585
  .clip(CircleShape),
@@ -592,7 +592,7 @@ AsyncImage(
592
592
 
593
593
  ```kotlin
594
594
  @Composable
595
- fun FlightList(flights: List<Flight>) {
595
+ fun OrderList(orders: List<Order>) {
596
596
  val listState = rememberLazyListState()
597
597
 
598
598
  // Only recalculates when the derived condition changes
@@ -602,7 +602,7 @@ fun FlightList(flights: List<Flight>) {
602
602
 
603
603
  Box {
604
604
  LazyColumn(state = listState) {
605
- items(flights, key = { it.id }) { FlightCard(it) }
605
+ items(orders, key = { it.id }) { OrderCard(it) }
606
606
  }
607
607
 
608
608
  if (showScrollToTop) {
@@ -640,12 +640,12 @@ fun DateDisplay(timestamp: Long) {
640
640
  ```kotlin
641
641
  @HiltViewModel
642
642
  class SearchViewModel @Inject constructor(
643
- private val searchUseCase: SearchFlightsUseCase,
643
+ private val searchUseCase: SearchOrdersUseCase,
644
644
  ) : ViewModel() {
645
645
 
646
646
  private val searchQuery = MutableStateFlow("")
647
647
 
648
- val searchResults: StateFlow<List<Flight>> = searchQuery
648
+ val searchResults: StateFlow<List<Order>> = searchQuery
649
649
  .debounce(300) // Wait 300ms after last keystroke
650
650
  .distinctUntilChanged()
651
651
  .filter { it.length >= 2 }
@@ -1,73 +1,117 @@
1
1
  ---
2
2
  name: api-patterns
3
- description: "API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. Use when choosing between REST, GraphQL and tRPC, or shaping response formats, versioning and pagination."
4
- risk: unknown
5
- source: community
6
- date_added: "2026-02-27"
3
+ description: "Choosing an API style (REST, GraphQL, gRPC, webhooks, events) and the contracts every style needs: versioning, cursor pagination, idempotency keys, RFC 9457 errors. Use when deciding how two systems talk or how a contract evolves."
4
+ metadata:
5
+ risk: safe
6
+ source: multi-agent-pipeline
7
+ date_added: "2026-09-25"
8
+ not-for: rest-api-design
7
9
  ---
8
10
 
9
11
  # API Patterns
10
12
 
11
- > API design principles and decision-making for 2025.
12
- > **Learn to THINK, not copy fixed patterns.**
13
-
14
- ## 📑 Topics
15
-
16
- | Topic | Covers | When it applies |
17
- |------|-------------|--------------|
18
- | API style | REST vs GraphQL vs tRPC decision tree | Choosing API type |
19
- | REST | Resource naming, HTTP methods, status codes | Designing REST API |
20
- | Response shape | Envelope pattern, error format, pagination | Response structure |
21
- | GraphQL | Schema design, when to use, security | Considering GraphQL |
22
- | tRPC | TypeScript monorepo, type safety | TS fullstack projects |
23
- | Versioning | URI/Header/Query versioning | API evolution planning |
24
- | Auth | JWT, OAuth, Passkey, API Keys | Auth pattern selection |
25
- | Rate limiting | Token bucket, sliding window | API protection |
26
- | Documentation | OpenAPI/Swagger best practices | Documentation |
27
- | Security testing | OWASP API Top 10, auth/authz testing | Security audits |
28
-
29
- ---
30
-
31
- ## 🔗 Related Skills
32
-
33
- | Need | Skill |
34
- |------|-------|
35
- | API implementation | `@[skills/backend-development]` |
36
- | Data structure | `@[skills/database-design]` |
37
- | Security details | `@[skills/security-hardening]` |
38
-
39
- ---
40
-
41
- ## ✅ Decision Checklist
42
-
43
- Before designing an API:
44
-
45
- - [ ] **Asked user about API consumers?**
46
- - [ ] **Chosen API style for THIS context?** (REST/GraphQL/tRPC)
47
- - [ ] **Defined consistent response format?**
48
- - [ ] **Planned versioning strategy?**
49
- - [ ] **Considered authentication needs?**
50
- - [ ] **Planned rate limiting?**
51
- - [ ] **Documentation approach defined?**
52
-
53
- ---
54
-
55
- ## ❌ Anti-Patterns
56
-
57
- **DON'T:**
58
- - Default to REST for everything
59
- - Use verbs in REST endpoints (/getUsers)
60
- - Return inconsistent response formats
61
- - Expose internal errors to clients
62
- - Skip rate limiting
63
-
64
- **DO:**
65
- - Choose API style based on context
66
- - Ask about client requirements
67
- - Document thoroughly
68
- - Use appropriate status codes
69
-
70
- ---
71
-
72
- ## When to Use
73
- This skill is applicable to execute the workflow or actions described in the overview.
13
+ An interface outlives the code on both sides of it. Clients ship on their own
14
+ schedule, mobile builds stay installed for years, and partner integrations get
15
+ written once and forgotten. The decisions here are the ones that are expensive
16
+ to reverse, so make them deliberately and write the reasoning down.
17
+
18
+ This skill covers the choice of style and the contracts that apply whatever
19
+ style wins. REST mechanics (URLs, verbs, status codes, cache headers, OpenAPI)
20
+ live in `rest-api-design`; security controls live in `api-security-best-practices`.
21
+
22
+ ## 1. Start from the consumers, not the technology
23
+
24
+ Answer these before naming a style:
25
+
26
+ - **Who calls it?** Your own frontend, other internal services, third parties
27
+ you do not control, or devices that update rarely.
28
+ - **What is the interaction shape?** Ask-and-answer, a long-running job, a
29
+ notification that something happened, or a continuous feed.
30
+ - **Who owns change?** If one team owns both ends, coupling is cheap. If the
31
+ caller is outside your release train, every change is a negotiation.
32
+ - **What does the network look like?** Browser, mobile on flaky links,
33
+ service mesh inside one data centre.
34
+
35
+ ## 2. Choosing a style
36
+
37
+ | Situation | Reasonable default | Why |
38
+ |---|---|---|
39
+ | Public or partner API, broad tooling expected | REST over HTTP with an OpenAPI document | Every language and proxy understands it; caching works |
40
+ | One product team owns a rich client with many screens pulling nested data | GraphQL | Client picks fields; one round trip per screen |
41
+ | Internal service-to-service calls with strict latency budgets | gRPC with protobuf | Typed contracts, code generation, HTTP/2 streaming |
42
+ | TypeScript monorepo where server and client ship together | tRPC or a shared schema package | Types flow end to end without a separate IDL |
43
+ | "Tell me when X happens" to an external party | Webhooks | Caller does not poll; you push on change |
44
+ | Many internal consumers reacting to the same fact | Events on a log or broker (Kafka, NATS, SQS/SNS) | Producers stay unaware of consumers |
45
+ | Work that takes longer than a request should | Accept, return a job resource, then poll or notify | Keeps request timeouts honest |
46
+
47
+ Mixing is normal: a public REST API, gRPC between internal services, and an
48
+ event stream for side effects is a common and healthy shape. What goes wrong is
49
+ picking GraphQL or gRPC for a public surface because it is fashionable, then
50
+ rebuilding caching, auth and tooling that REST gave for free.
51
+
52
+ ### GraphQL specifics worth deciding up front
53
+
54
+ - Depth and complexity limits, or one query can fan out into thousands of
55
+ resolver calls.
56
+ - A batching layer (DataLoader or equivalent) so a list of 50 orders does not
57
+ run 50 customer lookups.
58
+ - Persisted queries for production clients, which also shrink the attack surface.
59
+ - Errors: GraphQL returns 200 with an `errors` array; decide which failures are
60
+ field-level and which reject the whole operation.
61
+
62
+ ### gRPC specifics
63
+
64
+ - Never reuse or renumber a protobuf field tag; mark removed ones `reserved`.
65
+ - Set deadlines on every call and propagate them downstream.
66
+ - Browsers need gRPC-Web or Connect; plan a gateway if a web client is coming.
67
+
68
+ ## 3. Evolving a contract
69
+
70
+ Additive changes (optional fields, new endpoints or event types, enum values
71
+ clients were told to tolerate) ship without a version; removals, renames, type
72
+ or meaning changes need a migration plan. Prefer additive-only, then dated
73
+ versions, then a path major version. Announce deprecation with `Deprecation`
74
+ and `Sunset` headers, measure remaining callers, and check event schema
75
+ compatibility in CI. Details: `references/contract-details.md`.
76
+
77
+ ## 4. Contracts every style needs
78
+
79
+ Load `references/contract-details.md` for examples. The rules:
80
+
81
+ - **Pagination**: opaque cursor over the sort key plus a unique tiebreaker,
82
+ server-capped `limit`, no total count unless it is cheap; offset paging only
83
+ for small, static data.
84
+ - **Idempotency**: non-idempotent writes accept an `Idempotency-Key` scoped to
85
+ the caller. Replay the stored result for a completed key, `409` while it is
86
+ still running, `422` for the same key with a different body; store key and
87
+ result in the side effect's transaction and expire them after a stated window.
88
+ Consumers deduplicate on the event id.
89
+ - **Errors**: one RFC 9457 problem-details shape (`application/problem+json`)
90
+ with a stable `type`, field errors as JSON Pointers, a request id, and no
91
+ internals. gRPC uses canonical codes plus `google.rpc` details; events go to a
92
+ dead-letter destination with the reason.
93
+ - **Webhooks**: HMAC-signed timestamp plus body with replay rejection, retries
94
+ with backoff and jitter then parking, a documented thin or full payload, and
95
+ replay on request.
96
+
97
+ ## 5. Checklist before publishing a contract
98
+
99
+ - [ ] Style chosen from consumer and interaction shape, reasoning recorded (ADR).
100
+ - [ ] Machine-readable schema exists: OpenAPI, GraphQL SDL, `.proto`, or event schema.
101
+ - [ ] Unknown fields and enum values are tolerated by clients, and documented as such.
102
+ - [ ] List endpoints paginate with a capped cursor.
103
+ - [ ] Non-idempotent writes accept an idempotency key.
104
+ - [ ] Every error uses the shared problem shape with a stable `type`.
105
+ - [ ] Deprecation policy is written down with a minimum notice period.
106
+ - [ ] A contract test or breaking-change check runs in CI.
107
+
108
+ ## References
109
+
110
+ - `references/contract-details.md`: pagination, idempotency, problem-details and webhook examples in full.
111
+
112
+ ## Related skills
113
+
114
+ - `rest-api-design`: URLs, methods, status codes, caching headers, OpenAPI.
115
+ - `api-security-best-practices`: authentication, authorization, rate limits.
116
+ - `architecture`: recording the decision as an ADR.
117
+ - `nodejs-backend-patterns`, `fastapi-pro`: implementing the chosen contract.
@@ -0,0 +1,128 @@
1
+ # API contract details
2
+
3
+ Versioning rules and worked examples for the pagination, idempotency, error-shape and webhook rules summarised in SKILL.md.
4
+
5
+ ## Contents
6
+
7
+ - Evolving a contract
8
+ - Pagination
9
+ - Idempotency for retried writes
10
+ - One error shape everywhere
11
+ - Webhooks done properly
12
+
13
+ ## Evolving a contract
14
+
15
+ Treat every published field as a promise. Additive change is almost always safe;
16
+ removal, renaming and changing meaning are not.
17
+
18
+ Safe without a new version:
19
+
20
+ - adding an optional request field or a new response field;
21
+ - adding a new endpoint, RPC or event type;
22
+ - adding an enum value, **only if** clients were told to tolerate unknown values.
23
+
24
+ Breaking, needs a migration plan:
25
+
26
+ - removing or renaming a field, or making an optional field required;
27
+ - changing a type, unit or format (`price` from cents to decimal string);
28
+ - changing default behaviour or the meaning of a status.
29
+
30
+ Versioning mechanics, from lightest to heaviest:
31
+
32
+ 1. **No explicit version, additive only.** Works longer than people expect.
33
+ 2. **Dated versions** pinned per client (`Api-Version: 2026-06-01`), with the
34
+ server translating older shapes. Good for public APIs with many integrators.
35
+ 3. **Major version in the path** (`/v2/orders`). Simple to route and reason
36
+ about, costly to maintain two copies.
37
+
38
+ Whatever the scheme, publish a deprecation window, emit a `Deprecation` and
39
+ `Sunset` header (RFC 9745 / RFC 8594) on retiring endpoints, and measure who is
40
+ still calling before you switch anything off.
41
+
42
+ For events, the same rules apply to the payload schema. Keep a schema registry
43
+ or a versioned schema file and run a compatibility check in CI.
44
+
45
+ ## Pagination
46
+
47
+ Offset pagination (`?page=7`) is easy and wrong for data that changes: rows
48
+ shift between requests and deep pages get slow. Prefer an opaque cursor.
49
+
50
+ ```http
51
+ GET /products?limit=50&after=eyJpZCI6IjAxSjhRIn0
52
+
53
+ 200 OK
54
+ {
55
+ "data": [ ... ],
56
+ "page": { "next": "eyJpZCI6IjAxSjk0In0", "hasMore": true }
57
+ }
58
+ ```
59
+
60
+ - The cursor encodes the sort key plus a unique tiebreaker (`created_at`, `id`)
61
+ and is base64 so clients treat it as opaque.
62
+ - Cap `limit` on the server; ignore or clamp values above it.
63
+ - Do not promise a total count unless it is cheap; counting a large table on
64
+ every page request is a common production hotspot.
65
+ - Streaming or long-lived exports are a job, not a very large page.
66
+
67
+ ## Idempotency for retried writes
68
+
69
+ Networks drop responses, not just requests. A client that times out on
70
+ `POST /orders` cannot know if the order exists. Give it a way to retry safely.
71
+
72
+ ```http
73
+ POST /orders
74
+ Idempotency-Key: 5f1c2d0e-8b7a-4c77-9a61-0d3f6c1b2a90
75
+ Content-Type: application/json
76
+
77
+ { "productId": "p_812", "quantity": 2 }
78
+ ```
79
+
80
+ Server behaviour:
81
+
82
+ 1. Look up the key scoped to the caller. If a completed result exists, return it
83
+ unchanged, including the original status code.
84
+ 2. If a request with that key is still running, return `409 Conflict` so the client backs off.
85
+ 3. If the same key arrives with a different body, reject it with `422`.
86
+ 4. Store the key and result in the same transaction as the side effect, and
87
+ expire keys after a stated window (24 hours is typical).
88
+
89
+ `PUT` and `DELETE` are idempotent by definition, but only if your handler is.
90
+ Webhook and event consumers need the same property: deduplicate on the event id,
91
+ because at-least-once delivery means duplicates will arrive.
92
+
93
+ ## One error shape everywhere
94
+
95
+ Use RFC 9457 problem details for HTTP APIs. Clients then write one error
96
+ handler instead of one per endpoint.
97
+
98
+ ```json
99
+ {
100
+ "type": "https://api.example.com/problems/insufficient-stock",
101
+ "title": "Not enough stock",
102
+ "status": 409,
103
+ "detail": "Only 1 unit of product p_812 is available.",
104
+ "instance": "/orders/req_01J9Z",
105
+ "errors": [{ "pointer": "/quantity", "detail": "must be at most 1" }]
106
+ }
107
+ ```
108
+
109
+ - `type` is a stable identifier clients can branch on; `title` is for humans.
110
+ - Put field-level validation failures in an extension member (`errors` above)
111
+ using JSON Pointers into the request body.
112
+ - Never leak stack traces, SQL or internal hostnames in `detail`.
113
+ - Include a request or trace id so support can find the log line.
114
+ - Serve it as `application/problem+json`.
115
+
116
+ For gRPC, map to canonical status codes and attach `google.rpc` error details;
117
+ for events, a failed consumer moves the message to a dead-letter destination
118
+ with the reason attached.
119
+
120
+ ## Webhooks done properly
121
+
122
+ - Sign every delivery (HMAC-SHA256 over timestamp plus body) and document how to
123
+ verify it; reject deliveries older than a few minutes to stop replay.
124
+ - Retry with exponential backoff and jitter for a bounded period, then park the
125
+ delivery and surface it in a dashboard.
126
+ - Send a thin payload (event type, id, resource URL) or a full snapshot, and say
127
+ which; thin payloads avoid stale data at the cost of a follow-up call.
128
+ - Let integrators replay past deliveries; they will lose some.