@mmerterden/multi-agent-pipeline 17.6.0 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/CHANGELOG.md +310 -0
  2. package/README.md +76 -18
  3. package/README.tr.md +55 -16
  4. package/docs/adr/0002-instruction-driven-flag.md +1 -0
  5. package/docs/adr/0005-lazy-phase-docs.md +11 -1
  6. package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +1 -0
  7. package/docs/adr/0010-own-code-graph.md +1 -0
  8. package/docs/adr/0011-dormant-ci.md +25 -1
  9. package/docs/adr/0014-six-phase-consolidation.md +134 -0
  10. package/docs/adr/README.md +2 -1
  11. package/docs/architecture.md +37 -38
  12. package/docs/best-practices.md +1 -1
  13. package/docs/ecosystem.md +37 -26
  14. package/docs/engineering.md +1 -1
  15. package/docs/facts.json +45 -0
  16. package/docs/features.md +54 -53
  17. package/docs/performance.md +5 -5
  18. package/docs/recovery-guide.md +9 -9
  19. package/docs/server-readiness.md +188 -0
  20. package/docs/token-budget-history.md +3 -1
  21. package/index.js +18 -3
  22. package/install/_codex-agents.mjs +1 -1
  23. package/install/_common.mjs +42 -17
  24. package/install/_dev-only-files.mjs +8 -0
  25. package/install/_unattended-profile.mjs +113 -0
  26. package/install/index.mjs +48 -0
  27. package/install/templates/claude-hooks.json +1 -1
  28. package/install/templates/codex-instructions.md +1 -1
  29. package/install/templates/copilot-instructions.md +28 -28
  30. package/manifest.json +1065 -0
  31. package/package.json +6 -3
  32. package/pipeline/agents/dev-critic.md +3 -3
  33. package/pipeline/commands/figma-to-swiftui.md +1 -1
  34. package/pipeline/commands/multi-agent/SKILL.md +8 -8
  35. package/pipeline/commands/multi-agent/analysis/SKILL.md +9 -9
  36. package/pipeline/commands/multi-agent/autopilot/SKILL.md +7 -7
  37. package/pipeline/commands/multi-agent/channels/SKILL.md +15 -15
  38. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +6 -6
  39. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
  40. package/pipeline/commands/multi-agent/graph/SKILL.md +1 -1
  41. package/pipeline/commands/multi-agent/help/SKILL.md +62 -62
  42. package/pipeline/commands/multi-agent/language/SKILL.md +2 -2
  43. package/pipeline/commands/multi-agent/local/SKILL.md +11 -11
  44. package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +13 -13
  45. package/pipeline/commands/multi-agent/log/SKILL.md +2 -2
  46. package/pipeline/commands/multi-agent/manual-test/SKILL.md +9 -9
  47. package/pipeline/commands/multi-agent/model/SKILL.md +69 -0
  48. package/pipeline/commands/multi-agent/refactor/SKILL.md +3 -3
  49. package/pipeline/commands/multi-agent/resume/SKILL.md +4 -4
  50. package/pipeline/commands/multi-agent/resume-local/SKILL.md +19 -17
  51. package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
  52. package/pipeline/commands/multi-agent/route-off/SKILL.md +36 -0
  53. package/pipeline/commands/multi-agent/route-on/SKILL.md +74 -0
  54. package/pipeline/commands/multi-agent/route-status/SKILL.md +56 -0
  55. package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
  56. package/pipeline/commands/multi-agent/status/SKILL.md +54 -23
  57. package/pipeline/commands/multi-agent/steer/SKILL.md +2 -2
  58. package/pipeline/commands/multi-agent/sync/SKILL.md +12 -13
  59. package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
  60. package/pipeline/lib/_jira-auth.sh +8 -0
  61. package/pipeline/lib/analysis-jira-write.sh +32 -0
  62. package/pipeline/lib/ask-choice.sh +13 -2
  63. package/pipeline/lib/autopilot-state.sh +8 -0
  64. package/pipeline/lib/credential-inventory.sh +1 -1
  65. package/pipeline/lib/fatal.mjs +129 -0
  66. package/pipeline/lib/fetch-fortify.sh +1 -1
  67. package/pipeline/lib/figma-mcp-refresh.sh +18 -0
  68. package/pipeline/lib/figma-screenshot.sh +18 -0
  69. package/pipeline/lib/invoked-directly.mjs +43 -0
  70. package/pipeline/lib/jira-publish.sh +42 -0
  71. package/pipeline/lib/md2confluence-v3.py +47 -0
  72. package/pipeline/lib/model-rung.sh +142 -0
  73. package/pipeline/lib/outbound-gate.mjs +175 -0
  74. package/pipeline/lib/phase-schema.mjs +88 -0
  75. package/pipeline/lib/plan-todos.sh +32 -11
  76. package/pipeline/lib/post-pr-review.sh +77 -8
  77. package/pipeline/lib/repo-hygiene.sh +8 -3
  78. package/pipeline/lib/require-jq.sh +40 -0
  79. package/pipeline/lib/route-state.sh +161 -0
  80. package/pipeline/lib/run-paths.sh +335 -0
  81. package/pipeline/multi-agent-refs/_account-picker.md +1 -1
  82. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  83. package/pipeline/multi-agent-refs/_input-parser.md +1 -1
  84. package/pipeline/multi-agent-refs/analysis/evidence.md +0 -9
  85. package/pipeline/multi-agent-refs/analysis/intake.md +1 -1
  86. package/pipeline/multi-agent-refs/analysis/locked.md +21 -22
  87. package/pipeline/multi-agent-refs/analysis/render.md +1 -1
  88. package/pipeline/multi-agent-refs/analysis/synthesis.md +12 -6
  89. package/pipeline/multi-agent-refs/android-guide.md +1 -1
  90. package/pipeline/multi-agent-refs/audit-guide.md +13 -13
  91. package/pipeline/multi-agent-refs/channels/issue-comment.md +2 -2
  92. package/pipeline/multi-agent-refs/channels/jira.md +3 -3
  93. package/pipeline/multi-agent-refs/channels/pr.md +4 -4
  94. package/pipeline/multi-agent-refs/channels/wiki.md +1 -1
  95. package/pipeline/multi-agent-refs/component-dispatch.md +3 -3
  96. package/pipeline/multi-agent-refs/cross-cli-contract.md +31 -6
  97. package/pipeline/multi-agent-refs/features/autopilot-circuit-breaker.md +74 -4
  98. package/pipeline/multi-agent-refs/features/code-graph.md +5 -5
  99. package/pipeline/multi-agent-refs/features/cost-analysis.md +93 -0
  100. package/pipeline/multi-agent-refs/features/design-conformance.md +1 -1
  101. package/pipeline/multi-agent-refs/features/dev-critic.md +3 -3
  102. package/pipeline/multi-agent-refs/features/doctor.md +47 -2
  103. package/pipeline/multi-agent-refs/features/external-context-injection.md +3 -3
  104. package/pipeline/multi-agent-refs/features/maturity-followup.md +3 -3
  105. package/pipeline/multi-agent-refs/features/model-fallback.md +5 -5
  106. package/pipeline/multi-agent-refs/features/plan-todos.md +1 -1
  107. package/pipeline/multi-agent-refs/features/repo-map.md +1 -1
  108. package/pipeline/multi-agent-refs/features/review-delta.md +3 -3
  109. package/pipeline/multi-agent-refs/features/review-multi-repo.md +1 -1
  110. package/pipeline/multi-agent-refs/features/scope-check.md +4 -4
  111. package/pipeline/multi-agent-refs/features/skill-conformance.md +2 -2
  112. package/pipeline/multi-agent-refs/features/stack-skill-routing.md +1 -1
  113. package/pipeline/multi-agent-refs/features/verify-by-test.md +4 -4
  114. package/pipeline/multi-agent-refs/features/verify.md +83 -0
  115. package/pipeline/multi-agent-refs/features/visual-evidence.md +19 -19
  116. package/pipeline/multi-agent-refs/features/worktree-finalize.md +6 -6
  117. package/pipeline/multi-agent-refs/issue-jira-triad.md +10 -10
  118. package/pipeline/multi-agent-refs/knowledge.md +11 -11
  119. package/pipeline/multi-agent-refs/multi-repo-integration-build.md +13 -13
  120. package/pipeline/multi-agent-refs/payload-contracts.md +8 -8
  121. package/pipeline/multi-agent-refs/phases/log-format.md +10 -10
  122. package/pipeline/multi-agent-refs/phases/modes.md +30 -30
  123. package/pipeline/multi-agent-refs/phases/operations.md +21 -10
  124. package/pipeline/multi-agent-refs/phases/phase-0-init.md +25 -25
  125. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +599 -0
  126. package/pipeline/multi-agent-refs/phases/{phase-3-dev.md → phase-2-dev.md} +129 -49
  127. package/pipeline/multi-agent-refs/phases/{phase-4-review.md → phase-3-review.md} +225 -107
  128. package/pipeline/multi-agent-refs/phases/{phase-6-commit.md → phase-4-commit.md} +23 -23
  129. package/pipeline/multi-agent-refs/phases/{phase-7-report.md → phase-5-report.md} +29 -29
  130. package/pipeline/multi-agent-refs/phases.md +44 -48
  131. package/pipeline/multi-agent-refs/picker-contract.md +1 -1
  132. package/pipeline/multi-agent-refs/progress-contract.md +6 -6
  133. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  134. package/pipeline/multi-agent-refs/rules.md +7 -7
  135. package/pipeline/multi-agent-refs/swiftui-guide.md +2 -2
  136. package/pipeline/multi-agent-refs/tracker-contract.md +31 -32
  137. package/pipeline/multi-agent-refs/unattended-contract.md +129 -0
  138. package/pipeline/multi-agent-refs/wiki-capture.md +14 -14
  139. package/pipeline/preferences-template.json +9 -1
  140. package/pipeline/rules/outside-the-pipeline.md +1 -1
  141. package/pipeline/schemas/agent-state.schema.json +50 -50
  142. package/pipeline/schemas/analysis-output.schema.json +2 -2
  143. package/pipeline/schemas/autopilot-config.schema.json +1 -1
  144. package/pipeline/schemas/code-graph.schema.json +1 -1
  145. package/pipeline/schemas/criteria-manifest.schema.json +1 -1
  146. package/pipeline/schemas/dev-critic-output.schema.json +1 -1
  147. package/pipeline/schemas/diff-risk.schema.json +1 -1
  148. package/pipeline/schemas/migrations/prefs-2.4.0-to-2.5.0.mjs +2 -2
  149. package/pipeline/schemas/migrations/prefs-2.6.0-to-2.7.0.mjs +31 -0
  150. package/pipeline/schemas/migrations/state-2.1.0-to-2.2.0.mjs +129 -0
  151. package/pipeline/schemas/phases.json +105 -0
  152. package/pipeline/schemas/plan-todos.schema.json +5 -5
  153. package/pipeline/schemas/planning-output.schema.json +1 -1
  154. package/pipeline/schemas/prefs.schema.json +100 -56
  155. package/pipeline/schemas/reviewer-output.schema.json +3 -3
  156. package/pipeline/schemas/route-config.schema.json +74 -0
  157. package/pipeline/schemas/scope-check.schema.json +1 -1
  158. package/pipeline/schemas/test-gap.schema.json +1 -1
  159. package/pipeline/schemas/token-budget.json +12 -18
  160. package/pipeline/schemas/triage-output.schema.json +6 -6
  161. package/pipeline/scripts/README.md +3 -3
  162. package/pipeline/scripts/_code-graph.mjs +2 -2
  163. package/pipeline/scripts/_run-paths.mjs +372 -0
  164. package/pipeline/scripts/_smoke-root.sh +1 -1
  165. package/pipeline/scripts/aggregate-metrics.mjs +65 -65
  166. package/pipeline/scripts/autopilot-arming.mjs +2 -1
  167. package/pipeline/scripts/autopilot-intake.mjs +2 -1
  168. package/pipeline/scripts/autopilot-runner.mjs +206 -2
  169. package/pipeline/scripts/build-references.mjs +2 -1
  170. package/pipeline/scripts/build-stack-plugins.mjs +10 -2
  171. package/pipeline/scripts/capture-evidence.sh +7 -2
  172. package/pipeline/scripts/capture-flush.sh +8 -8
  173. package/pipeline/scripts/capture-resume.sh +3 -3
  174. package/pipeline/scripts/classify-plan-safety.mjs +3 -2
  175. package/pipeline/scripts/cost-analyze.mjs +600 -0
  176. package/pipeline/scripts/cost-budget-check.mjs +4 -12
  177. package/pipeline/scripts/council-view.mjs +2 -1
  178. package/pipeline/scripts/crush-json.mjs +2 -1
  179. package/pipeline/scripts/diff-explain.mjs +7 -10
  180. package/pipeline/scripts/diff-risk-score.mjs +2 -1
  181. package/pipeline/scripts/doctor.mjs +140 -6
  182. package/pipeline/scripts/evidence-gate.mjs +9 -3
  183. package/pipeline/scripts/feedback-send.mjs +12 -2
  184. package/pipeline/scripts/gc-abandoned.sh +32 -16
  185. package/pipeline/scripts/gc-tmp.sh +1 -1
  186. package/pipeline/scripts/gc-worktrees.sh +12 -5
  187. package/pipeline/scripts/gen-facts.mjs +175 -0
  188. package/pipeline/scripts/gen-mode-dispatch.mjs +32 -37
  189. package/pipeline/scripts/gen-ref-toc.mjs +1 -1
  190. package/pipeline/scripts/github-ssh-setup.sh +64 -7
  191. package/pipeline/scripts/graph-mermaid.mjs +4 -2
  192. package/pipeline/scripts/graph-report.mjs +1 -1
  193. package/pipeline/scripts/jira-attach.sh +1 -1
  194. package/pipeline/scripts/keychain-save.sh +101 -30
  195. package/pipeline/scripts/learn-from-transcripts.mjs +3 -2
  196. package/pipeline/scripts/learning-curve.mjs +36 -31
  197. package/pipeline/scripts/log-metric.sh +17 -4
  198. package/pipeline/scripts/make-manifest.mjs +199 -0
  199. package/pipeline/scripts/memory-save.sh +1 -1
  200. package/pipeline/scripts/migrate-prefs.mjs +24 -6
  201. package/pipeline/scripts/migrate-state.mjs +94 -4
  202. package/pipeline/scripts/phase-banner.sh +26 -22
  203. package/pipeline/scripts/phase-tracker.sh +48 -10
  204. package/pipeline/scripts/plan-coverage-gate.mjs +8 -4
  205. package/pipeline/scripts/pre-commit-check.sh +7 -0
  206. package/pipeline/scripts/pre-push-check.sh +7 -0
  207. package/pipeline/scripts/purge.sh +23 -6
  208. package/pipeline/scripts/render-agent-log-cost.sh +10 -3
  209. package/pipeline/scripts/render-cost-summary.sh +9 -2
  210. package/pipeline/scripts/render-work-summary.sh +14 -7
  211. package/pipeline/scripts/review-file-filter.mjs +5 -3
  212. package/pipeline/scripts/review-scope.mjs +2 -1
  213. package/pipeline/scripts/routine-registry.mjs +2 -1
  214. package/pipeline/scripts/run-aggregator.mjs +26 -20
  215. package/pipeline/scripts/run-metrics.mjs +4 -2
  216. package/pipeline/scripts/runs-index.mjs +353 -0
  217. package/pipeline/scripts/scorecard-snapshot.mjs +178 -0
  218. package/pipeline/scripts/search-logs.sh +18 -0
  219. package/pipeline/scripts/smoke-cross-cli-behavior.sh +6 -6
  220. package/pipeline/scripts/smoke-schema-validation.sh +26 -7
  221. package/pipeline/scripts/test-gap-scan.mjs +2 -1
  222. package/pipeline/scripts/test-integrity-gate.mjs +2 -1
  223. package/pipeline/scripts/token-budget-report.mjs +13 -2
  224. package/pipeline/scripts/triage-memory.mjs +2 -2
  225. package/pipeline/scripts/update-issue-progress.sh +56 -7
  226. package/pipeline/scripts/usage-report.mjs +12 -1
  227. package/pipeline/scripts/validate-analysis-doc.mjs +75 -18
  228. package/pipeline/scripts/validate-code-graph.mjs +6 -3
  229. package/pipeline/scripts/validate-complaint-doc.mjs +2 -1
  230. package/pipeline/scripts/validate-diff-risk.mjs +6 -3
  231. package/pipeline/scripts/validate-planning.mjs +1 -1
  232. package/pipeline/scripts/validate-reviewer.mjs +1 -1
  233. package/pipeline/scripts/validate-state.mjs +45 -5
  234. package/pipeline/scripts/validate-test-gap.mjs +6 -3
  235. package/pipeline/scripts/validate-triage.mjs +6 -4
  236. package/pipeline/scripts/verify-citations.mjs +4 -2
  237. package/pipeline/scripts/verify.mjs +327 -0
  238. package/pipeline/scripts/worktree-finalize.sh +18 -9
  239. package/pipeline/scripts/write-state.mjs +154 -15
  240. package/pipeline/skills/.skill-manifest.json +37 -21
  241. package/pipeline/skills/.skills-index.json +104 -5
  242. package/pipeline/skills/shared/README.md +15 -6
  243. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +2 -2
  244. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +2 -2
  245. package/pipeline/skills/shared/core/multi-agent/SKILL.md +69 -71
  246. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +3 -3
  247. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +14 -14
  248. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +5 -5
  249. package/pipeline/skills/shared/core/multi-agent-graph/SKILL.md +1 -1
  250. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +25 -23
  251. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -2
  252. package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +2 -2
  253. package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +8 -8
  254. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +6 -6
  255. package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +71 -0
  256. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +3 -3
  257. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +1 -1
  258. package/pipeline/skills/shared/core/multi-agent-resume-local/SKILL.md +7 -7
  259. package/pipeline/skills/shared/core/multi-agent-route-off/SKILL.md +39 -0
  260. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +76 -0
  261. package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +59 -0
  262. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
  263. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +35 -11
  264. package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +2 -2
  265. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +6 -5
  266. package/pipeline/skills/shared/external/macos-spm-app-packaging/assets/templates/package_app.sh +4 -1
  267. package/pipeline/skills/shared/external/macos-spm-app-packaging/assets/templates/setup_dev_signing.sh +4 -1
  268. package/pipeline/skills/shared/external/macos-spm-app-packaging/assets/templates/sign-and-notarize.sh +2 -1
  269. package/pipeline/skills/skills-index.md +13 -4
  270. package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +0 -263
  271. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +0 -344
  272. package/pipeline/multi-agent-refs/phases/phase-5-test.md +0 -182
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Continue already-done LOCAL work through the pipeline tail: Review → Build+Test → Commit/PR → Report (technical analysis + Jira test-scenario comment). No dev phase. Use when local work is already done and only review, build, commit and reporting remain."
3
- description-tr: "Halihazırda bitmiş LOKAL işi pipeline kuyruğundan geçirir: Review → Build+Test → Commit/PR → Report (teknik analiz + Jira test-senaryosu yorumu). Dev fazı yok."
2
+ description: "Continue already-done LOCAL work through the pipeline tail: Review (with its build gate) → Commit/PR → Report (technical analysis + Jira test-scenario comment). No dev phase. Use when local work is already done and only review, build, commit and reporting remain."
3
+ description-tr: "Halihazırda bitmiş LOKAL işi pipeline kuyruğundan geçirir: Review (build kapısıyla) → Commit/PR → Report (teknik analiz + Jira test-senaryosu yorumu). Dev fazı yok."
4
4
  allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdate, TaskList, TaskGet, AskUserQuestion, WebFetch, WebSearch, Skill
