@mmerterden/multi-agent-pipeline 20.2.0 → 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 +923 -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 -31
  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 +82 -7
  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 -63
  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
package/CHANGELOG.md CHANGED
@@ -14,6 +14,928 @@ Internal file-layout changes that don't affect the slash-command surface are sti
14
14
 
15
15
  ---
16
16
 
17
+ ## [Unreleased]
18
+
19
+ ## [20.3.0] - 2026-09-25
20
+
21
+ ### Added
22
+
23
+ - **The client contract, over the CLI and localhost HTTP.** `contract-server.mjs`
24
+ serves runs, commands, run questions, issues, worktrees and the launch shape,
25
+ plans a launch and answers a pending question on `127.0.0.1`, byte for byte
26
+ what the CLI prints: a per-start bearer token in a 0600 file, Host and Origin
27
+ checks, schema-validated bodies up to 64 KiB, `?redact=1` (forced for a
28
+ browser origin), `?v=` major selection and idle shutdown. It never starts a
29
+ host CLI. `/multi-agent:serve` starts it on demand. `pipeline/contract/`
30
+ ships the client kit: a manifest pointing at `pipeline/schemas`, generated
31
+ TypeScript declarations and fixtures (`build.mjs`, run at prepack), the
32
+ frozen fields of the current client and a contract changelog of its own.
33
+ - **Commands, run questions and the launch shape as data.** Every command
34
+ declares `parameters`, `gui`, `destructive` and `confirm` in its frontmatter,
35
+ held to `argument-hint` by `lint-skills`, and `commands.mjs --json` prints
36
+ the catalog. `run-questions.json` lists the Phase 0 pickers;
37
+ `MA_LAUNCH_REQUEST` names a request whose answers pre-fill them, validated by
38
+ `launch-request.mjs` (unset, Phase 0 is unchanged). `launch.json` declares
39
+ the unattended launch shape. `answer-question.mjs` records only an option id
40
+ the pending question offered, and `resume --answer` goes through it.
41
+ `issues.mjs`, `worktrees.mjs` and `runs-index.mjs --json` carry
42
+ `contractVersion`, schemas with `x-sensitivity`, and `--redact`.
43
+ - **Per-stack evidence.** `stack-adapters.json` gives each stack (ios, android,
44
+ web, backend-node, python, go, rust, jvm, unknown) its detection, commands,
45
+ success markers, parsers, test-file patterns and truth-source globs.
46
+ `evidence-gate --stack` fails a test claim that executed nothing or counted
47
+ a failure, `test-summary.mjs` reads the counts from the runner's own output
48
+ and reports unread counts as unparsed, and `test-strength.mjs` reverts the
49
+ production side of a diff in a temporary worktree and requires the changed
50
+ tests to go red.
51
+ - **Quality gates for autopilot runs.** With `MULTI_AGENT_UNATTENDED=1` or a run
52
+ in autopilot mode, `symbol-existence-gate` checks added references against
53
+ the stack's truth sources, `open-questions-gate` parks a run with open
54
+ analysis questions on `waitingFor: question` before Phase 2,
55
+ `verify-citations` matches quotes to lines and checks pre-existing claims
56
+ against the base commit, and `gate-ledger.mjs` is the one locked writer of
57
+ `state.gates[]`; with the variable set the commit hook requires every
58
+ mandatory gate to pass for HEAD. With neither, every gate is a no-op.
59
+ - **Terminal output in the reader's language.** `user-facing.{mjs,sh}` resolve
60
+ `outputLanguage` and the host's command spelling (`/multi-agent:<sub>` or
61
+ `/multi-agent-<sub>`) once; the GUI, the autopilot menu bar and the terminal
62
+ panels use them, and `smoke-terminal-language.sh` fails a frozen string or a
63
+ hardcoded spelling in a user-facing surface. `promptLanguage` stays English.
64
+ - `design-check-config` `inventory.targetsFile` names a JSON target catalog
65
+ that both design-check skills pass to `design_scenario_inventory`, for a repo
66
+ whose state drivers no source signal reveals.
67
+
68
+ - `check-derived-drift.mjs`: a `git-paths` upstream type for sources that ship no manifest. The recorded version is the commit the port was taken from, and drift is any later commit on `upstreamRef` that touches `upstreamPaths`, so unrelated commits in an app repo do not count.
69
+ - **Android knowledge: same-frame input intents, deferred state reads and
70
+ custom architecture rules.** `android-mvi-viewmodel` gains a per-intent
71
+ immediate-dispatch flag so text, toggle and selection intents write state on
72
+ `Dispatchers.Main.immediate` instead of a `Dispatchers.Default` hop, and shows
73
+ how a context parameter confines use-case invocation to the ViewModel
74
+ executor. `android-performance` gains a deferred-state-reads section (the
75
+ composition / layout / draw phase table, `offset { }`, `graphicsLayer { }`,
76
+ `drawBehind { }`) and a stability row for classes from modules the Compose
77
+ compiler does not see. `android-build-quality-gates` gains a custom detekt
78
+ rule set section for architecture rules a single file can show. `android-architecture`
79
+ adds the data-source-only repository rule, the shared request helper, feature-local
80
+ UI models and `internal`-by-default visibility. `compose-testing` fixes the
81
+ test-tag hierarchy and uniqueness rule. `compose-navigation` requires the
82
+ typed argument helper even for primitive-only routes, and its type-map
83
+ example uses a neutral search filter.
84
+
85
+ - **Phone API on the contract server** (`features/phone-api.md`). Four routes
86
+ under `/v1/phone/` - runs and one run (always redacted), answer a parked
87
+ question, and launch - served by the existing handlers behind an Ed25519
88
+ device signature instead of the bearer token. The signed text covers method,
89
+ target, body digest, device id, timestamp and nonce; a request that is
90
+ unsigned, from an unknown or revoked device, more than 60 seconds behind or
91
+ 5 seconds ahead of this machine's clock or older than the server's start,
92
+ replayed (seen nonces persist on disk, so a restart does not reopen them), or
93
+ for an unknown verb is refused. Requests whose signature verified go to a
94
+ 0600 audit log with five generations; refusals decided before that go to a
95
+ separate, rate-limited refusals log, so an unsigned flood cannot rotate the
96
+ audit log. Neither holds the signature, nonce or body. Devices are enrolled locally with the new `phone-devices.mjs add|list|revoke|launch`,
97
+ which stores public keys only under the autopilot root with a per-device
98
+ scope (`read`, `answer`, `launch`), refuses to change the registry under
99
+ `MULTI_AGENT_UNATTENDED=1`, and is blocked by name in the unattended guard.
100
+ Launch from a phone is off until `phone-devices.mjs launch on`. An answer is
101
+ still only an offered option id, and the maturity and open-questions gates
102
+ re-run on resume. Pause, resume, stop and steer are not offered: their
103
+ existing backends start a session, run `launchctl`, delete a worktree or
104
+ queue free text. The bearer path for the desktop client is unchanged. Client
105
+ contract 1.2.0: `manifest.json` `phone`, `phone-signed-request.schema.json`,
106
+ `phone-devices.schema.json`, new `contract-error` codes. The phone app is a
107
+ separate project.
108
+
109
+ - **Autopilot keeps the Mac awake while it is on.** `autopilot-on` installs a
110
+ second launchd agent, `com.multi-agent.autopilot-awake`, that runs
111
+ `/usr/bin/caffeinate -s -i` until `autopilot-off` removes it, because
112
+ launchd's `StartInterval` does not wake a sleeping Mac and a machine that
113
+ sleeps between ticks stops taking work. `-s` holds system sleep off on AC,
114
+ `-i` idle sleep on battery too. `autopilot-on` asks whether the display stays
115
+ on as well (`-d`, `awake.display`, default no: builds, simctl screenshots and
116
+ headless browsers work with the display asleep, and display sleep does not
117
+ lock the keychain). New `autopilot-awake.mjs render|install|remove|status`,
118
+ `templates/multi-agent-autopilot-awake.plist.template`, config `awake`
119
+ (`{enabled: true, display: false}`), and `awake: {held, display}` in
120
+ `autopilot-status --json`. The in-flight lock is unchanged.
121
+
122
+ - **Autopilot operations around a run** (`features/autopilot-operations.md`).
123
+ A tick holds a sleep inhibitor from the launch to its end - `caffeinate -s -w
124
+ <runner pid>`, honoured on AC only - and kills the process group it spawned on
125
+ every exit path. `autopilot-arming.mjs probe` checks every credential the configured
126
+ repos need before `autopilot-on` offers the schedule (`gh auth status`, and the
127
+ new no-value `credential-store.sh probe <key>`: `readable`, `missing` or
128
+ `locked`), and every tick re-probes the item's source through `check --probe`,
129
+ so a keychain that locked on sleep refuses with the key and the fix instead of
130
+ failing the run. `maxParallelAgents` caps runner-launched sessions working at
131
+ once, counting parked runs that are busy again; unset, the one-at-a-time claim
132
+ is unchanged, and the claim is now an exclusive create of `runner.pid`. Once
133
+ per local day the runner writes `gc-report-<date>.json` / `.md`, a
134
+ `gc-abandoned.sh` dry run over only the worktrees it created
135
+ (`worktrees.jsonl`; new `--only` and `--report` flags), with removal opt-in
136
+ through `gc.autoDelete`, and, when `digest.enabled`, a digest of items,
137
+ outcome classes, PRs, parked items and cost, sent through `reportChannels`
138
+ after the outbound gate (`reportDigest`, posted to `digest.jiraIssue`).
139
+ `autopilot-status --json` adds `inhibitorHeld`, `lastGcReport`, `lastDigest`
140
+ and `maxParallelAgents`.
141
+ - **The autopilot runner is the single outward writer.** After an unattended
142
+ session ends at the Phase 4 hand-off, `autopilot-publish.mjs` verifies the PR
143
+ request the run left and only then pushes and opens the PR. The repository
144
+ comes from the runner's config, never the request; the worktree must belong
145
+ to it and sit on an unprotected branch that is ahead of the base fetched from
146
+ the configured remote; worktree git config that rewrites URLs or runs a
147
+ command is refused. The gate ledger, the named test log, the commit hook's
148
+ secret detectors over the commit range and the outbound gate are re-run
149
+ outside the run. The push URL is the config's `pushUrl` or `gh repo view`,
150
+ never `.git/config`; the push is never forced and runs with hooks off, and
151
+ `gh pr create --draft` takes the body from a file. Every spawn runs with
152
+ `MULTI_AGENT_UNATTENDED` unset. Bitbucket pushes the branch and writes a
153
+ summary, outcome `pushed-awaiting-pr` (terminal); an unknown host and every
154
+ failed check are `verification-failed`, with the verdict in
155
+ `pr-requests/<session>.verdict.json`.
156
+ - The runner refuses to launch (`blocked-guard-missing`) unless `agent-guard.sh`
157
+ is registered on both the `Bash` and `Edit|Write|NotebookEdit` PreToolUse
158
+ matchers, prepares `pr-requests/` at 0700 before every launch, and passes
159
+ `MCP_TOOLKIT_URL_POLICY=strict` and `MCP_TOOLKIT_INDEX_DENY` to the child
160
+ (`launch.json` contract 1.1.0 carries both).
161
+ - Post-PR reports move to the runner, off by default: `reportChannels` with a
162
+ configured `jira` target posts one Jira comment, and the new
163
+ `reportIssueUpdates` runs `update-issue-progress.sh` and a PR-link Jira
164
+ comment. Both run once, after the PR opened, through the outbound gate.
165
+ - `pre-commit-check.sh --scan-range <base>..<head>` runs the secret detectors
166
+ over the lines a commit range added. `test-summary.mjs` records the log it
167
+ read in its ledger entry (`detail.source`). New autopilot config keys
168
+ `repos[].host`, `repos[].pushUrl`, `repos[].baseBranch`, `reportIssueUpdates`;
169
+ new state key `publish`.
170
+ - **Plan critic, one round.** With the quality gates active, Phase 1 ends with
171
+ one adversarial critic (`agents/plan-critic.md`, dispatched through
172
+ `model-dispatch.sh --persona plan-critic --default fable`, so it follows the
173
+ fable switch like review) asking why the plan will fail under four lenses:
174
+ scope, feasibility, security and a cheaper alternative. Each objection carries
175
+ an id, lens, claim and evidence anchors (`file:line` resolved like
176
+ `verify-citations.mjs`, a plan task, an analysis id or heading, or
177
+ `inference`), in `.pipeline/plan-critique.json`
178
+ (`plan-critique.schema.json`). The planner answers each objection once:
179
+ accept and revise the plan, or rebut with evidence. `plan-critique-gate.mjs`
180
+ judges with no model call: a missing, duplicate or orphan reply, `round`
181
+ other than 1, or a second critique of a run already judged fails; an
182
+ objection citing a binding constitution rule blocks unless its reply
183
+ resolves it with an anchor that holds; everything else is advisory and kept
184
+ in `state.planCritique.advisory` for the plan render and the PR summary.
185
+ Gates active it records `plan-critique` in the gate ledger and parks a
186
+ failing run as `verification-failed` (exit 0 pass, 1 fail, 2 not-applicable,
187
+ 3 unreadable); attended no critic runs and the gate, if invoked, is advisory,
188
+ exit 0, nothing written. One round, because further rounds of debate move
189
+ agents toward each other rather than toward the right answer. It is not in
190
+ `MANDATORY_AT_COMMIT`: the resume tail commits under the gates with no Plan
191
+ phase. Feature: `features/plan-critic.md`.
192
+ - **Review decision rule for autopilot.** `review-decision-gate.mjs` runs on
193
+ the triage output after Step 3.7 in every round, the empty Step 3.1 result
194
+ included. With the quality gates active an accepted `blocking` finding keeps
195
+ its severity only when two independent reviewer outputs carry the same
196
+ finding (same file, and the same fingerprint or cited lines at most three
197
+ apart, never across different `ruleId`s or CWEs), when a `confirmed`
198
+ verify-by-test log inside the checkout shows a failing test and no pass, or
199
+ when test-integrity-gate.mjs produced it. Anything else is lowered to
200
+ `important` in place, never dropped, with its fingerprint and reason in the
201
+ report and the ledger entry; `approved` is recomputed. The Step 2.5 rebuttal
202
+ round does not run under the gates (`--rebuttal-allowed` exits 1), and a
203
+ reviewer entry with `roundCount` above 1 fails the gate. `review-decision`
204
+ joins `MANDATORY_AT_COMMIT`: every mode carries Review and the gate records
205
+ `pass` on a run with no blocker, so no clean commit is refused. Attended
206
+ review is unchanged: advisory output, exit 0, nothing written. The reviewer
207
+ panel on Claude Code is one model family, so the rule leans on executable
208
+ evidence rather than on more same-family agreement
209
+ (`features/review-decision.md`). `state.reviewIterations[].reviewDecision`
210
+ is declared.
211
+ - **`/multi-agent:scaffold` and the scaffold contract.** The command resolves
212
+ `ai-<stack>-toolkit:scaffold`, dispatches it through the Skill tool and then
213
+ only verifies: `scaffold-gate.mjs --phase skeleton` requires a valid
214
+ `.scaffold.json` (`scaffold-manifest.schema.json`), no commit and no remote
215
+ yet, and the stack adapter's build, test and lint commands to pass, build and
216
+ test judged by `evidence-gate.mjs --stack` with test counts. The first commit
217
+ follows exit 0; creating the hosted repository is a separate question asked
218
+ after it and is refused unattended by agent-guard. For a scaffolded repo
219
+ Phase 2 runs `scaffold-gate.mjs --phase story` at entry and exit: build, test,
220
+ lint and the manifest's demo command must pass, or the next story does not
221
+ start (`features/scaffold.md`). The stack adapters gain an optional `lint`
222
+ command kind, declared for ios, android, web and backend-node.
223
+
224
+ - **Project constitution and the spec-consistency gate.** `/multi-agent:analysis`
225
+ writes the project's invariant rules (security, accessibility, architecture,
226
+ licensing) to `~/.claude/knowledge/<project>/constitution.md` and its
227
+ machine-readable twin `constitution.json` (`constitution.schema.json`). Each
228
+ rule cites one labelled source: `repo` (a file and line in the repository),
229
+ `evidence` (a standards document or tracker item) or `inference`, which is
230
+ always `proposed` and never binding. A run with no repository keys the file on
231
+ the analysis name and cites no repo. `constitution.mjs` resolves the path
232
+ (worktree-safe), lists the repository files a rule may cite (license,
233
+ instruction files, lint configs, the stack manifest) and checks a
234
+ constitution, including that every repo ref resolves.
235
+ `spec-consistency-gate.mjs` checks by id, with no model call, that every
236
+ requirement (`BR-<slug>-NN` or `FG-NN`) has a task and a Test Plan row or test
237
+ task, that every task cites a defined requirement, and that no requirement
238
+ row or task waives a binding constitution rule. With the quality gates active
239
+ it records `spec-consistency` in the gate ledger and exits 0 pass, 1 gap, 2
240
+ not-applicable, 3 unreadable; attended it prints an advisory report, exits 0
241
+ and writes nothing. `/multi-agent:analysis-jira` runs it after planning: gates
242
+ active, a gap is the existing exit 4 and no issue is created; attended, the
243
+ preview gains an advisory `consistency:` line. Pipeline Phase 1 Step 12 runs
244
+ it before Phase 2. It is not in `MANDATORY_AT_COMMIT`, since a run whose
245
+ item carries no requirement id has nothing for it to check. Planning tasks
246
+ gain an optional `requirements[]` field, checked by `validate-planning.mjs`. Feature: `features/constitution.md`.
247
+ - **Research before asking.** A run the autopilot runner finds parked on a
248
+ maturity blocker or on open analysis questions gets a research pass before it
249
+ is left for a person: `/multi-agent:research <id> --autonomous` reads the
250
+ tracker thread, issue links, similar closed items, linked documents and the
251
+ repository, and `research-gate.mjs` decides what closed. `inference` alone
252
+ never closes a gap, `evidence` must be quoted from a source in the fetched
253
+ context, `repo` must resolve at `file:line` or in a commit, and acceptance
254
+ criteria and business rules only ever yield candidates. The maturity check or
255
+ the open-questions gate re-runs on the result and decides; `proceed` resumes
256
+ the run, anything else parks it with the gaps left and the candidates found.
257
+ `maxAskRounds` now bounds these rounds per item. The research session runs
258
+ without the `research_*` MCP tools and web search. Engine:
259
+ `multi-agent-refs/research/engine.md`; feature: `features/research.md`.
260
+ - `lib/issue-fetcher.sh` carries Jira comments and issue links and GitHub issue
261
+ comments on the request that fetches the item, bounded by count, per-comment
262
+ length and total bytes, and lists every tracker-written field in
263
+ `untrustedFields`. The maturity score is unchanged. `--rescore` re-scores a
264
+ descriptor on stdin with the same formula.
265
+ - New state key `research` and schema `research-output.schema.json`;
266
+ `prefs.projects.<slug>.research.providers` (graylog, crashlytics,
267
+ counterpart).
268
+ - `lint-skills` fails a skill under `shared/external` whose frontmatter has a
269
+ top-level key no host reads. The allowed set is skill-creator's packaging keys
270
+ plus Claude Code's documented skill fields; repo bookkeeping goes under
271
+ `metadata:`.
272
+
273
+ - **Attribution check for vendored skills** (`_notices.mjs`). Every
274
+ `NOTICE-*.md` under `shared/external` lists the skills it covers in a
275
+ `## Skills (N)` section, and every vendored skill carries
276
+ `metadata.source: "<upstream> (<license>)"`. `lint-skills` fails when the two
277
+ disagree: a vendored skill no NOTICE lists (so deleting a NOTICE fails), a
278
+ listed skill without that source, a NOTICE whose upstream differs from the
279
+ skill's, a wrong count, or a skill listed twice. `build-stack-plugins.mjs`
280
+ runs the same check before writing anything and exits 1 on a problem, ships a
281
+ NOTICE only beside the skills its section lists, and gains `--check-notices`.
282
+ `lint-skills` also warns on a `metadata.source` that names no licensed
283
+ upstream (27 skills marked `community`).
284
+ - `NOTICE-vibeship-spawner-skills.md` attributes `firebase` to
285
+ vibeforge1111/vibeship-spawner-skills under Apache 2.0, with the license terms
286
+ and the changes made to the upstream work.
287
+ - `launch-request.mjs plan --channel desktop|phone` (default `desktop`) applies
288
+ that channel's input rule, so `plan --channel phone --redact` prints what
289
+ `POST /v1/phone/launch` returns for the same request file; the manifest's
290
+ phone-launch invocation passes it.
291
+ - `CREDENTIAL_STORE_KEYCHAIN` scopes `credential-store.sh` and `keychain.py` to
292
+ one keychain file instead of the user's search list.
293
+ - Schemas for `phases.json`, `token-budget.json`, `unattended-policy.json`,
294
+ `unattended-profile.json`, `secret-patterns.json` and
295
+ `review-file-exclusions.json`.
296
+
297
+ ### Security
298
+
299
+ - `usage-register.mjs` sends the GitHub login proof only over https to the default reporting host or a host listed in `usageLog.trustedHosts`, and reads the server's answer by code: a login mismatch, a login without collaborator access and a decline each get their own status. `usage-report.mjs` no longer follows a redirect with the ingest token.
300
+ - **The OS sandbox is the primary boundary for unattended runs.**
301
+ `install --unattended` always writes an OS sandbox block into the unattended
302
+ profile: enabled and required at startup, no unsandboxed retry, no excluded
303
+ commands, auto-allow off, writes confined to the worktree, host configuration
304
+ and credential stores denied, and network limited by a strict allowlist to the
305
+ package registries the stack adapters need. The autopilot runner refuses to
306
+ launch (`blocked-sandbox-unavailable`) unless the profile file's content still
307
+ holds the sandbox, and re-checks before every research pass and resume, so a
308
+ run that rewrote the profile cannot widen the next one. An unattended run
309
+ writes its logs and PR request under `~/.multi-agent-unattended` (the one
310
+ place outside the worktree the sandbox permits), and `Edit`/`Read` deny rules
311
+ cover the file and MCP tools the sandbox does not. Behaviour verified against
312
+ Claude Code 2.1.282 and recorded in `features/unattended-security.md`.
313
+ - **The publish step verifies a clean checkout and refuses host changes.**
314
+ Independent verification builds and tests a detached checkout of the run's
315
+ commit, so an untracked file (a `.npmrc`, a `conftest.py`) cannot change what
316
+ runs; a build or test that rewrites a tracked file, or that changes
317
+ `~/.claude/{scripts,lib}`, the settings files, the profile or
318
+ `~/Library/LaunchAgents`, is refused before anything is pushed. The push range
319
+ is scanned through repository `.gitattributes` and binary blobs, so a path
320
+ marked `-diff`/binary cannot hide an added secret.
321
+ - **The unattended command guard closes the round-3 one-liner bypasses** as a
322
+ second layer behind the sandbox: `/dev/*` and non-regular files as programs;
323
+ debuggers, job runners and tracers; `node -r`/`sort --compress-program`/
324
+ `rg --pre` helper values; git `send-pack`/`http-push`/`lfs push`/`svn`/`p4`,
325
+ credential helpers, `maintenance start`, browser/server subcommands and the
326
+ `--git-dir`/`--work-tree`/`--exec-path`/`--namespace` global flags; host
327
+ checks on git and `gh` URLs and `--hostname`; `ssh`/`scp`/`nc`/`dig` and
328
+ rsync-to-remote; `gh` alias normalization, `config set`, `config get` of a
329
+ token; git `mv`/`checkout`/`worktree add`/`clone`/`init`/`checkout-index`/
330
+ `apply --directory` write targets, `mkdir`, copy destination-plus-basename and
331
+ `mv`/`rm` sources; `cd -` as an unresolved directory; the whole host roots and
332
+ `$HOME`'s ancestors; the proxy and toolchain-redirect environment variables;
333
+ `patch` and `git apply`/`am`; and every path-typed MCP argument, including
334
+ inside `agent_run_steps`. A program file counts as trusted only when unchanged
335
+ at the run's base commit and inside the run's own worktree.
336
+ - `fetch-confluence.sh` sends the token only to `prefs.global.hosts.confluence`
337
+ or a subdomain of it, or to Atlassian Cloud when no host is configured, and
338
+ refuses any other link host with exit 6 before the token is read. The setup
339
+ flows write secrets through the stdin sentinel (`set <key> -`);
340
+ `credential-store.sh` delegates writes to `keychain.py`, and its shell
341
+ fallback writes `-X` hex and decodes the `0x` marker, so a multi-line value
342
+ such as a service-account JSON round-trips byte-exact.
343
+ - `context-link-extractor.sh` matches hosts by domain rather than suffix, so a
344
+ look-alike such as `evil-figma.com` is not classified as Figma, and a Graylog
345
+ label must end at a word boundary.
346
+ - `agent-guard` blocks force-push bypasses (`HEAD`, any remote, push options,
347
+ `git -C`, `cd`) in every mode. Under `MULTI_AGENT_UNATTENDED=1` it also
348
+ blocks pushes, PR and issue writes, publisher scripts, Keychain reads,
349
+ fetches outside the host allowlist, package installs, manifest edits and
350
+ writes into protected paths, and fails closed. Phase 4 writes
351
+ `pr-request.json` through `pr-request.mjs` instead of pushing, channels posts
352
+ nothing unattended, and fetched text goes into `<untrusted-data>` blocks.
353
+ - `pre-commit-check.sh --scan-range` scans every commit in the range on its own, reading content from the commit objects, so a secret added and later removed inside a branch is refused before it is pushed.
354
+ - The publish step resolves its build and test commands from the base commit's manifests and refuses a range that changes those commands, their package scripts and hooks, the declared package manager, or the executable a command starts with (`publish/verify-scripts`).
355
+ - The publish step snapshots git credential settings before running the build and tests, pushes with that snapshot, and refuses to push when `~/.gitconfig`, the XDG git config or the credential settings changed meanwhile (`publish/verify-credentials`). Processes started by verification are killed by process group and by a per-run environment marker.
356
+ - With no `baseBranch` configured, a PR must target the remote's default branch; other bases need the new `allowedBases` repo option. Branch and base names that start with `-` or contain `..` are refused.
357
+ - `readRegularFile` refuses a file whose path no longer names the opened descriptor (dev/ino compared after the no-follow open).
358
+ - Redacted free text also replaces IPv4 addresses, host names under known TLDs and any `host:port`; file names, versions and code paths are left intact.
359
+ - Prefs writes from usage identity, usage registration and the prefs migrator share one locked, atomic writer and keep the file at `0600`.
360
+
361
+ - **The unattended Bash guard is fail-closed on anything it cannot parse into
362
+ simple commands** (`scripts/unattended_policy.py`, `agent-guard.py`). Under
363
+ `MULTI_AGENT_UNATTENDED=1` a command is judged only when it reduces to simple
364
+ commands joined by `;`, `&&`, `||` and plain pipes between non-interpreter
365
+ commands. A subshell, brace group, command or process substitution, heredoc,
366
+ background job, shell keyword, interpreter reading its program from stdin, `-c` cluster on a
367
+ shell, runtime-built command name, `sudo`/`doas`, `find -exec`, or a line above
368
+ 50 segments is refused unparsed. `$(...)` is analysed instead of refused: each inner command must pass the same parser and policy checks, a substitution may not name a command, subcommand or write target, and nesting, backticks, `<(`/`>(` and arithmetic stay refused. Quoted-delimiter heredocs and here-strings are literal data; segments and redirections are split quote-aware; in-command variables and `$HOME` are expanded and an unresolvable write target or `cd` is refused. Wrappers are stripped with their option values
369
+ (`env -u`, `nice -n`, `timeout -s`); command basenames are casefolded and
370
+ absolute paths reduced to their basename; git aliases and `git -c
371
+ core.hooksPath=` are refused. Path checks casefold on darwin, resolve through
372
+ `cd`/`pushd`, parse `--opt=value` and attached short options, cover `curl -o`,
373
+ `tar -C`, `unzip -d`, `ln`, `git checkout -- `/`git restore`, `patch`, and a
374
+ directory that is an ancestor of a protected path. New protected paths:
375
+ `~/.gitconfig`, `~/.config/git/`, the shell rc files, `~/Library/LaunchAgents/`,
376
+ `~/.claude/CLAUDE.md`, `~/.claude/plugins/`, `~/.claude/multi-agent-preferences.json`.
377
+ `gh` gains `alias`/`ssh-key`/`gpg-key`/`extension`/`codespace`/`secret`/`variable`
378
+ and `auth` (except `auth status`) to the write list, skips `-R/--repo` inside a
379
+ group, treats attached `-f*`/`-F*` as POST fields, and refuses graphql `@file`
380
+ fields. `curl`/`wget` parse the host with `urllib.parse.urlsplit`, refuse
381
+ `-x`/`--proxy`/`--connect-to`/`--resolve`/`-K`/`--unix-socket`/`--doh-url`, and
382
+ refuse any request body or upload outright. `keychain.py get/set/delete` and
383
+ `gate-ledger.mjs append/park` are blocked from Bash. `WebFetch` and the
384
+ toolkit's `web_*` tools are gated on the network allowlist (`web_eval`
385
+ refused), registered as a third PreToolUse matcher; the installer requires the
386
+ `Bash` tool-name matcher for the Bash guard and migrates a stale `Bash(...)`
387
+ guard entry. `agent-guard.py` arms a 5 s internal deadline (hook timeout 10 s)
388
+ and memoizes git reads. Attended verdicts are unchanged in the allow direction.
389
+ - **The unattended guard judges what a command runs, not only its name**
390
+ (`scripts/unattended_policy.py`). `xcrun`, `arch` and `sandbox-exec` are
391
+ wrappers like `env`, so `xcrun git push` is judged as `git push`; `script`,
392
+ `watch`, `env -S` and `env -C` are refused because the guard does not model
393
+ the command line they run. An interpreter may run only a file the run did
394
+ not write: an installed pipeline script, a file the user cannot write, a
395
+ `node_modules/.bin` binary, or a file tracked and unmodified at HEAD. The same
396
+ holds for a command named by path (`./x.sh`, behind `nohup` too), a module
397
+ `python3 -m` finds in the cwd, `awk -f` / `sed -f` program files and the
398
+ Makefile `make` reads. Inline programs are refused on every interpreter
399
+ (`node -e/-p`, `perl -e/-E`, `ruby -e`, `osascript -e`, `php -r`, `lua -e`,
400
+ `Rscript -e`, `swift -e`, `bun -e`, `deno eval`), as are awk programs with
401
+ `system`, a pipe, `getline` or a `print >` redirect, sed programs with a `w`
402
+ or `e` command, and `make --eval` or a `VAR=value` operand.
403
+ - **Configuration and environment that make git or a shell run a program are
404
+ refused wherever they are set.** One key list covers `git -c`,
405
+ `git --config-env`, `git clone -c` and `git config` (`diff.external`,
406
+ `core.pager`, `core.editor`, `core.sshCommand`, `core.fsmonitor`,
407
+ `core.hooksPath`, `gpg.program`, `url.*.insteadOf`, `alias.*`, `filter.*`,
408
+ `credential.*` and the rest); `git config --global/--system` writes and
409
+ `git config --edit` are refused. Every `GIT_*` variable other than commit
410
+ identity, date and prompt control is refused, as are `BASH_ENV`, `ENV`,
411
+ `PROMPT_COMMAND`, `CDPATH`, `HOME`, `NODE_OPTIONS`, `PYTHONPATH`, `LD_*`,
412
+ `DYLD_*` and a non-trivial `EDITOR` / `PAGER`, including after `env` and in
413
+ `arch -e`. `rebase --exec`, `bisect run`, `submodule foreach`,
414
+ `difftool --extcmd`, `filter-branch`, `grep -O`, `--upload-pack`,
415
+ `--template` and `ext::` / `fd::` transports are refused.
416
+ - **Write targets the shell expands, and writers the guard did not read.** A
417
+ write target or `cd` with an unquoted glob is refused, since the shell picks
418
+ the path at run time; an inherited `CDPATH` leaves a bare relative `cd`
419
+ unresolved. `sed` `w` commands, `sort -o`, `find -fprint/-fprintf/-fls` and
420
+ `find -delete`, `git diff --output`, `git format-patch -o` and `ditto` are
421
+ read as writers. `crontab`, `launchctl` and `defaults` writes, `altool` and
422
+ `notarytool` are refused. New protected home paths: `~/.zshenv`, `~/.zlogin`,
423
+ `~/.zlogout`, `~/.bash_login`, `~/.ssh/`, `~/.gnupg/`, `~/.config/gh/`,
424
+ `~/.npmrc`, `~/.netrc`, `~/.git-credentials`, and the new
425
+ `~/.claude/multi-agent-unattended.settings.json`.
426
+ - **Packages fetched by a runner command are refused.** `npx`, `npm exec` and
427
+ `npm x` pass only for a binary already in `node_modules/.bin`, because with
428
+ no TTY npm installs a missing package without asking; `--call` is refused.
429
+ `pnpm dlx`, `pnpx`, `yarn dlx`, `bunx`, `bun x`, `uvx`, `uv tool run/install`,
430
+ `pipx run/install`, `yarn global` and `npm install-test <pkg>` are refused.
431
+ `security` is judged by its subcommand after leading flags
432
+ (`security -q find-generic-password`).
433
+ - **Every multi-agent-toolkit tool goes through the guard.** The installer
434
+ registers `agent-guard.sh` on `WebFetch|mcp__multi-agent-toolkit__.*` and
435
+ migrates the older web-tools-only matcher in place. Each step of
436
+ `agent_run_steps` is judged as if called directly, a web URL given to
437
+ `ios_open_url` / `android_open_url`, `xcrun simctl openurl` or `open` is held
438
+ to the host allowlist (an app's own deep-link scheme passes), and the
439
+ `research_*` tools are refused.
440
+ - **The attended force-push rule covers deletes and hidden pushes**
441
+ (`agent-guard.py`). `git push origin :main`, `--mirror`, and `--prune` with a
442
+ glob refspec are blocked like a force-push to a protected branch; the rule
443
+ reads through subshells, brace groups, `sh -c` / `bash -c` payloads and
444
+ `eval`; and after a `cd` it cannot read, a relative `cd` keeps the directory
445
+ unknown, so a bare force-push there is blocked.
446
+ - **`install --unattended` no longer changes attended sessions.** The profile
447
+ (`dontAsk`, the narrow allow list, the push deny, the toolkit env, the
448
+ optional sandbox) is written to `~/.claude/multi-agent-unattended.settings.json`
449
+ and the autopilot runner passes it to every child with `claude --settings`
450
+ (`launchArgv`, `researchArgv`, `resumeArgv`, and `{settingsFile}` in
451
+ `schemas/launch.json`). `~/.claude/settings.json` keeps its own posture; a
452
+ whole-Bash allow there is reported by the installer and doctor, not removed.
453
+ A profile an earlier install wrote into `settings.json` is moved out on the
454
+ next `install --unattended`, printed first. The allow list names `xcrun`
455
+ subcommands (`simctl`, `xcresulttool`, `xctrace`, `--find`) instead of all of
456
+ `xcrun`.
457
+ - **The runner's guard precondition accepts only the installer's hook.** A hook
458
+ command counts only when it is exactly
459
+ `bash $HOME/.claude/scripts/agent-guard.sh` (or that path with `$HOME`
460
+ expanded), only user or managed settings count, the web entry has to cover
461
+ `agent_run_steps` and both `open_url` tools, and the launch is refused while
462
+ the permission profile file is missing.
463
+ - `untrusted.mjs` defuses a forged closing tag written with whitespace, a tab
464
+ or a newline before the slash, which could end an `<untrusted-data>` block
465
+ early.
466
+ - The Copilot setup skill and the token-rotation step in `recovery-guide.md`
467
+ stream the token over stdin instead of passing it to
468
+ `security add-generic-password -w`. `smoke-secret-off-argv.sh` also catches a
469
+ variable or backtick value on a store `set` and a `security` call carrying
470
+ `-w`/`-X` on argv, in scripts and lib as well as docs.
471
+
472
+ ### Changed
473
+
474
+ - **First-party knowledge skills in place of skills of unknown license.** 23
475
+ knowledge skills are rewritten as original content and marked
476
+ `metadata.source: multi-agent-pipeline`, keeping their names so routing and
477
+ plugin indexes are unchanged: the nine `hig-*` skills (written against
478
+ Apple's public Human Interface Guidelines, which they cite),
479
+ `android-jetpack-compose-expert`, `kotlin-coroutines-expert`, `api-patterns`,
480
+ `api-security-best-practices`, `nodejs-backend-patterns`, `fastapi-pro`,
481
+ `docker-expert`, `github-actions-templates`, `observability-engineer`,
482
+ `monorepo-architect`, `architecture`, `debugging-strategies`,
483
+ `context-compression` and `accessibility-compliance-accessibility-audit`.
484
+ `agentflow`, `closed-loop-delivery`, `ios-developer` and
485
+ `android-ui-verification` are removed: the pipeline's own orchestration,
486
+ `multi-agent:test`, and the Swift, SwiftUI and Compose skills already cover
487
+ them. `NOTICE-provenance-unconfirmed.md` is gone with them, and `lint-skills`
488
+ and `build-stack-plugins` now reject any skill whose `metadata.source` is
489
+ `community`, whether or not a NOTICE lists it.
490
+ - Knowledge-skill examples use neutral domains (orders, products, notes)
491
+ instead of travel wording.
492
+
493
+ - The autopilot runner, intake and circuit breaker share one outcome contract
494
+ (`_autopilot-outcomes.mjs`: terminal, retryable, parked, blocked). Every
495
+ retryable outcome counts toward `maxAttempts` once per run, with new
496
+ `awaiting-answer`, `rate-limited` (its own backoff) and `verification-failed`
497
+ outcomes. The runner finds its run by the session id it passes as
498
+ `MULTI_AGENT_SESSION_ID`, which Phase 0 records as `sessionId`; a parked run
499
+ holds its repo, not a slot; only a linked worktree matched by session is
500
+ removed; spend is priced from tracker tokens and null when unknown, and
501
+ arming refuses on unknown spend.
502
+ - The model router resolves a `fable` default to `opus` on every path while
503
+ `modelFallback.fableEnabled` is off, and `/multi-agent:review`,
504
+ `review-analysis` and the untracked-branch tail of `resume` ask it for their
505
+ reviewer and triage slots.
506
+ - Every shipped surface uses the six-phase numbering in `phases.json`;
507
+ `smoke-phase-labels.sh` fails a `Phase N (Name)` that disagrees with it or a
508
+ phase above 5. Lite analysis mode and the removed `:local` commands are gone
509
+ from the refs, schema and Copilot skill.
510
+ - Usage registration proves ownership of the GitHub login: it sends the verified account's `gh auth token --user <login>` as `Authorization: Bearer`, over https only (plain http only to loopback), without following redirects, and reports 401/403 with the login that could not be confirmed.
511
+ - Android, Compose, localization, clean-code and command examples in the shipped skills use a neutral orders/payments domain. The iOS coding standard names its data classes `identity-document` and `order-reference`. Technical guidance is unchanged.
512
+ - `unattended-security.md` and the publish step's docs state what the run's code can still reach when it runs as the runner's user (Keychain items readable without a prompt, `gh auth token`, the user's files) and recommend a separate macOS user for the runner.
513
+ - Core skill frontmatter (`skills/shared/core/multi-agent-*`,
514
+ `apple-archive-compliance`, `google-play-compliance`) carries only keys a host
515
+ reads. `language`, `not-for` and `standards-registry` sit under `metadata:`,
516
+ and `lint-skills.mjs` reads `not-for` from either place and enforces the host
517
+ key set on `shared/core` as well as `shared/external`.
518
+ - `lint-skills.mjs` rejects an angle bracket in any `description` or
519
+ `description-tr`, not only in `shared/external`; the `save` and
520
+ `test-screenshots` descriptions write placeholders as `{name}`.
521
+ - The line-grace ceilings for `setup` and `sync` drop to their current lengths
522
+ (826, 528).
523
+ - The autopilot indicator fixture and the menu bar comments use the six-phase
524
+ shape (`2/5 Dev`) with no pipeline-depth field, which the runner does not
525
+ write.
526
+
527
+ - `NOTICE-swift-ios-skills.md` stays, with a `## Skills (67)` list and the
528
+ PolyForm Perimeter 1.0.0 URL; the license requires its terms and the
529
+ `Required Notice:` line to accompany every copy of the 67 skills.
530
+ - 79 vendored skills carry `metadata.source` naming their upstream and license:
531
+ 67 from swift-ios-skills, six Xcode build skills, `swiftui-expert-skill`, the
532
+ four Paul Hudson skills and `firebase`. `swift-security` records PolyForm
533
+ Perimeter 1.0.0 there instead of the upstream `license: MIT` line, which
534
+ contradicts the repository license. Twelve of these files drop one or two
535
+ blank lines to stay within 500 lines.
536
+ - `clean-code` is written in this project's own words and marked
537
+ `metadata.source: multi-agent-pipeline`. It credits no upstream: the
538
+ repository it cited has no license, so nothing from it can be redistributed.
539
+ The skill stays in `shared/external`, the single source for knowledge skills
540
+ that the stack-plugin builder publishes and the Copilot and Codex installs copy.
541
+ - Operational reporting is sent under the logged-in GitHub account that can
542
+ read the pipeline repository (`usageLog.accessRepo`), not the account `gh`
543
+ has active. New `usage-identity.mjs` checks each account `gh auth status`
544
+ lists with that account's token in the child's `GH_TOKEN`, caches the
545
+ answer in `usageLog.login` (7 days; 1 day when none qualifies), and
546
+ re-checks on `--refresh`. With no such account nothing is registered or
547
+ sent, and one line says why. `usage-register.mjs` replaces a stored token
548
+ issued for a different login (`usageLog.registeredAs`) and no longer falls
549
+ back to the OS user.
550
+ - Each run record now says what happened: `ev` (`phase`, `completed`,
551
+ `halted`, `parked`), a run status derived from it, the current phase taken
552
+ from the tracker, task type, a halt or park reason code, and, opt-in through
553
+ `usageLog.includeTitle` / `usageLog.includePrUrl`, a cleaned one-line title
554
+ and the PR URL. `phase-tracker.sh` reports every non-pending transition as
555
+ `--event phase`; Phase 5 writes `status: complete` and `finishedAt` before
556
+ sending `--event completed`; halts send `--event halted` and parked runs
557
+ `--event parked`. A completed run is no longer reported with its Phase 0
558
+ status and phase.
559
+ - The reported mode is one of `schemas/phases.json`'s modes or `unknown`, and
560
+ the command is one that still ships, so a state written by an older version
561
+ cannot report a removed mode. The analysis render writes `mode: analysis`
562
+ and an explicit `complete` / `failed` status.
563
+
564
+ - The always-on description ceiling in `smoke-context-budget.sh` is 90500 (was 90000) for the new command and its shared/core counterpart.
565
+ - Overlapping iOS knowledge skills state their boundary in the description, so a
566
+ host choosing between them has a clause to decide on: `swift-testing-pro` and
567
+ `swiftdata-pro`, the three concurrency skills, the four SwiftUI review and
568
+ pattern skills, and the two SwiftUI performance skills. Third-party
569
+ descriptions keep their upstream text and gain one appended clause, recorded
570
+ under "Local modifications" in their NOTICE. `backlog`, `localization-reuse-map`
571
+ and `swift-language` descriptions are shorter, so the always-on description
572
+ surface still shrinks with the boundaries in (90252 to 90237 bytes).
573
+ - Tables of contents in `android-build-quality-gates/references/patterns.md` and
574
+ `ios-coding-standard/references/STANDARD.md`; `macos-spm-app-packaging` links
575
+ its `references/scaffold.md`.
576
+ - Frontmatter of 65 external skills moves repo bookkeeping under `metadata:`:
577
+ `source` (42), `risk` (42), `date_added` (41), `version` (21), `tags` (15),
578
+ `standards-registry` (2) and `category` (1). `skill-conformance.mjs` reads
579
+ `metadata.standards-registry` and still accepts the top-level spelling.
580
+ - `hig-components-content` and `hig-components-layout` descriptions each gain a
581
+ clause naming what they cover and which of the two handles the rest.
582
+ - `NOTICE-xcode-build-skills.md` records that the six Xcode build skills link one
583
+ another by relative path. `NOTICE-paul-hudson-skills.md` records a table of
584
+ contents added to `swift-testing-pro/references/new-features.md`.
585
+ `NOTICE-dimillian-skills.md` names the `metadata:` keys.
586
+
587
+ - Open questions: `open-questions-gate.mjs` runs as the last step of Phase 1
588
+ whatever `analysis.docStatus` says, and the resume tail runs it at Phase 0, so
589
+ every gated path leaves the entry `MANDATORY_AT_COMMIT` asks for (a list never
590
+ recorded is not-applicable). On re-entry the gate applies `state.lastAnswer`:
591
+ `assume` moves the rows to `analysis.assumptions[]` and records pass,
592
+ `ask-now` re-parks under `MULTI_AGENT_UNATTENDED=1`, `abort` stops the run as
593
+ verification-failed. Exit 3 halts Phase 1 too.
594
+ - With the quality gates active, Phase 1 always writes plan todos, and
595
+ `plan-coverage-gate.mjs` reads a run that had a Plan phase but left no todos
596
+ and no Section 14 `Add new` row as a gap (exit 1); only a run with no Plan
597
+ phase is not-applicable. Phase 4 branches on exit code and `--json` verdict.
598
+ - Review decision: Step 1.76 writes `.pipeline/test-integrity.json` and Step 2.7
599
+ `.pipeline/security-audit-<n>.json`; the gate reads both as files
600
+ (`--integrity`, `--source`), treats a missing or empty file as no findings or
601
+ no audit, and refuses an empty `reviewers: []` like a missing record (exit 3).
602
+ The phase doc writes `reviewIterations[-1].reviewDecision` and parks with an
603
+ explicit `gate-ledger.mjs park`.
604
+ - The attended path of `verify-citations.mjs`, `plan-coverage-gate.mjs` and
605
+ `evidence-gate.mjs` returns the verdicts and exit codes of its base contract:
606
+ quote checks, nested deferred findings and the plan-coverage exit codes 1 and
607
+ 3 apply only with the gates active. `test/attended-parity.test.mjs` runs a
608
+ corpus against the base scripts and lists the four intended differences, each
609
+ a false failure at the base.
610
+ - `autopilot-config.schema.json` marks `askOnLowMaturity`, `reportStatus` and
611
+ `sendItemKeys` reserved: nothing reads them, and `autopilot-on` no longer
612
+ writes a default for them.
613
+ - `smoke-removed-modes-absent.sh` scans `.github/` and rejects a fast mode or a
614
+ Short answer.
615
+ - `smoke-no-mcp-in-dev-phases.sh` is described as what it is, a maintainer
616
+ regression check over a state file: the phase docs, `rules.md` and the
617
+ schema no longer say it fails a run. It has no default state file, and a
618
+ Figma entry recorded without an integer phase exits 2 instead of reading as
619
+ phase 0.
620
+ - `write-state.mjs` names on stderr any top-level key a write introduces that
621
+ `agent-state.schema.json` does not declare. The write still lands: failing
622
+ it would stop a run over a documentation gap, and the runtime package ships
623
+ no validator.
624
+ - The smoke runner gives each suite its own temporary `HOME`
625
+ (`SMOKE_SHARED_HOME=1` keeps the real one). The live keychain smokes run
626
+ against a throwaway keychain, `smoke-cross-cli-behavior.sh` installs a git
627
+ checkout into a temporary home and checks that, `gen-facts --check` leaves
628
+ out and names the numbers it cannot read without the sibling repos, and the
629
+ npm registry probe runs only with `SMOKE_NETWORK=1`.
630
+ - `validate-schemas.mjs` compiles every schema with ajv under the draft it
631
+ names and validates each data file in `pipeline/schemas` against its sibling
632
+ schema; a data file without one fails. The contract test harness holds every
633
+ non-2xx body to `contract-error.schema.json`.
634
+ - Complaint intake redacts reservation and order reference codes as `[REDACTED:reference]`, recognises more reference-code labels, and `validate-complaint-doc` warns on a code after any of them, in any case.
635
+ - `guardRegistration` takes the managed settings path as an option; unit tests cover `allowManagedHooksOnly`, project-level `disableAllHooks` and `CLAUDE_CONFIG_DIR`.
636
+ - `json-file-lock.mjs` has direct tests: contention between two processes, stale and dead-holder reclaim, timeout, atomic replace and exact file mode.
637
+
638
+ ### Docs
639
+
640
+ - README (EN and TR) describes current behaviour only: the release-labelled
641
+ sections become feature sections, version history stays in this file and in
642
+ ADR-0014. The command tables list `analysis-jira`, `graph`, `security-review`
643
+ and `doctor`, and the Turkish `jq` prerequisite matches the English one.
644
+ - `autopilot-status`: a waiting item is parked until `resume <id> --answer` or a
645
+ client answers it; a comment is posted only when `autopilotCommentsOnIssue` is
646
+ on. The `--subjects` example shows `Phase 2/5`.
647
+ - `help` (EN and TR) lists the pipeline entries without a count and with no
648
+ depth question; the Turkish block matches the English one.
649
+ - `sync` names the Codex transform without hardcoded spec and persona counts;
650
+ `docs/architecture.md` and `docs/ecosystem.md` count six sync targets.
651
+ - Removed references to pipeline depth: `analysisPhase.mode` in Phase 1,
652
+ short-run elision in the cross-CLI and component-dispatch contracts, `:local`
653
+ in the tracker registration rule, and the Lite paragraph in `analysis`.
654
+ - `unattended-gates.md` places plan critique before the open-questions gate
655
+ that closes Phase 1; `autopilot-circuit-breaker.md` excludes `died` and
656
+ `rate-limited` from the failure count; `autopilot-off` names the
657
+ `autopilot/abandoned/<task-id>` stash entry.
658
+ - ADR-0007 and ADR-0008 carry the ADR-0012 macOS-only amendment.
659
+ - `docs/features.md` opens with a table of contents.
660
+ - Schema descriptions (`phases.json`, `token-budget.json`, `prefs.schema.json`,
661
+ `agent-state.schema.json`, `triage-output.schema.json`) state what each field
662
+ is and who reads it. The token-budget ceiling history moved from
663
+ `docs/token-budget-history.md` to the end of `CHANGELOG-archive.md`.
664
+ - Removed `docs/internal/STABILITY-FIX-PLAN.md` and
665
+ `docs/internal/GENERICITY-REVIEW.md`.
666
+ - `features/maturity-followup.md` states that a parked autopilot item is not
667
+ queued again by a later scan; it moves on `resume <id> --answer` or a client
668
+ answer, and the resumed run re-enters the maturity step.
669
+ - `picker-contract.md` says `agent-guard.sh` blocks on an internal error when
670
+ unattended, instead of calling all three hooks fail-open.
671
+ - The naming defaults, the Phase 2 conventions handoff, the task-sequence rule
672
+ and the repo-discovery sample use neutral order and storefront names.
673
+ - The status command's group table lists `waitingFor` as a reason for the
674
+ waiting group.
675
+
676
+ ### Removed
677
+
678
+ - `NOTICE-swift-ios-skills.md`, and the `license` line in `swift-security`.
679
+ - **The Linux and Windows code paths** (ADR-0012). `credential-store.sh` keeps
680
+ only the Keychain backend: platform detection answers `macos` or `unknown`,
681
+ and on anything else every subcommand but `platform` exits 2 with `macOS only,
682
+ see ADR-0012`; the `secret-tool` and PowerShell Credential Manager arms of
683
+ `get`, `set`, `delete`, `probe`, `list` and `doctor`, `ps_run`, and the
684
+ `linux` case in `delegate_to_python` are gone. `keychain.py` drops its
685
+ `secret-tool` branches and reports non-macOS hosts as unsupported. The
686
+ runner's in-flight sleep lock drops its `systemd-inhibit` branch. Also gone:
687
+ the `USERPROFILE` fallbacks, the Windows path conversion in the installer's
688
+ `relOf`, the `xclip` branch in `github-ssh-setup.sh`, the Linux cron example
689
+ in `audit-log-rotate.sh`, the Linux branch of `smoke-keychain.sh`, the
690
+ `secret-tool` stub in `smoke-bitbucket-contract.sh`, and the Linux and
691
+ Windows wording in the setup, uninstall, review, channels and
692
+ complaint-analysis SKILLs, `keychain.md`, `tracker-contract.md`,
693
+ `url-enrichment.md`, `recovery-guide.md` and the workflow comments. The seven
694
+ constructs ADR-0012 lists as load-bearing on macOS stay.
695
+ `smoke-macos-only.sh` now scans shipped code and docs for another platform's
696
+ backend or branch, proved on a planted `systemd-inhibit` line first.
697
+
698
+ ### Fixed
699
+
700
+ - The commit hook scans the repository the commit runs in: a `cd <dir>` or `git -C <dir>` earlier on the line moves the scan to that checkout, and text inside a quoted heredoc is no longer read as a commit.
701
+ - `_autopilot-config` honours `minLength`/`maxLength`, so an empty string in a
702
+ repo's `allowedBases` is refused at load. `attended-parity` fails, rather than
703
+ silently skips, when the base commit is missing unless
704
+ `MA_ATTENDED_PARITY_SKIP=1` is set. `feedback-send` accepts the bracketed IPv6
705
+ loopback (`[::1]`) that `URL.hostname` returns. `markedPids` in the publish
706
+ step is macOS-only (`ps -E`), dropping a dead Linux `/proc` branch.
707
+ - A session at its plan limit that prints only the "You've hit your weekly
708
+ limit" notice is recognised, so the runner backs off instead of recording a
709
+ retryable failure.
710
+ - `diff-explain` reads triage from the newest `reviewIterations` entry;
711
+ `issue-fetcher` strips a URL fragment and re-validates the key before
712
+ re-dispatching and times out Jira requests at 30 s; `evidence-gate`
713
+ recognises Gradle `BUILD SUCCESSFUL`, pytest `PASSED` and `N passed` and
714
+ reads `failed=0` as a zero summary; `plan-coverage-gate` writes its verdict
715
+ synchronously, so a pipe keeps all of it.
716
+ - Autopilot checks `config.json` against `autopilot-config.schema.json` whenever arming, intake or the runner load it. A value the schema refuses, such as a non-numeric ceiling, slot count or attempt limit, blocks the queue with the field named (`blocked-config`).
717
+ - The cleanup report lists a runner worktree only while the newest run state naming it carries the ledger row's session. A refused `git worktree remove` is reported as `remove-failed`.
718
+ - The runner's circuit breaker counts each run once per window and, like the rate-limit backoff, reads a trailing time window. `ticks.jsonl` is size-capped and `attempted.jsonl` is compacted, with the full log kept in `attempted.jsonl.1`.
719
+ - Autopilot identifies GitHub items by `owner/repo#N`; rows recorded under the short id still count. A Jira issue matched by more than one repo is queued once, and the other matches are listed in `queue.json.dropped`.
720
+ - A run already waiting on a question at its first poll is parked from its own state instead of holding the queue.
721
+ - When retiring a run with uncommitted work, the runner records the stash reference only when `git stash push` succeeded.
722
+ - `gc-abandoned.sh` removes only paths git reports as worktree top levels, and only through `git worktree remove`.
723
+ - `autopilot-status.sh --write` keeps the previous `status.json` and exits 3 when the status envelope cannot be built; `--json` prints an error object with exit 3.
724
+ - `build-lock.sh` writes its owner atomically, takes a lock over only when the holder's process is gone, the owner file is stale, or the owner file is missing past a grace window, and `release <task-id>` frees only the caller's own lock.
725
+ - `worktree-prepare.sh` recognises a registered worktree named through a symlinked path and re-enters an existing task branch.
726
+ - Scripts that fall back to the installed copy of a helper keep running under `set -e` on bash 3.2 when the first location is missing.
727
+ - `answer-question` and `runs-index` read run state as a bounded regular file, so a FIFO or oversized file is reported unreadable instead of blocking the contract server.
728
+ - `gate-ledger.mjs check --repo` checks the named repository's HEAD.
729
+ - A state update that changes nothing no longer rewrites the file or bumps `rev`.
730
+ - `launch-request register-repo` holds the file's lock across read-modify-write, so concurrent registrations all land.
731
+ - `usageLog.optOut` is honoured before any credential read.
732
+ - `agent-state.schema.json` declares `review` and `complaintSpec`, and the state-keys check covers command docs too. design-check persists its platform under `designCheck`.
733
+ - The channels report example records `invokedFrom: phase-5`.
734
+
735
+ - The guard's internal deadline verdict reaches the hook wrapper: it is flushed
736
+ before the process exits, so an unattended guard that runs out of time refuses
737
+ with its reason. `MA_GUARD_DEADLINE_SECONDS` can lower the 5 s deadline, never
738
+ raise it.
739
+ - `install/templates/claude-hooks.json` registers the same hooks the installer
740
+ writes: tool-name matchers (`Bash`, `Edit|Write|NotebookEdit`,
741
+ `WebFetch|mcp__multi-agent-toolkit__.*`, `Read|Bash`) and a readme that states
742
+ which gates fail open and that `agent-guard.sh` fails closed unattended.
743
+ - Guard tests and the agent-guard and red-team smokes count an exit 2 as a
744
+ refusal only when stderr carries a rule's reason, so a crash, a timeout or a
745
+ missing decision in the policy code fails them.
746
+ - `state.currentPhase` moves forward on every completed phase, so resume re-enters after the last finished phase instead of after Phase 0. `phase-tracker.sh update <n> completed` calls the new `record-phase.mjs`, which writes through the locked state writer and never moves the value back.
747
+ - **An unattended run can execute its own documented steps.** Every command in
748
+ the phase docs now passes the fail-closed unattended guard as written, once
749
+ its placeholders are filled. Shell control flow moved into installed scripts,
750
+ each called as one command: the new `worktree-prepare.sh` (heal a stale lock
751
+ and dead admin entries, residue guard, add or re-enter, identity; JSON out)
752
+ and `build-lock.sh acquire|release`; `probe-evidence-capability.sh --platform
753
+ auto --stack-root` picks the platform from `stack-detect.sh` and records a
754
+ backend repo as `other` with a `skippedReason`; `repo-hygiene.sh
755
+ ensure|release|gitignore|prune <root>` runs without sourcing;
756
+ `triage-memory.mjs prior-art` answers every finding in one call;
757
+ `memory-save.sh --from-json` saves a synthesis array, bodies with spaces and
758
+ newlines included; `test-integrity-gate.mjs --out`, `plan-coverage-gate.mjs
759
+ --analysis-from-state --json-out`, `test-gap-scan.mjs --stack-from <state>` and
760
+ `render-agent-log-cost.sh --append <log>` replace the redirects, arrays and
761
+ `case` blocks around them. Write targets in the docs are spelled
762
+ `{worktreePath}/...`, LLM-written JSON goes through the Write tool, and
763
+ `stack-detect.sh --json` replaces the `eval`. The steps a run does not take
764
+ (credential read, evidence push, `gh pr create`, issue comment and progress
765
+ sync, release PR edit) carry a `# unattended: skipped` comment, and
766
+ `test/unattended-doc-lines.test.mjs` fails on any other refusal; its doc
767
+ scanner judges a template line with its placeholders filled.
768
+ - `gate-ledger.mjs park` is allowed from Bash again under
769
+ `MULTI_AGENT_UNATTENDED=1`, as `unattended-gates.md` instructs: parking only
770
+ stops the run. `append` stays refused.
771
+ - The autopilot runner's guard-registration check also requires `agent-guard.sh`
772
+ on the `WebFetch|mcp__multi-agent-toolkit__web_.*` matcher that the installer
773
+ registers.
774
+ - Desktop launch free text is refused only when its first word is an op or mode
775
+ word, the one position that can route; "Add unit test for X" is accepted.
776
+ Newlines, control characters, a leading `-`, quotes, backticks and URLs are
777
+ still refused, and the phone route still takes structured input only.
778
+ - The Codex and Copilot installs copy every vendored skill's `NOTICE-*.md` next
779
+ to the installed skills, so the attribution ships with them.
780
+
781
+ - Phase 3 no longer passes JSON through a `${X:-{}}` default, which bash 3.2
782
+ (the stock macOS `/bin/bash`) expands to `{\}`: the review decision gate read
783
+ that as unreadable input and every gated commit was refused, and the Step 3.0
784
+ merge came out empty. `smoke-shell-portability.sh` runs the documented blocks
785
+ under `/bin/bash` and rejects a brace default in any doc.
786
+ - `plan-critique-gate.mjs`: an `analysis` anchor resolves only on a requirement
787
+ id or a whole heading, and a rebuttal clears a binding objection with a file
788
+ anchor only as `path:line` plus a quote.
789
+ - Pre-existing claims (`_pre-existing.mjs`) need a cited line that the diff from
790
+ the base does not add or change, the same text elsewhere in the base file no
791
+ longer counts, a blank or punctuation-only line never qualifies, and a
792
+ failing-test log must sit in the checkout or the run's state directory, name
793
+ the test and show a failure marker.
794
+ - `spec-consistency-gate.mjs` matches `CON-` ids in any case and reads passive
795
+ and gerund waivers (`is waived`, `waiving`, `waived for`, `does not apply`).
796
+ - `symbol-existence-gate.mjs` resolves JSON keys by their full nested path: an
797
+ invented dotted key built from segments that exist elsewhere, or a bare leaf
798
+ that exists only nested, is reported missing.
799
+ - `evidence-gate.mjs`: with the gates active a test claim needs a positive
800
+ executed count, from the log or from the new `--junit` / `--xcresult` /
801
+ `--xcresult-json`; adapters gain `skipped` markers, and a Gradle log whose
802
+ every test task is `SKIPPED` or `NO-SOURCE` or a Maven `Tests are skipped.`
803
+ counts as zero. The `failed: 0` zero form is read only as a summary-list item,
804
+ so `Assertion failed: 0 == expected` stays a failure. The web and Node
805
+ adapters fail on vitest's `Errors N error` and yarn's `error Command failed`.
806
+ - `test-strength.mjs` reports a test that goes red only by failing to compile or
807
+ load without the change as `unjudged`, never red (adapter `loadError`
808
+ markers); red plus unjudged is a pass in the ledger, unjudged alone
809
+ not-applicable.
810
+ - `verify-citations.mjs` needs a quote of at least 8 non-space characters or
811
+ the whole line, and records not-applicable when there is nothing to check.
812
+ - `scaffold-gate.mjs`: a manifest `vars` entry cannot replace the per-run
813
+ `resultBundle`. The phase docs handle scaffold exit 3 as a halt and exit 2 as
814
+ a call error.
815
+ - Doc counts: 10 agent personas and Codex TOML files, 13 rules, 61 Copilot
816
+ sub-command skills, 158 external skills, the stack plugins' skill counts and
817
+ versions, and the toolkit's tool count.
818
+ - Product voice in `stack-adapters.md`, `sync/SKILL.md`,
819
+ `unattended-contract.md`, `phase-0-init.md`, `gen-facts.mjs` and the
820
+ `waitingFor` schema description; removed-mode leftovers in `help/SKILL.md`,
821
+ `payload-contracts.md` and the bug report template.
822
+ - **A launch request's input is a reference, not a prompt.** The run starts
823
+ with `--permission-prompts none`, so `launch-request.mjs` accepts a Jira key,
824
+ a GitHub issue URL, `repo#N`, `#N` or a Jira URL on the configured host, and
825
+ on the desktop channel free text that the plan passes as one quoted
826
+ argument. A newline, a control or format character, a leading `-`, a
827
+ flag-like token, and any token naming a pipeline op or mode keyword (read
828
+ from the command tree, the dispatcher's routing table, `phases.json`,
829
+ `launch.json` and the workspace options) is refused on every channel; the
830
+ phone route takes structured references only. `repo` must be a configured
831
+ autopilot repo or one registered with the new
832
+ `launch-request.mjs register-repo <path>` (refused under
833
+ `MULTI_AGENT_UNATTENDED=1`); any other directory is `403 repo-not-allowed`.
834
+ - `fetch-confluence.sh` refuses a host that is not a bare `host[:port]` before
835
+ the allowlist check and before any token is read (`host-malformed`, exit 6),
836
+ so `--host attacker.example/.confluence.example.com` and the same with `#`,
837
+ `?`, `@` or `\` no longer pass the suffix match; the check compares the string
838
+ curl receives. `issue-fetcher.sh` holds a Jira URL to the same shape and to
839
+ the configured Jira host (Atlassian Cloud only when none is configured)
840
+ before it re-dispatches with that host, instead of sending the Jira token to
841
+ whatever host the link named.
842
+ - `scrub` (the redacted contract views and every phone response) replaces
843
+ `host.tld/path` links written without a scheme, absolute paths under
844
+ `/Volumes`, `/private`, `/var`, `/opt` and `/tmp`, and any user's home
845
+ directory; the redacted runs view scrubs phase names too.
846
+ - `/multi-agent:autopilot-off` is declared `destructive: true` with
847
+ `confirm: required`, because `--now` abandons the item in flight, and it
848
+ names that item and asks before stopping it.
849
+ - Docs: the phone API's question-id pattern and audit outcomes
850
+ (`registry-unreadable`), the attended exit of `plan-critique-gate.mjs` and
851
+ `spec-consistency-gate.mjs` (3 on a usage error) and
852
+ `review-decision-gate.mjs` (2), the `scaffold-gate.mjs` row in the
853
+ unattended contract, and the picker contract's path.
854
+ - `lint-skills` rejects an unquoted frontmatter value YAML would not parse (a
855
+ `: ` inside it, or text after a flow collection), and an angle bracket in the
856
+ description of a skill that ships into the stack plugins. `signal-community`
857
+ had such a header; it now parses, and four external skill descriptions drop
858
+ angle brackets.
859
+ - `NOTICE-paul-hudson-skills.md` and `NOTICE-avdlee-swiftui-agent-skill.md`
860
+ attribute `swiftui-pro`, `swift-concurrency-pro`, `swiftdata-pro`,
861
+ `swift-testing-pro` and `swiftui-expert-skill` to their MIT upstreams, which
862
+ had no notice; the stack-plugin builder ships them with those skills.
863
+ - The evals of eleven renamed knowledge skills name the skill as it ships
864
+ (`callkit-voip`, not `callkit`), so a skill-creator run matches them to the
865
+ right skill.
866
+ - `build-stack-plugins.mjs` removes a plugin's `NOTICE-*.md` once its source
867
+ file is deleted, and bumps the version. It only removed a notice whose source
868
+ still existed but no longer named one of the plugin's skills.
869
+ - The autopilot publish step no longer takes the run's gate ledger as evidence.
870
+ It re-runs the stack adapter's build and test commands in the worktree, with
871
+ token-shaped variables, the ssh agent socket and askpass helpers removed and
872
+ a bounded timeout (`verify.timeoutSec`), and judges the output with
873
+ `evidence-gate.mjs --stack` and `test-summary.mjs`; a failure, zero tests, or a
874
+ stack with no commands refuses (`publish/verify-*`) unless
875
+ `verify.allowUnverifiedStack` is set. A ledger that names no test log is
876
+ refused as `publish/test-log`.
877
+ - The publish step pushes from a fresh bare staging repository with no system
878
+ config and a global config holding only the operator's `credential.*`
879
+ settings, instead of from the worktree behind a key denylist. `url.*`,
880
+ `http.proxy`, `http.curloptResolve`, `http.sslVerify`, `http.extraHeader`,
881
+ `credential.*`, `core.sshCommand` and includes in the worktree's config no
882
+ longer reach the push, the base fetch or the remote-branch check.
883
+ - The pushed branch must be the `branch` the run recorded in its state, and a
884
+ branch already on the remote is refused unless this session pushed it and its
885
+ tip is an ancestor of the run's HEAD (`publish/remote-branch`). A worktree
886
+ with uncommitted changes to tracked files is refused, since the tree tested
887
+ would not be the tree pushed.
888
+ - Agent-writable files are read as bounded regular files
889
+ (`lib/regular-file.mjs`): the PR request (read once and validated in process
890
+ with `validatePrRequest`), the run state, the test log (inside the worktree or
891
+ the run's directory), run states and trackers in the runner, `_run-paths.mjs`
892
+ and `gate-ledger.mjs`. A FIFO under any of those names blocked the tick.
893
+ - `gc-abandoned.sh` keeps a run parked with `verificationFailed` or `waitingFor`,
894
+ which gate-ledger's park writes with `status: failed` and pass 2 removed as
895
+ finished. The daily cleanup report also drops a worktree whose item's newest
896
+ attempt is parked, since a parked run leaves the queue when its session ends.
897
+ - The tick's credential probe also checks the credential the item's repo
898
+ publishes with (`gh auth status` for a GitHub host, `check --repo`), and
899
+ `verification-failed` rows refused at `publish/remote`, `publish/push` or
900
+ `publish/pr-create` count toward the circuit breaker; the runner now records
901
+ the refusing gate as `publishGate`.
902
+ - Spend in the arming check and the daily digest counts each run once, at the
903
+ largest cumulative `usd` any of its rows recorded, instead of adding every row
904
+ (`_cost.mjs` `attemptSpend`).
905
+ - `maxAskRounds` counts research rounds over the whole attempt log rather than
906
+ its last 50 rows.
907
+ - `runner.pid` is claimed by writing a temp file and hard-linking it into place,
908
+ the runner's other files are replaced by temp file and rename, and an
909
+ unparseable `runner.pid` younger than a minute is left for the tick writing
910
+ it. A run retired as died is marked `abandoned` through the locked state
911
+ writer with a `rev` bump; `status: abandoned` and `abandonedBy` are declared
912
+ in `agent-state.schema.json`.
913
+ - The Phase 0 state template in `phase-0-init.md` is a valid
914
+ `agent-state.schema.json` document (`schemaVersion`, an integer `shortId`,
915
+ phase keys 0-5), and a unit test holds it there. The schema declares the keys
916
+ the phases read (`inputType`, `offlineOnly`, `figmaUrl`, `instructionFiles`,
917
+ `contextLinks`, `crashContext`, `fortifyFinding`, `graylogContext`), and
918
+ `remoteType` accepts `generic-git` and `local`, which Phase 0 writes.
919
+ - `runs-index` groups a run with `waitingFor` set as `waiting` at any phase. A
920
+ run paused on a question at phase 0 was grouped `question`, whose offered
921
+ action is garbage-collecting an abandoned intake.
922
+ - `autopilot-status --subjects` no longer prints a `Full` pipeline-depth label
923
+ the runner never writes, and the menu bar drops the matching field.
924
+ - The contract manifest's `launch-spec` surface carries `launch.json`'s version
925
+ (1.1.0), and `phone-signed-request.schema.json` states the timestamp bounds
926
+ the server applies: 60 seconds behind, 5 ahead.
927
+
928
+ ## [20.2.1] - 2026-09-22
929
+
930
+ ### Fixed
931
+
932
+ - **Usage reporting could attribute a run to a work identity.** On a machine with
933
+ more than one identity, the reporting login came from `identities[0]` (or the
934
+ active `gh` account inside a work repo), so a run could land on the panel under
935
+ a corporate account rather than the personal login that owns the ingest token.
936
+ A new `usageLog.reportAs` pins the reporting login and is resolved before
937
+ `identities[0]`, `gh api user` and the OS user.
938
+
17
939
  ## [20.2.0] - 2026-09-21
18
940
 
19
941
  ### Added
@@ -1780,7 +2702,7 @@ A review of the three repositories together (pipeline, toolkit MCP, plugin marke
1780
2702
  - **Sourced from zsh, `credential-store-resolver.sh` printed the store path to stdout** and `figma-token.sh` asked for a single key named `figma figma_pat`.
1781
2703
  - **`validate-analysis-doc.mjs` crashed on a document without front matter,** failed the gate on a check it called a warning, listed the correct Turkish word `Onay` as a typo, and cited "Locked 37" in a list of 36.
1782
2704
  - **`multi-repo-pipeline.sh` committed `git add -A`** while its header said staged changes, and ignored `state.identity`. `plan-todos.sh` returned 0 for an unknown id. `update-issue-progress.sh` failed on macOS `mktemp` on the second call.
1783
- - **Smoke hygiene.** Thirty-six smokes: five asserted against the installed `~/.claude` copy instead of the repo, one passed when `sha256sum` was missing (`"" = ""`), eleven used predictable `/tmp` paths, five wrote probe files into the repo tree, five wrote into the real `$HOME`, four turned errexit on halfway through, four had assertions that could not fail, and the `THY` personal-data pattern matched `thyme` under `grep -i`.
2705
+ - **Smoke hygiene.** Thirty-six smokes: five asserted against the installed `~/.claude` copy instead of the repo, one passed when `sha256sum` was missing (`"" = ""`), eleven used predictable `/tmp` paths, five wrote probe files into the repo tree, five wrote into the real `$HOME`, four turned errexit on halfway through, four had assertions that could not fail, and a short personal-data pattern matched `thyme` under `grep -i`.
1784
2706
  - **Smaller ones.** `build-skills-index.mjs` recorded `|` and `>-` as descriptions for five skills, so `match-skills` could never score them; `learning-curve` and `aggregate-metrics` computed "cache ratio" with different formulas; `graph-build` omitted Go; `repo-map --include` matched substrings while documented as globs; `eval-mine-corpus` read the corpus from a path the writer never used inside a worktree; `gen-mode-dispatch` defaulted to a mode removed in 16.0.0; `scorecard` claimed no network and ran `npm audit`; `_dev-only-files` misgrouped its regex; `render-cost-summary` selected 0/0 phases; `gc-refs` matched `pr-body-final.md`; `credential-inventory` reported every key missing with rc 0 when no backend existed; `repo-cache` and `issue-fetcher` split scan roots on whitespace; `md2confluence-v3.py` detected every document as Turkish and its residual-character warning could never fire; `github-ssh-setup.sh` wrote `UseKeychain` on Linux; dead functions and stale headers in `cost-lib`, `extract-conventions`, `shadow-git`, `fetch-document`, `benchmark-phase-0`, `sync-parity-check`, `_mcp-register`, `_plugin-skills`, `cost-budget-check`, `triage-memory`, `migrate-prefs`, `eval-golden-tasks`; dangling references to `figma-navigation`, `/multi-agent:fix-bug`, `ask_choice.sh`, `refs/frontend-guide.md` and a `-v610` anchor.
1785
2707
  - **Vendored knowledge skills point at files that exist.** Twenty-six external skills linked 184 files that were never vendored; 58 were fetched from their upstream (Dimillian/Skills, MIT, provenance recorded), the rest de-linked. `help-skills` (Turkish, install-path catalog) is retired; `ios-module-structure` resolves its scripts relative to the skill; `ios-coding-standard` examples use a neutral domain.
1786
2708