@mmerterden/multi-agent-pipeline 20.2.1 → 20.3.1

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