5
5
  ---
6
6
 
@@ -25,7 +25,7 @@ You already did the work locally - wrote code on the current branch and maybe
25
25
 
26
26
  ```bash
27
27
  /multi-agent:resume-local # current branch vs its base; resolve Jira id from branch name
28
- /multi-agent:resume-local PROJ-12345 # bind to an explicit Jira id for the Phase 7 comment
28
+ /multi-agent:resume-local PROJ-12345 # bind to an explicit Jira id for the Phase 5 comment
29
29
  /multi-agent:resume-local --base develop # override the base branch for the diff
30
30
  /multi-agent:resume-local autopilot # no gate prompts: auto-fix blocking findings, auto-PR, auto-comment
31
31
  ```
@@ -34,13 +34,15 @@ You already did the work locally - wrote code on the current branch and maybe
34
34
 
35
35
  ```
36
36
  Phase 0: Init → project/branch detect, resolve base + diff (work-already-done), Jira id, state (NO worktree)
37
- Phase 4: Review → deterministic gates + parallel review (Fable + Opus + Sonnet) + Fable triage
38
- Phase 5: Build+Test → stack-aware build gate + run existing tests; SUCCESS required (automated, not the interactive user-test)
39
- Phase 6: Commit → commit remaining local changes + push + open PR if none exists
40
- Phase 7: Report → technical analysis + Jira comment with test scenarios (channels: Jira / PR / Confluence / Wiki)
37
+ Phase 3: Review → the Verify gate first (stack-aware build + existing tests; SUCCESS required), then
38
+ parallel review (Fable + Opus + Sonnet) + Fable triage
39
+ Phase 4: Commit → commit remaining local changes + push + open PR if none exists
40
+ Phase 5: Report → technical analysis + Jira comment with test scenarios (channels: Jira / PR / Confluence / Wiki)
41
41
  ```
42
42
 
43
- Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `ship` treats the current branch's local changes as the Phase 3 output.
43
+ Phases 1-2 (Plan / Dev) are skipped by design - `ship` treats the current branch's local changes as the Phase 2 output.
44
+
45
+ **Why Review runs the build gate here.** Verify is Phase 2 Dev's exit gate since v19.0.0, and this mode has no Dev: the work arrived already written. The gate still has to run, so Review runs it before dispatching reviewers, which is what Review Stage 1 did before the consolidation. Reviewing a branch whose build was never checked is the failure this ordering prevents.
44
46
 
45
47
  ## Phase 0 - Context resolution (finish-specific)
46
48
 
@@ -52,12 +54,12 @@ Phases 1-3 (Analysis / Planning / Dev) are skipped by design - `ship` treats t
52
54
 
53
55
  ## Phase execution (reuse the existing phase contracts)
54
56
 
55
- - **Phase 4 Review** - run per `$HOME/.claude/multi-agent-refs/phases/phase-4-review.md` against the resolved diff: deterministic gates (Step 1.x), stack-specific parallel reviewers (Fable + Opus + Sonnet on Claude Code; GPT + Opus + Sonnet on Copilot CLI), Fable triage → `triage.accepted`. Blocking/important accepted findings:
57
+ - **Phase 4 Review** - run per `$HOME/.claude/multi-agent-refs/phases/phase-3-review.md` against the resolved diff: deterministic gates (Step 1.x), stack-specific parallel reviewers (Fable + Opus + Sonnet on Claude Code; GPT + Opus + Sonnet on Copilot CLI), Fable triage → `triage.accepted`. Blocking/important accepted findings:
56
58
  - interactive: present them and ask (`AskUserQuestion`) whether to fix now (loop back through a minimal Phase-3-style TDD fix) or proceed;
57
59
  - `autopilot` (or `prefs.global.resumeLocal.autoFix == true`): auto-fix accepted blocking/important findings, then re-review the fix, before advancing.
58
- - **Phase 5 Build+Test** - the **automated success gate** (this is what "build+test success" means here; the interactive device user-test is `/multi-agent:manual-test`). Stack-aware: build via `figma-config.build` (iOS scheme / Android gradle / detected backend/web build) and run the existing test suite if present (`swift test` / `xcodebuild test` / `./gradlew test` / `pytest` / `npm test` / `vitest`). Require success to advance; on failure, surface logs and (interactive) stop or (autopilot) attempt a bounded fix loop. **If the repo has no tests, report "no tests present" - never fabricate test results.**
59
- - **Phase 6 Commit/PR** - per `$HOME/.claude/multi-agent-refs/phases/phase-6-commit.md`: stage + commit any remaining local changes with a conventional message (`{type}(scope): desc [{JIRA_KEY}-{id}]`), push, and open a PR **only if one does not already exist** for the branch. PR body per `$HOME/.claude/multi-agent-refs/rules.md "External System Outputs"` and `$HOME/.claude/rules/git-conventions.md` - `Ref: #N` / `Related: #N`, never `Closes/Fixes/Resolves`; NO AI/bot attribution anywhere.
60
- - **Phase 7 Report** - per `$HOME/.claude/multi-agent-refs/phases/phase-7-report.md` + `channels.md`: produce the **technical analysis** and **test scenarios**, then post to the configured channels. Default content for `ship`: a Jira **comment** carrying the technical analysis + the test scenarios (and, when the PR was opened, the PR description). Every body runs through the humanizer; bot/tool/AI signatures are FORBIDDEN in comments.
60
+ - **Phase 3 Verify gate** - the **automated success gate** (this is what "build+test success" means here; the interactive device user-test is `/multi-agent:manual-test`). Stack-aware: build via `figma-config.build` (iOS scheme / Android gradle / detected backend/web build) and run the existing test suite if present (`swift test` / `xcodebuild test` / `./gradlew test` / `pytest` / `npm test` / `vitest`). Require success to advance; on failure, surface logs and (interactive) stop or (autopilot) attempt a bounded fix loop. **If the repo has no tests, report "no tests present" - never fabricate test results.**
61
+ - **Phase 4 Commit/PR** - per `$HOME/.claude/multi-agent-refs/phases/phase-4-commit.md`: stage + commit any remaining local changes with a conventional message (`{type}(scope): desc [{JIRA_KEY}-{id}]`), push, and open a PR **only if one does not already exist** for the branch. PR body per `$HOME/.claude/multi-agent-refs/rules.md "External System Outputs"` and `$HOME/.claude/rules/git-conventions.md` - `Ref: #N` / `Related: #N`, never `Closes/Fixes/Resolves`; NO AI/bot attribution anywhere.
62
+ - **Phase 5 Report** - per `$HOME/.claude/multi-agent-refs/phases/phase-5-report.md` + `channels.md`: produce the **technical analysis** and **test scenarios**, then post to the configured channels. Default content for `ship`: a Jira **comment** carrying the technical analysis + the test scenarios (and, when the PR was opened, the PR description). Every body runs through the humanizer; bot/tool/AI signatures are FORBIDDEN in comments.
61
63
 
62
64
  ## Modes
63
65
 
@@ -70,17 +72,17 @@ Before writing anything outward-facing - PR body, Jira comment, Confluence pag
70
72
 
71
73
  ## Required: Phase Tracker Contract
72
74
 
73
- **The phase tracker is required.** Full spec: [`$HOME/.claude/multi-agent-refs/tracker-contract.md`]($HOME/.claude/multi-agent-refs/tracker-contract.md). `ship` registers its active phase set - `0:Init 4:Review 5:Build+Test 6:Commit 7:Report` - but NEVER resets a tracker that an earlier run already built (load-or-continue; contract section "Continuation runs"):
75
+ **The phase tracker is required.** Full spec: [`$HOME/.claude/multi-agent-refs/tracker-contract.md`]($HOME/.claude/multi-agent-refs/tracker-contract.md). `ship` registers its active phase set - `0:Init 3:Review 4:Commit 5:Report` - but NEVER resets a tracker that an earlier run already built (load-or-continue; contract section "Continuation runs"):
74
76
 
75
77
  ```bash
76
78
  # Phase 0, first shell call (every CLI). init ONLY when no prior state exists -
77
- # a task handed off from Phase 5 ("awaiting local test") keeps its full
78
- # phase 0-3 history (elapsed, tokens, USD).
79
+ # a task handed off from the user test inside Phase 3 ("awaiting local test")
80
+ # keeps its full phase 0-2 history (elapsed, tokens, USD).
79
81
  STATE="$HOME/.claude/logs/multi-agent/${TASK_ID}/tracker-state.json"
80
82
  if [ ! -f "$STATE" ]; then
81
83
  bash $HOME/.claude/scripts/phase-tracker.sh init "$TASK_ID"
82
84
  fi
83
- for p in "0:Init" "4:Review" "5:Build+Test" "6:Commit" "7:Report"; do
85
+ for p in "0:Init" "3:Review" "4:Commit" "5:Report"; do
84
86
  bash $HOME/.claude/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}" # idempotent: existing phases keep their history
85
87
  done
86
88
  bash $HOME/.claude/scripts/phase-tracker.sh update 0 in_progress
@@ -91,7 +93,7 @@ bash $HOME/.claude/scripts/phase-tracker.sh update <N> in_progress|completed|fai
91
93
  bash $HOME/.claude/scripts/phase-tracker.sh tokens <N> <in> <out> [cached]
92
94
  ```
93
95
 
94
- **Continuation path (prior state existed):** (1) if Phase 5 was left `in_progress` with `Now: awaiting local test (user)`, mark it `update 5 completed` + `meta 5 Result "local test done (user)"` before finish's own work (finish re-opens it with `update 5 in_progress` when its Build+Test gate runs; elapsed keeps the original `started_at`, which is expected); (2) print ONE line in `outputLanguage` summarizing the inherited history, e.g. `Continuing PROJ-12345: phases 0-3 finished earlier (12m, 38.4k tok, ~$0.74)` (USD via `phase-tracker.sh cost total`); (3) `render`.
96
+ **Continuation path (prior state existed):** (1) if Phase 3 was left `in_progress` with `Now: awaiting local test (user)`, mark it `update 3 completed` + `meta 3 Result "local test done (user)"` before finish's own work (finish re-opens it with `update 3 in_progress` when its Verify gate runs; elapsed keeps the original `started_at`, which is expected); (2) print ONE line in `outputLanguage` summarizing the inherited history, e.g. `Continuing PROJ-12345: phases 0-3 finished earlier (12m, 38.4k tok, ~$0.74)` (USD via `phase-tracker.sh cost total`); (3) `render`.
95
97
 
96
98
  ### Visual channel - Claude Code (native TaskList widget, required)
97
99
 
@@ -194,7 +194,7 @@ Every host runs three reviewers; only the second slot differs, because GPT-5.4 e
194
194
 
195
195
  With the `fable` rung disabled by prefs the Claude Code panel is two reviewers (Opus + Sonnet); see `$HOME/.claude/multi-agent-refs/features/model-fallback.md`.
196
196
 
197
- Each reviewer receives the diff, the module review guides from Step 2b (when any were found), plus the standard reviewer system prompt (see `$HOME/.claude/multi-agent-refs/phases/phase-4-review.md` for the prompt contract). Output: structured `findings[]` per reviewer.
197
+ Each reviewer receives the diff, the module review guides from Step 2b (when any were found), plus the standard reviewer system prompt (see `$HOME/.claude/multi-agent-refs/phases/phase-3-review.md` for the prompt contract). Output: structured `findings[]` per reviewer.
198
198
 
199
199
  ### 4. Store-compliance cross-reference
200
200
 
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: "Disable model routing and keep its rules, so turning it back on does not re-ask for the same configuration. Use when asked to turn model routing off."
3
+ description-tr: "Model yönlendirmesini kapatır ve kurallarını saklar; tekrar açıldığında aynı yapılandırma yeniden sorulmaz."
4
+ ---
5
+
6
+ # multi-agent route-off - disarm routing, keep the configuration
7
+
8
+ ```bash
9
+ bash "$HOME/.claude/lib/route-state.sh" off
10
+ ```
11
+
12
+ Sets `prefs.global.modelRouting.enabled` to `false`. Dispatch returns to the
13
+ plain ladder immediately: every persona takes its `preferredModel`, and the
14
+ `modelFallback` rules are the only thing that can move it.
15
+
16
+ ## The rules are not deleted
17
+
18
+ `strategy`, `scope`, `rules[]` and `budgetCeilingUsd` all survive. `route-on`
19
+ brings back exactly what was configured, without asking again.
20
+
21
+ This is the same contract `autopilot-off` follows with its repo selection, for
22
+ the same reason: a command named after a toggle that quietly discards
23
+ configuration is a destructive action in disguise. To actually remove the rules,
24
+ replace them with an empty array:
25
+
26
+ ```bash
27
+ echo '[]' > /tmp/none.json
28
+ bash "$HOME/.claude/lib/route-state.sh" set-rules /tmp/none.json
29
+ ```
30
+
31
+ ## What stays behind
32
+
33
+ Routing decisions already written to the cost ledger stay there. They are a
34
+ record of what happened on past runs, and deleting them would make a run's cost
35
+ unexplainable after the fact - which is the one thing the ledger exists to
36
+ prevent.
@@ -0,0 +1,74 @@
1
+ ---
2
+ description: "Enable policy-driven model routing: pick a strategy, a scope, and the rules that say which rung a call lands on. Use when asked to turn model routing on."
3
+ description-tr: "Politika güdümlü model yönlendirmesini açar: strateji, kapsam ve hangi çağrının hangi basamağa düşeceğini söyleyen kuralları sorar."
4
+ argument-hint: "[--strategy=manual|task-fit|cost-ceiling] [--scope=subagent,bulk-read,research]"
5
+ ---
6
+
7
+ # multi-agent route-on - arm model routing
8
+
9
+ ```bash
10
+ bash "$HOME/.claude/lib/route-state.sh" on ${ARGUMENTS}
11
+ ```
12
+
13
+ Routing ships **off**. This is the command that turns it on, and it writes to
14
+ `prefs.global.modelRouting`, validated against the repo's `schemas/route-config.schema.json`.
15
+
16
+ ## What a rule is
17
+
18
+ ```json
19
+ { "when": { "persona": "code-reviewer" }, "prefer": ["opus", "sonnet"] }
20
+ { "when": { "phase": 2 }, "prefer": ["sonnet", "haiku"] }
21
+ ```
22
+
23
+ Ordered, first match wins. `when` matches on `persona`, `phase` (0..5) or
24
+ `taskKind`; `prefer` lists rungs in descending preference.
25
+
26
+ **Rung names are the contract; model ids are not.** `opus` is a rung here and a
27
+ model id in `cost-table.json`, and the second can change without anyone editing
28
+ a rule. Writing `claude-opus-5` into a rule pins a decision to a string that will
29
+ go stale.
30
+
31
+ Set rules with:
32
+
33
+ ```bash
34
+ bash "$HOME/.claude/lib/route-state.sh" set-rules path/to/rules.json
35
+ ```
36
+
37
+ ## Strategies
38
+
39
+ | Strategy | What it does |
40
+ |---|---|
41
+ | `manual` | only the explicit rules apply, nothing is inferred. The default, because a router that guesses is a router nobody can predict |
42
+ | `task-fit` | a rule may match on `taskKind`, and the cheapest rung clearing it is chosen |
43
+ | `cost-ceiling` | rungs downgrade as the run approaches `budgetCeilingUsd` |
44
+
45
+ ## Scope, and the value that is not in it
46
+
47
+ `scope` names the call sites routing may act on: `subagent`, `bulk-read`,
48
+ `research`. Every one of them is a call **this pipeline makes itself**.
49
+
50
+ There is no `host-session` value, and that absence is enforced by that schema
51
+ rather than written as advice. Routing a host session means rewriting the CLI's
52
+ base URL to point at a local gateway - which sends the user's *entire* session
53
+ through a third layer, including work that has nothing to do with this pipeline,
54
+ breaks the subscription's auth model, and silently changes which model answered.
55
+ Passing `--scope=host-session` is refused with that reason, not ignored.
56
+
57
+ ## The limit this command prints every time
58
+
59
+ On Claude Code a subagent cannot be dispatched to a non-Anthropic model: subagent
60
+ dispatch belongs to the host, not to us. So Phase 1, 2 and 3 personas stay inside
61
+ the Anthropic ladder no matter what the rules say, and external providers apply
62
+ only at `bulk-read` and `research`, where the pipeline makes the HTTP call.
63
+
64
+ This is printed by `route-status` on every invocation instead of living in a doc,
65
+ because the question it answers - "routing is on, why is the reviewer still on
66
+ Opus" - otherwise arrives days later as a bug report.
67
+
68
+ ## Related
69
+
70
+ - `/multi-agent:route-off` - disables routing and **keeps** the rules
71
+ - `/multi-agent:route-status` - what is active, and what it costs
72
+ - `/multi-agent:model` - whether the top rung exists at all. That is a different
73
+ question: this command decides which rung a call picks, that one decides
74
+ whether the top one is in play
@@ -0,0 +1,56 @@
1
+ ---
2
+ description: "Report model routing: whether it is armed, which rule applies where, which rung the last dispatches took, and what this run has cost. Use when asked which model is being used or why."
3
+ description-tr: "Model yönlendirmesinin durumunu raporlar: açık mı, hangi kural nerede geçerli, son çağrılar hangi basamağa gitti, bu koşu ne tuttu."
4
+ ---
5
+
6
+ # multi-agent route-status - what is actually routing
7
+
8
+ ```bash
9
+ bash "$HOME/.claude/lib/route-state.sh" status
10
+ ```
11
+
12
+ Reports the stored policy, then the part that matters more: **what it can and
13
+ cannot reach.**
14
+
15
+ ## Three states, told apart
16
+
17
+ | Output | Meaning |
18
+ |---|---|
19
+ | `routing: false`, rules present | configured and disarmed. `route-on` restores it as-is; nothing is lost |
20
+ | `routing: true`, `rules: 0` | armed with nothing to match. Not an error - a configuration state, and the most common "I turned it on and nothing changed" |
21
+ | `routing: true` with rules listed | live. Each rule is printed as `when <key>=<value> -> rung > rung` |
22
+
23
+ A disabled router with rules is deliberately not reported as "off" alone: that
24
+ reads as "unconfigured" and sends the user through `route-on`'s questions a
25
+ second time.
26
+
27
+ ## The limit, printed every time
28
+
29
+ On Claude Code a subagent cannot be sent to a non-Anthropic model. Subagent
30
+ dispatch belongs to the host; the pipeline asks for a persona and the host
31
+ decides what answers. So Phase 1, 2 and 3 personas stay inside the Anthropic
32
+ ladder whatever the rules say, and an external provider is only reachable where
33
+ the pipeline makes the HTTP call itself - `bulk-read.sh` and `research_ask`.
34
+
35
+ This paragraph is output, not documentation, because the alternative is the
36
+ question arriving later as "routing is on but the reviewer is still on Opus, is
37
+ it broken". It is not broken; it is the seam.
38
+
39
+ ## Where decisions are recorded
40
+
41
+ With `recordDecisions: true` (the default) every routing decision is written to
42
+ the cost ledger: which rule matched, which rung it chose, and why. That is what
43
+ makes a run's cost explainable after it finished - a router whose choices are not
44
+ recorded cannot be audited, and the cost question always arrives after the run,
45
+ never during it.
46
+
47
+ Per-run cost and the model breakdown come from the same ledger:
48
+
49
+ ```bash
50
+ node "$HOME/.claude/scripts/token-budget-report.mjs" --json
51
+ ```
52
+
53
+ ## Related
54
+
55
+ - `/multi-agent:route-on` / `/multi-agent:route-off` - arm and disarm
56
+ - `/multi-agent:model` - whether the top rung exists at all
@@ -558,7 +558,7 @@ Re-run scan from Step 1. Show final status:
558
558
  All tokens present. Pipeline ready to use.
559
559
 
560
560
  Optional per-project features (configured on first use, nothing to do now):
561
- • Phase 7 Report Step 2 Wiki - auto-generates component wiki pages + Figma
561
+ • Phase 5 Report Step 2 Wiki - auto-generates component wiki pages + Figma
562
562
  screenshots. Activates when (a) task is a component AND (b) a Figma token
563
563
  is in Keychain. Four adapters supported: submodule / in-repo / github-wiki
564
564
  / separate-repo. First run asks: use auto-detected path, use a custom
@@ -803,7 +803,7 @@ All tokens are optional in the sense that every service can be answered with Ski
803
803
  Offer to merge `$HOME/.claude/templates/claude-hooks.json`: three `PreToolUse` gates that block on a non-zero exit (secret scan, agent-guard, read-size) plus three capture hooks that block nothing (`PreCompact`, `SessionEnd`, `SessionStart`). What each does: `$HOME/.claude/multi-agent-refs/picker-contract.md`.
804
804
 
805
805
  - Ask (picker): "Install the pipeline's hooks into `~/.claude/settings.json`?" Default Yes.
806
- - On Yes, deep-merge EVERY event in the template's `hooks` object, not `PreToolUse` alone - merging one event silently drops the capture hooks, and a run killed before Phase 7 then loses its findings exactly as it did before they existed. Preserve existing hooks; never duplicate a matcher already calling the same script.
806
+ - On Yes, deep-merge EVERY event in the template's `hooks` object, not `PreToolUse` alone - merging one event silently drops the capture hooks, and a run killed before Phase 5 then loses its findings exactly as it did before they existed. Preserve existing hooks; never duplicate a matcher already calling the same script.
807
807
  - Say what the merge does NOT cover: only the three gates need no run-specific arguments, so only they are hookable; the rest are phase-enforced.
808
808
  - Say what it does not turn on: the read-size gate is inert until `prefs.global.bulkRead.mode` is set. Recommend `observe` first. Why, and the Phase 3 exemption: `$HOME/.claude/multi-agent-refs/picker-contract.md`.
809
809
 
@@ -9,43 +9,56 @@ Show every active and completed task as a table.
9
9
 
10
10
  ## Steps
11
11
 
12
- 1. **Detect the project** - find the repo root from cwd (otherwise scan every known repo):
13
- - `~/my-ios-app/.worktrees/`
14
- - `~/my-figma-app/.worktrees/`
15
- - `~/my-ui-components/.worktrees/`
12
+ 1. **Ask the producer, do not go looking.** One command answers the whole
13
+ question:
16
14
 
17
- 2. **Scan worktrees** - read `agent-state.json` in each worktree dir. **Also scan the log dir**, because a task whose PR is open has no worktree any more (Phase 6 removes it and salvages its state): `find $HOME/.claude/logs/multi-agent -maxdepth 4 -name agent-state.json -path '*/artifacts/*'`. (`-maxdepth 4`, not 3: Phase 6 always passes `--project`, so the salvaged copy lands at `<project>/<task-id>/artifacts/agent-state.json`, which a depth-3 scan can never reach.) Merge both sets by `taskId`, preferring the worktree copy when both exist, and render a finalized task with its `worktreeRemovedAt` rather than omitting it - a task that shipped should not vanish from status.
18
15
  ```bash
19
- find {repo}/.worktrees/ -name "agent-state.json" -maxdepth 2
16
+ node "$HOME/.claude/scripts/runs-index.mjs" # grouped table
17
+ node "$HOME/.claude/scripts/runs-index.mjs" --json # the same records
20
18
  ```
21
19
 
22
- 3. **Parse state** - for each task:
23
- - `taskId`, `branch`, `currentPhase`, `status`, `startedAt`, `autopilot`
24
-
25
- 3b. **Sort into three groups, and label them.** `in_progress` alone cannot tell
26
- a run that is waiting for you from one that died, and on this machine that
27
- difference covered 20 runs: 3 were holding at Phase 6/7 with their PR already
28
- open, 11 were left at a Phase 0 question with nothing built, 6 stopped
29
- mid-development. One "in progress" label for all three is what made a
30
- finished job and a crashed one share a row.
20
+ `runs-index.mjs` resolves through `lib/run-paths.sh` / `scripts/_run-paths.mjs`,
21
+ so it sees both directory layouts (`<project>/<id>/` and the flat `<id>/`),
22
+ the salvaged `artifacts/` copy Phase 4 leaves behind, and every spelling of a
23
+ task id - and it counts a run that exists in both layouts once. Do NOT
24
+ re-scan the tree by hand: the earlier instruction here listed three
25
+ hard-coded `.worktrees/` paths and a single `find` depth, and on a real
26
+ install that combination missed a quarter of the runs and double-counted
27
+ others. It also scanned worktrees for `agent-state.json`, which Phase 0 has
28
+ never written there ("never inside the worktree", `phases/phase-0-init.md`).
29
+
30
+ The JSON and the table are rendered from the same records, so a dashboard and
31
+ this command cannot disagree.
32
+
33
+ 2. **Fields per run** (already in the output): `taskId`, `project`, `branch`,
34
+ `currentPhase`, `status`, `startedAt`, `worktreePath`, `prUrl`, `autopilot`,
35
+ `phases[]`, `tokens`, `estUsd`, `group`, plus `duplicateOf` when the run also
36
+ exists in the other layout and `salvaged` when its state is the Phase 4 copy.
37
+
38
+ 3. **Groups are computed, not judged.** `runs-index.mjs` assigns `group` by the
39
+ table below; report what it returns rather than re-deriving it. `in_progress`
40
+ alone cannot tell a run that is waiting for you from one that died, and on
41
+ this machine that difference covered 21 runs.
31
42
 
32
43
  | Group | Test | Action offered |
33
44
  |---|---|---|
34
- | Waiting on you | `status == "awaiting_input"`, or a `pr.url`, or phase 6/7 | `resume #N` - the work landed, it needs your answer |
35
- | Stopped mid-development | anything else past phase 0 | `resume #N` or `kill #N` |
36
- | Left at a question | phase 0 | `garbage-collect --abandoned` - nothing was built |
45
+ | `waiting` - Waiting on you | `status == "awaiting_input"`, or a `pr.url`, or phase >= 4 | `resume #N` - the work landed, it needs your answer |
46
+ | `stopped` - Stopped mid-development | anything else past phase 0 | `resume #N` or `kill #N` |
47
+ | `question` - Left at a question | phase 0 | `garbage-collect --abandoned` - nothing was built |
48
+ | `unknown` - Status not recorded | no `status` field | say so; offer nothing |
37
49
 
38
- A run with no `status` is **not** placed in any group. Unknown is not a
39
- finding, and calling it dead is the same false claim in the other direction.
50
+ A run with no `status` is **not** placed in an actionable group. Unknown is
51
+ not a finding, and calling it dead is the same false claim in the other
52
+ direction.
40
53
 
41
- 4. **Render as a table**, grouped per 3b, with the group as a section heading:
54
+ 4. **Render as a table**, grouped per step 3, with the group as a section heading:
42
55
  ```
43
56
  🤖 Multi-Agent Tasks
44
57
 
45
58
  | ID | Jira/Task | Branch | Phase | Status | Duration |
46
59
  |----|-----------|--------|-------|--------|----------|
47
- | #1 | {JIRA-KEY}-12345 | feature/{JIRA-KEY}-12345-... | 7/7 DONE | ✅ Complete | 12m |
48
- | #3 | {JIRA-KEY}-12345 | feature/{JIRA-KEY}-12345-... | 7/7 DONE | ✅ Complete | 8m |
60
+ | #1 | {JIRA-KEY}-12345 | feature/{JIRA-KEY}-12345-... | 5/5 DONE | ✅ Complete | 12m |
61
+ | #3 | {JIRA-KEY}-12345 | feature/{JIRA-KEY}-12345-... | 5/5 DONE | ✅ Complete | 8m |
49
62
 
50
63
  💡 log #1 | resume #N | kill #N
51
64
  ```
@@ -59,6 +72,24 @@ Show every active and completed task as a table.
59
72
 
60
73
  Report `N lesson(s) minable from transcripts - /multi-agent:refactor to review` and `N open pipeline observation(s)` when either count is above zero, and print nothing when both are zero. Neither runs a model and neither writes anything: the miner is dry-run by default. Zero candidates alongside a non-zero `toolResultsExamined` means there is nothing to find; zero of both means the read is broken, and that is worth saying rather than reporting a clean queue.
61
74
 
75
+ 7. **What the spend is doing** (one line, and only when there is something to
76
+ say). `cost-budget-check.mjs` watches ONE run against ONE ceiling, which is
77
+ blind to the two ways a budget actually empties: a drift no single run trips,
78
+ and one pathological session that burns a week in an hour while every run
79
+ stays under its cap.
80
+
81
+ ```bash
82
+ node "$HOME/.claude/scripts/cost-analyze.mjs" burn --json 2>/dev/null
83
+ node "$HOME/.claude/scripts/cost-analyze.mjs" anomaly --days 30 --json 2>/dev/null
84
+ ```
85
+
86
+ Report a line only when either exits 10 - an accelerating day, or a day out
87
+ of family - and say nothing otherwise. The figures are estimates priced from
88
+ `cost-table.json` at LIST price, so on a subscription they are the right
89
+ number for comparing days to each other and the wrong number to call a bill;
90
+ say which when quoting one. `UNMEASURED` means the transcripts could not be
91
+ read, and it is reported as that rather than as zero.
92
+
62
93
  5. **Quick command hints** - based on state:
63
94
  - Paused task → suggest `resume #N`
64
95
  - Done task → suggest `log #N`
@@ -41,7 +41,7 @@ is being replaced.
41
41
  | `paused` / `failed` | Say the task is not running, and that `/multi-agent:resume #N` will re-enter with the instruction applied at that phase's entry. Queue it. |
42
42
  | `complete` | Refuse. Nothing will read it. Point at `/multi-agent` for a follow-up run. |
43
43
 
44
- `currentPhase` is 7 and status is `in_progress` → warn that Phase 7 is the
44
+ `currentPhase` is 7 and status is `in_progress` → warn that Phase 5 is the
45
45
  last one, so an instruction queued now may never be consumed.
46
46
 
47
47
  3. **Read the instruction** - from the argument, or ask for it when the
@@ -52,7 +52,7 @@ is being replaced.
52
52
  4. **Show what will be queued, and ask**:
53
53
 
54
54
  ```
55
- Steer #3 ({JIRA-KEY}-12345, Phase 3 Dev, in_progress)
55
+ Steer #3 ({JIRA-KEY}-12345, Phase 2 Dev, in_progress)
56
56
 
57
57
  "the field is called web, not frontend"
58
58
 
@@ -65,8 +65,8 @@ Run every step automatically:
65
65
  ```
66
66
  Step 0: DOCTOR doctor.mjs - exit 2 or 4 stops the sync
67
67
  Step 1.5: DETECT Compare timestamps, find stale targets
68
- Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 56 sub-command skills)
69
- Step 2b: CODEX Claude Code -> Codex CLI (1 router skill + 56 specs as refs + 8 agent TOML)
68
+ Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 60 sub-command skills)
69
+ Step 2b: CODEX Claude Code -> Codex CLI (1 router skill + 60 specs as refs + 8 agent TOML)
70
70
  Step 3: REPO Claude Code -> pipeline repo (genericized, personal data scrub, bash -n on all sh)
71
71
  Step 3c: PLUGINS pipeline shared/external -> multi-agent-plugins marketplace (rebuild knowledge/,
72
72
  bump changed plugins' patch version, commit + push the plugins repo)
@@ -494,19 +494,18 @@ same 56 specs as reference files rather than as peer skills, via Step 2b - see
494
494
  |-------------|-------------|
495
495
  | `~/.claude/commands/multi-agent/{cmd}/SKILL.md` | `~/.copilot/skills/multi-agent-{cmd}/SKILL.md` |
496
496
 
497
- **56 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
497
+ **60 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
498
498
 
499
499
  ```
500
- analysis, analysis-jira, analysis-resolve, autopilot, autopilot-off,
501
- autopilot-on, autopilot-status, build-optimize, channels, complaint-analysis,
502
- create-jira, design-check, diff-explain, doctor, feedback, forget,
503
- garbage-collect, graph, help, ios-coding-standard, issue, jira, kill,
504
- language, local, local-autopilot, log, manual-test, prune-logs,
505
- prune-prompts, purge, refactor, resume, resume-local, review,
506
- review-analysis, review-issue, review-jira, routines, save, scan, search,
507
- setup, stack, status, steer, store-ready, sync, test, test-accessibility,
508
- test-dark-mode, test-dynamic-type, test-screenshots, testflight-validation,
509
- uninstall, update
500
+ analysis, analysis-jira, analysis-resolve, autopilot, autopilot-off, autopilot-on,
501
+ autopilot-status, build-optimize, channels, complaint-analysis, create-jira,
502
+ design-check, diff-explain, doctor, feedback, forget, garbage-collect, graph, help,
503
+ ios-coding-standard, issue, jira, kill, language, local, local-autopilot, log,
504
+ manual-test, model, prune-logs, prune-prompts, purge, refactor, resume, resume-local,
505
+ review, review-analysis, review-issue, review-jira, route-off, route-on, route-status,
506
+ routines, save, scan, search, setup, stack, status, steer, store-ready, sync, test,
507
+ test-accessibility, test-dark-mode, test-dynamic-type, test-screenshots,
508
+ testflight-validation, uninstall, update
510
509
  ```
511
510
 
512
511
  **NOT synced**: `$HOME/.claude/multi-agent-refs/*` - lazy-load references, Claude Code specific
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: "UI Bug Hunter - iOS Simulator (simctl) + Android Emulator (adb). Auto-detects platform. Screenshot + tap + analyze on the booted device. The Phase 5 Manual Test flow lives at /multi-agent:manual-test. Use when a running app should be driven on a simulator or emulator to hunt UI bugs."
3
- description-tr: "UI Bug Hunter - iOS Simulator (simctl) + Android Emulator (adb). Platformu otomatik algılar. Açık cihazda screenshot + tap + analiz. Faz 5 Manuel Test akışı /multi-agent:manual-test'te."
3
+ description-tr: "UI Bug Hunter - iOS Simulator (simctl) + Android Emulator (adb). Platformu otomatik algılar. Açık cihazda screenshot + tap + analiz. Faz 3 Manuel Test akışı /multi-agent:manual-test'te."
4
4
  argument-hint: '[scenario] - e.g. "dark mode" | "accessibility" | "dynamic type" | "screenshot tr" | "store-ready" | (empty = full sweep)'
5
5
  ---
6
6
 
@@ -40,6 +40,14 @@ JIRA_AUTH_PREFS="${JIRA_AUTH_PREFS:-$HOME/.claude/multi-agent-preferences.json}"
40
40
 
41
41
  _jira_auth_pref() { # _jira_auth_pref <jq path> -> value or empty
42
42
  [ -f "$JIRA_AUTH_PREFS" ] || { printf ''; return 0; }
43
+ # Without jq this printed empty and returned 0, so "no jq" and "key not set"
44
+ # were the same answer and the caller went on to authenticate with nothing -
45
+ # surfacing much later as a 401 that blames the credential.
46
+ if ! command -v jq >/dev/null 2>&1; then
47
+ echo "jq not found - cannot read $JIRA_AUTH_PREFS (install: brew install jq)" >&2
48
+ printf ''
49
+ return 3
50
+ fi
43
51
  jq -r "$1 // empty" "$JIRA_AUTH_PREFS" 2>/dev/null || printf ''
44
52
  }
45
53
 
@@ -125,6 +125,30 @@ fi
125
125
  # back in CREATED_KEY. Returning the key on stdout too meant a caller using
126
126
  # command substitution swallowed the report - the first dry run printed a header
127
127
  # and nothing else, and the tree looked empty.
128
+ # Same gate, same five candidate paths, same refusal as jira-publish.sh and
129
+ # post-pr-review.sh. This file is the only ISSUE-CREATION path in the tree, and
130
+ # a summary plus a description is outbound text like any other - it was the one
131
+ # writer the gate did not cover.
132
+ ma_outbound_gate_text() {
133
+ local text="$1" og="" tmp rc
134
+ for c in "$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/outbound-gate.mjs" \
135
+ "$HOME/.claude/lib/outbound-gate.mjs" \
136
+ "$HOME/.copilot/lib/outbound-gate.mjs" \
137
+ "$HOME/.codex/lib/outbound-gate.mjs"; do
138
+ [ -f "$c" ] && { og="$c"; break; }
139
+ done
140
+ if [ -z "$og" ]; then
141
+ echo "outbound-gate.mjs not found - refusing to create unchecked issues." >&2
142
+ return 7
143
+ fi
144
+ tmp="$(mktemp)"
145
+ printf '%s' "$text" > "$tmp"
146
+ node "$og" --file "$tmp"
147
+ rc=$?
148
+ rm -f "$tmp"
149
+ return $rc
150
+ }
151
+
128
152
  CREATED_KEY=""
129
153
  create_issue() { # create_issue <label> <summary> <issuetype> <parentKey|""> <description>
130
154
  local label="$1" summary="$2" itype="$3" parent="$4" desc="$5" body key existing
@@ -146,6 +170,14 @@ create_issue() { # create_issue <label> <summary> <issuetype> <parentKey|""> <d
146
170
  echo " create $itype $summary [$label]"
147
171
  return 0
148
172
  fi
173
+ # After the dry-run branch, because a dry run publishes nothing, and before
174
+ # the ledger line, because an intent recorded for a POST that never happens
175
+ # is a false entry in the only record of what was attempted.
176
+ if ! ma_outbound_gate_text "$summary
177
+ $desc"; then
178
+ echo "ERR: outbound gate refused '$summary'; nothing was created" >&2
179
+ return 1
180
+ fi
149
181
  ledger intent "$label"
150
182
  local resp
151
183
  resp="$(printf '%s' "$body" | jira_api POST "/rest/api/2/issue" --data @- || echo "")"
@@ -14,6 +14,9 @@
14
14
  #
15
15
  # Non-interactive / autopilot / CI:
16
16
  # - ASK_CHOICE_DEFAULT=<label-or-1based-index> picks without prompting.
17
+ # - MULTI_AGENT_UNATTENDED=1 means nobody is watching even if a terminal is
18
+ # attached (screen, tmux, a login shell on a server). Same resolution as
19
+ # the no-TTY case.
17
20
  # - If stdin is not a TTY and no default is set, the FIRST option is chosen
18
21
  # and a notice is written to stderr (never blocks an automated run).
19
22
  #
@@ -64,8 +67,16 @@ if [ -n "${ASK_CHOICE_DEFAULT:-}" ]; then
64
67
  fi
65
68
 
66
69
  # Non-interactive with no usable default: pick the first option, don't block.
67
- if [ ! -t 0 ]; then
68
- echo "ask-choice: no TTY and no ASK_CHOICE_DEFAULT - selecting first option '${OPTIONS[0]}'" >&2
70
+ #
71
+ # "No TTY" is the usual shape of that, but it is not the only one. A server run
72
+ # under screen, tmux or a login shell HAS a terminal and still has nobody in
73
+ # front of it, and there the TTY test says "ask" and the process waits forever.
74
+ # MULTI_AGENT_UNATTENDED=1 is the operator saying so out loud; see
75
+ # refs/unattended-contract.md. Unset, nothing below changes.
76
+ if [ ! -t 0 ] || [ "${MULTI_AGENT_UNATTENDED:-}" = "1" ]; then
77
+ why="no TTY"
78
+ [ "${MULTI_AGENT_UNATTENDED:-}" = "1" ] && why="MULTI_AGENT_UNATTENDED=1"
79
+ echo "ask-choice: $why and no ASK_CHOICE_DEFAULT - selecting first option '${OPTIONS[0]}'" >&2
69
80
  printf '%s\n' "${OPTIONS[0]}"
70
81
  exit 0
71
82
  fi
@@ -133,6 +133,14 @@ ma_ap_read() { # $1 = filename; empty and exit 1 when absent
133
133
  # jq with a default, so a caller never has to distinguish "key absent" from
134
134
  # "file absent" from "file unparseable" - all three mean "use the default".
135
135
  ma_ap_cfg() { # $1 = jq path, $2 = default
136
+ # An unreadable queue must not read as an EMPTY queue. Without this, a
137
+ # machine with no jq made the runner conclude there was no work and go
138
+ # quiet - the worst failure this mode can have, because it looks like
139
+ # success.
140
+ if ! command -v jq >/dev/null 2>&1; then
141
+ echo "jq not found - cannot read the autopilot config (install: brew install jq)" >&2
142
+ return 3
143
+ fi
136
144
  local v
137
145
  v=$(ma_ap_read config.json 2>/dev/null | jq -r "$1 // empty" 2>/dev/null)
138
146
  [ -n "$v" ] && printf '%s\n' "$v" || printf '%s\n' "$2"
@@ -345,7 +345,7 @@ capability_of() {
345
345
  esac
346
346
  fi
347
347
  case "$1" in
348
- jira) echo "read the ticket, its comments and its linked issues; post the Phase 7 comment" ;;
348
+ jira) echo "read the ticket, its comments and its linked issues; post the Phase 5 comment" ;;
349
349
  bitbucket_token) echo "read the repo, open and update pull requests" ;;
350
350
  bitbucket_user) echo "identify the PR author (paired with bitbucket_token)" ;;
351
351
  github) echo "read issues, open pull requests, read Actions runs" ;;