@mmerterden/multi-agent-pipeline 20.12.0 → 20.15.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 (183) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +8 -6
  3. package/README.tr.md +8 -6
  4. package/docs/architecture.md +3 -3
  5. package/docs/ecosystem.md +5 -5
  6. package/docs/facts.json +4 -4
  7. package/install/_common.mjs +1 -1
  8. package/install/_plugin-skills.mjs +13 -9
  9. package/install/catalog-history.json +1 -1
  10. package/install/codex.mjs +12 -12
  11. package/manifest.json +186 -120
  12. package/package.json +1 -1
  13. package/pipeline/commands/multi-agent/SKILL.md +1 -0
  14. package/pipeline/commands/multi-agent/analysis/SKILL.md +17 -82
  15. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +57 -7
  16. package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +2 -2
  17. package/pipeline/commands/multi-agent/autopilot/SKILL.md +8 -23
  18. package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +25 -45
  19. package/pipeline/commands/multi-agent/channels/SKILL.md +11 -63
  20. package/pipeline/commands/multi-agent/design-check/SKILL.md +43 -178
  21. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +2 -0
  22. package/pipeline/commands/multi-agent/doctor/SKILL.md +6 -0
  23. package/pipeline/commands/multi-agent/estimate/SKILL.md +65 -0
  24. package/pipeline/commands/multi-agent/feedback/SKILL.md +2 -2
  25. package/pipeline/commands/multi-agent/forget/SKILL.md +1 -0
  26. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -0
  27. package/pipeline/commands/multi-agent/help/SKILL.md +5 -546
  28. package/pipeline/commands/multi-agent/kill/SKILL.md +14 -18
  29. package/pipeline/commands/multi-agent/prune-logs/SKILL.md +1 -0
  30. package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +1 -0
  31. package/pipeline/commands/multi-agent/refactor/SKILL.md +7 -76
  32. package/pipeline/commands/multi-agent/review/SKILL.md +5 -0
  33. package/pipeline/commands/multi-agent/review-analysis/SKILL.md +8 -3
  34. package/pipeline/commands/multi-agent/scenario-audit/SKILL.md +79 -0
  35. package/pipeline/commands/multi-agent/serve/SKILL.md +6 -3
  36. package/pipeline/commands/multi-agent/setup/SKILL.md +12 -365
  37. package/pipeline/commands/multi-agent/status/SKILL.md +2 -0
  38. package/pipeline/commands/multi-agent/store-ready/SKILL.md +56 -184
  39. package/pipeline/commands/multi-agent/sync/SKILL.md +14 -267
  40. package/pipeline/contract/CHANGELOG.md +52 -0
  41. package/pipeline/contract/README.md +41 -1
  42. package/pipeline/contract/build.mjs +49 -7
  43. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  44. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  45. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  46. package/pipeline/contract/fixtures/launch-plan.json +1 -2
  47. package/pipeline/contract/fixtures/runs-awaiting-question.json +10 -3
  48. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  49. package/pipeline/contract/fixtures/runs-failed.json +19 -6
  50. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +25 -8
  51. package/pipeline/contract/fixtures/runs-pr-opened.json +25 -8
  52. package/pipeline/contract/fixtures/runs-running.json +31 -4
  53. package/pipeline/contract/frozen/toolbox.json +13 -0
  54. package/pipeline/contract/manifest.json +112 -10
  55. package/pipeline/contract/types/index.d.ts +186 -17
  56. package/pipeline/lib/analysis-jira-write.sh +81 -27
  57. package/pipeline/lib/analysis-quality.mjs +261 -0
  58. package/pipeline/lib/analysis-sections.mjs +105 -0
  59. package/pipeline/lib/claude-sessions.mjs +93 -0
  60. package/pipeline/lib/credential-resolve.mjs +39 -0
  61. package/pipeline/lib/gc-report.sh +64 -0
  62. package/pipeline/lib/jira-epic-link.sh +54 -0
  63. package/pipeline/lib/unattended-settings-location.mjs +4 -0
  64. package/pipeline/lib/workspace-trust.mjs +73 -0
  65. package/pipeline/multi-agent-refs/analysis/intake.md +5 -3
  66. package/pipeline/multi-agent-refs/analysis/locked.md +12 -11
  67. package/pipeline/multi-agent-refs/analysis/redesign.md +3 -1
  68. package/pipeline/multi-agent-refs/analysis/render.md +24 -24
  69. package/pipeline/multi-agent-refs/analysis/resolve.md +1 -1
  70. package/pipeline/multi-agent-refs/analysis/resume.md +37 -0
  71. package/pipeline/multi-agent-refs/analysis/reusable-refs.md +25 -0
  72. package/pipeline/multi-agent-refs/analysis/review.md +16 -3
  73. package/pipeline/multi-agent-refs/analysis/synthesis.md +10 -2
  74. package/pipeline/multi-agent-refs/analysis-template-corporate.md +44 -9
  75. package/pipeline/multi-agent-refs/analysis-template.md +21 -14
  76. package/pipeline/multi-agent-refs/channels/board.md +17 -0
  77. package/pipeline/multi-agent-refs/channels/multi-repo.md +15 -0
  78. package/pipeline/multi-agent-refs/cross-cli-contract.md +8 -4
  79. package/pipeline/multi-agent-refs/design-check/build-launch.md +14 -0
  80. package/pipeline/multi-agent-refs/design-check/compare.md +44 -0
  81. package/pipeline/multi-agent-refs/design-check/drive-capture.md +35 -0
  82. package/pipeline/multi-agent-refs/design-check/export.md +37 -0
  83. package/pipeline/multi-agent-refs/design-check/figma-mapping.md +11 -0
  84. package/pipeline/multi-agent-refs/design-check/init-inventory.md +56 -0
  85. package/pipeline/multi-agent-refs/design-check/mcp-currency-gate.md +41 -0
  86. package/pipeline/multi-agent-refs/features/analysis-jira.md +69 -19
  87. package/pipeline/multi-agent-refs/features/analysis-outline.md +55 -0
  88. package/pipeline/multi-agent-refs/features/analysis-sources.md +60 -0
  89. package/pipeline/multi-agent-refs/help/en.md +273 -0
  90. package/pipeline/multi-agent-refs/help/tr.md +271 -0
  91. package/pipeline/multi-agent-refs/orchestrator/operations.md +99 -0
  92. package/pipeline/multi-agent-refs/orchestrator/phase-0-projects.md +72 -0
  93. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +40 -0
  94. package/pipeline/multi-agent-refs/orchestrator/phase-4-5-projects.md +68 -0
  95. package/pipeline/multi-agent-refs/orchestrator/skill-loading.md +99 -0
  96. package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -2
  97. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +1 -1
  98. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
  99. package/pipeline/multi-agent-refs/picker-contract.md +29 -0
  100. package/pipeline/multi-agent-refs/refactor/drift.md +49 -0
  101. package/pipeline/multi-agent-refs/refactor/run-errors.md +46 -0
  102. package/pipeline/multi-agent-refs/setup/discovery.md +84 -0
  103. package/pipeline/multi-agent-refs/setup/figma.md +27 -0
  104. package/pipeline/multi-agent-refs/setup/identity-routing.md +60 -0
  105. package/pipeline/multi-agent-refs/setup/token-save-flow.md +201 -0
  106. package/pipeline/multi-agent-refs/store-ready/build.md +49 -0
  107. package/pipeline/multi-agent-refs/store-ready/gate-1-static.md +37 -0
  108. package/pipeline/multi-agent-refs/store-ready/gate-3-policy.md +31 -0
  109. package/pipeline/multi-agent-refs/store-ready/preflight.md +50 -0
  110. package/pipeline/multi-agent-refs/store-ready/report.md +40 -0
  111. package/pipeline/multi-agent-refs/sync/codex.md +43 -0
  112. package/pipeline/multi-agent-refs/sync/dev-toolkit.md +174 -0
  113. package/pipeline/multi-agent-refs/sync/stack-plugins.md +51 -0
  114. package/pipeline/multi-agent-refs/tracker-contract.md +29 -4
  115. package/pipeline/schemas/agent-state.schema.json +13 -4
  116. package/pipeline/schemas/analysis-spec.schema.json +76 -2
  117. package/pipeline/schemas/autopilot-off-request.schema.json +20 -0
  118. package/pipeline/schemas/autopilot-off.schema.json +24 -0
  119. package/pipeline/schemas/autopilot-status.schema.json +63 -0
  120. package/pipeline/schemas/contract-error.schema.json +13 -2
  121. package/pipeline/schemas/gc-request.schema.json +31 -0
  122. package/pipeline/schemas/gc.schema.json +116 -0
  123. package/pipeline/schemas/kill-request.schema.json +22 -0
  124. package/pipeline/schemas/kill.schema.json +118 -0
  125. package/pipeline/schemas/launch-plan.schema.json +11 -2
  126. package/pipeline/schemas/launch-request.schema.json +7 -2
  127. package/pipeline/schemas/launch.json +65 -4
  128. package/pipeline/schemas/launch.schema.json +23 -8
  129. package/pipeline/schemas/prefs.schema.json +25 -4
  130. package/pipeline/schemas/repos.schema.json +39 -0
  131. package/pipeline/schemas/resume-request.schema.json +37 -0
  132. package/pipeline/schemas/run-log.schema.json +32 -0
  133. package/pipeline/schemas/run-questions.json +5 -1
  134. package/pipeline/schemas/run-questions.schema.json +1 -1
  135. package/pipeline/schemas/runs-index.schema.json +59 -3
  136. package/pipeline/scripts/_run-paths.mjs +8 -2
  137. package/pipeline/scripts/analysis-conform-coverage.mjs +96 -0
  138. package/pipeline/scripts/analysis-sources.mjs +264 -0
  139. package/pipeline/scripts/analysis-story-body.mjs +210 -0
  140. package/pipeline/scripts/analysis-story-tree.mjs +73 -12
  141. package/pipeline/scripts/analysis-tickets-writeback.mjs +101 -0
  142. package/pipeline/scripts/autopilot-control.mjs +223 -0
  143. package/pipeline/scripts/autopilot-runner.mjs +14 -39
  144. package/pipeline/scripts/build-references.mjs +19 -2
  145. package/pipeline/scripts/confluence-readback.mjs +129 -0
  146. package/pipeline/scripts/contract-server.mjs +373 -7
  147. package/pipeline/scripts/doctor.mjs +5 -2
  148. package/pipeline/scripts/estimate.mjs +223 -0
  149. package/pipeline/scripts/gate-ledger.mjs +64 -3
  150. package/pipeline/scripts/gc-plan.mjs +288 -0
  151. package/pipeline/scripts/gc-refs.sh +33 -2
  152. package/pipeline/scripts/gc-tmp.sh +33 -2
  153. package/pipeline/scripts/gc-worktrees.sh +42 -3
  154. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -24
  155. package/pipeline/scripts/jira-wiki-escape.mjs +40 -0
  156. package/pipeline/scripts/launch-request.mjs +182 -10
  157. package/pipeline/scripts/phase-tracker.sh +62 -1
  158. package/pipeline/scripts/run-kill.mjs +232 -0
  159. package/pipeline/scripts/run-log.mjs +111 -0
  160. package/pipeline/scripts/runs-index.mjs +177 -11
  161. package/pipeline/scripts/scenario-audit.mjs +245 -0
  162. package/pipeline/scripts/validate-analysis-doc.mjs +204 -76
  163. package/pipeline/skills/.skill-manifest.json +27 -19
  164. package/pipeline/skills/shared/README.md +5 -3
  165. package/pipeline/skills/shared/core/multi-agent/SKILL.md +51 -450
  166. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +13 -2
  167. package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +56 -6
  168. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +6 -0
  169. package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +26 -44
  170. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +31 -127
  171. package/pipeline/skills/shared/core/multi-agent-doctor/SKILL.md +6 -0
  172. package/pipeline/skills/shared/core/multi-agent-estimate/SKILL.md +61 -0
  173. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +14 -19
  174. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +7 -76
  175. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +6 -1
  176. package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +6 -1
  177. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
  178. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
  179. package/pipeline/skills/shared/core/multi-agent-scenario-audit/SKILL.md +77 -0
  180. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +6 -3
  181. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +206 -324
  182. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +5 -0
  183. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmerterden/multi-agent-pipeline",
3
- "version": "20.12.0",
3
+ "version": "20.15.0",
4
4
  "description": "6-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: "Task orchestrator - full pipeline via Jira ID + branch or GitHub Issue URL: analysis, plan, TDD development, parallel review + Fable triage (3 reviewers per host: Fable + Opus + Sonnet on Claude Code, GPT-5.4 + Opus + Sonnet on Copilot CLI), commit, log. Use when given a Jira ID, a GitHub issue or a free-text task and the whole pipeline should run."
3
3
  description-tr: "Görev orkestratörü - Jira ID + branch veya GitHub Issue URL ile tam pipeline: analiz, plan, TDD geliştirme, paralel review + Fable triyajı (CLI'ya göre: Claude Code'da 3, Copilot CLI'da 3 model), commit, log"
4
+ argument-hint: "[JIRA-KEY | issue URL | repo#N | \"task\"] [autopilot] [--dev] - or a sub-command: status, log #N, resume #N, kill #N"
4
5
  allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep, TaskCreate, TaskUpdate, TaskList, TaskGet, AskUserQuestion, WebFetch, WebSearch, NotebookEdit, Skill
5
6
  ---
6
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: "Standalone feature-spec analysis. Two profiles picked at intake: global (23-section development handoff, evidence-trimmed) or corporate (IG/UC/FG requirements document with traceability matrices). Platform-agnostic concept layer with repo-driven convention extraction (Phase 1c) and per-platform Pass B render; stack selection is optional. Collects Figma / Swagger / Confluence / Jira / Standards (Confluence + Wiki + local file) / Firebase / repo inputs. Stops after emit - does not chain into a dev run. Use when a feature needs a written specification before any code."
3
3
  description-tr: "Bağımsız özellik-spesifikasyonu analizi. Girişte iki profil: global (23 bölümlük geliştirme dokümanı, kanıta göre budanır) veya kurumsal (izlenebilirlik matrisleriyle IG/UC/FG gereksinim dokümanı). Repo'dan konvansiyon çıkarımıyla (Faz 1c) platform-bağımsız kavram katmanı ve platform başına Pass B render; stack seçimi opsiyonel. Figma / Swagger / Confluence / Jira / Standartlar (Confluence + Wiki + yerel dosya) / Firebase / repo girdilerini toplar. Çıktıyı üretince durur - dev koşusuna zincirlenmez."
4
- argument-hint: "[\"<analysis-name>\"] [--no-cache] [--preview-conventions]"
4
+ argument-hint: "[\"<analysis-name>\" | check <doc.md> | refresh <doc.md> | conform <doc.md>] [--no-cache] [--preview-conventions]"
5
5
  parameters: [{"name":"name","kind":"text"},{"name":"--no-cache","kind":"flag"},{"name":"--preview-conventions","kind":"flag"}]
6
6
  gui: form
7
7
  destructive: false
@@ -11,6 +11,8 @@ confirm: none
11
11
  # multi-agent analysis - Feature Spec Analysis (v3)
12
12
 
13
13
  > **Pickers follow** `$HOME/.claude/multi-agent-refs/picker-contract.md`: never a one-option call, and branch on the option selected, not on its text.
14
+ >
15
+ > **Background runs** (`MULTI_AGENT_UNATTENDED=1`, no `autopilot`): never ask or default a picker; write `agent-state.json`, park on the question, stop (`$HOME/.claude/multi-agent-refs/picker-contract.md`, Background).
14
16
 
15
17
  This command is **independent** from the orchestrator's Phase 1 analysis (which is a stack/findings detector inside `/multi-agent`). It produces a stakeholder-ready, platform-agnostic feature-spec document - up to 23 sections, trimmed to whatever the evidence supports - before any implementation starts. Each per-platform file is rendered by projecting concept-layer content onto repo-extracted conventions (Pass B).
16
18
 
@@ -20,17 +22,24 @@ This command is **independent** from the orchestrator's Phase 1 analysis (which
20
22
 
21
23
  > **Language**: Per `$HOME/.claude/multi-agent-refs/rules.md` Language Application matrix - instruction prose stays English (this file is read as a system prompt). `AskUserQuestion.question`, `.options[].label` and `.options[].description` follow `outputLanguage`; only `header` stays English (<=12-char chip). The emitted analysis document body follows `outputLanguage` (`tr` or `en`).
22
24
 
25
+ ## Gotchas
26
+
27
+ - Design is fetched only inside this command (Locked 29). A variant missing from the document is added by re-running analysis, never by a later phase.
28
+ - `status: final` fails the validator while any `AS-NN` is still open; publish drafts as `draft`.
29
+
23
30
  ## Locked decisions (do not re-ask)
24
31
 
25
32
  These decisions are settled. Do not surface them as `AskUserQuestion` items, do not re-derive them from context, do not invite the user to override mid-run. If the user explicitly wants one of them changed, treat that as a separate request and update this list.
26
33
 
27
- The full list of 35, with the category index, lives in `$HOME/.claude/multi-agent-refs/analysis/locked.md`. Read it before the run starts; it is the contract the whole flow is judged against. `/multi-agent:analysis-resolve` inherits the same list.
34
+ The full list of 37, with the category index, lives in `$HOME/.claude/multi-agent-refs/analysis/locked.md`. Read it before the run starts; it is the contract the whole flow is judged against. `/multi-agent:analysis-resolve` inherits the same list.
28
35
 
29
36
  Cite a decision as `Locked <n> (<short label>)` so the category is inferable.
30
37
 
31
38
  ## Input
32
39
 
33
40
  - `$ARGUMENTS` - optional analysis name (e.g. `"UserProfile"`). If empty, asked at Phase 0 Step 1. Stored internally as `state.analysisSpec.featureName` for backward compatibility.
41
+ - `check <doc.md>` / `refresh <doc.md>` - not a name: compare the document with its sources, or redraft from the stale ones. Read `$HOME/.claude/multi-agent-refs/features/analysis-sources.md` and follow it instead of the steps below.
42
+ - `conform <doc.md>` - not a name: map an existing document onto a template without changing what it says. Follow `$HOME/.claude/multi-agent-refs/features/analysis-outline.md` instead of the steps below.
34
43
 
35
44
  ## Profile
36
45
 
@@ -47,7 +56,7 @@ One run emits one profile. A missing input never blocks either profile: the gap
47
56
 
48
57
  ## Template
49
58
 
50
- v3 template at `$HOME/.claude/multi-agent-refs/analysis-template.md`. The document renders up to 23 main sections + footer, minus any dropped by the omission table. The analysis doc is a development handoff, so low-signal sections are default-drop: **19 Alternatives** (render only for a real 2+-option architectural decision), **22 Glossary** (render only on request or >5 unfamiliar domain terms), and **18 Rollout** (compact checklist only, dropped when the pipeline's own commit/PR/rollout phase covers it). Sections are chosen from evidence; there is no second mode (ADR-0015, `docs/adr/0015-one-pipeline-no-depth-answer.md` in the pipeline repo). Section omission rule (Locked 2): zero-evidence and default-drop sections omit entirely; numbering re-flows to stay sequential `1..N` over the rendered set.
59
+ v3 template at `$HOME/.claude/multi-agent-refs/analysis-template.md`. The document renders up to 23 main sections + footer, minus any dropped by the omission table. The analysis doc is a development handoff, so low-signal sections are default-drop: **19 Alternatives** (render only for a real 2+-option architectural decision), **22 Glossary** (render only on request or >5 unfamiliar domain terms), and **18 Rollout** (compact checklist only, dropped when the pipeline's own commit/PR/rollout phase covers it). Sections are chosen from evidence; there is no second mode (ADR-0015, `docs/adr/0015-one-pipeline-no-depth-answer.md` in the pipeline repo). Section omission rule (Locked 2): zero-evidence and default-drop sections omit entirely; a rendered section keeps its canonical template number, so the rendered set has gaps.
51
60
 
52
61
  Numbering is plain Arabic numerals: `## 1. Geliştirme Özeti` / `## 1. Summary`, `## 2. Hedefler ve Karşı Hedefler` / `## 2. Goals and Non-Goals`. No special section characters; the section sign codepoint (U+00A7) is banned by `feedback_no-section-sign`.
53
62
 
@@ -73,67 +82,14 @@ Full contract: `$HOME/.claude/multi-agent-refs/analysis/render.md`. Renders one
73
82
 
74
83
  ### Resume contract
75
84
 
76
- `state.analysisSpec.phase` enumeration:
77
-
78
- - `intake` (Phase 0 in progress)
79
- - `fetching` (Phase 1 in progress)
80
- - `collecting_repo_evidence` (Phase 1b)
81
- - `extracting_conventions` (Phase 1c)
82
- - `synthesizing_pass_a` (Phase 2 Pass A)
83
- - `awaiting_pass_b_approval` (Phase 2a - preview not yet answered)
84
- - `rendering_pass_b` (Phase 2b)
85
- - `drafting` (Phase 3)
86
- - `awaiting_output_decision` (Phase 3.5 - drafts written, picker not yet answered)
87
- - `dispatching` (Phase 4)
88
- - `reporting` (Phase 5)
89
- - `done`
90
- - `cancelled_at_pass_b_preview` (user cancelled at Phase 2a)
91
-
92
- When `/multi-agent:resume` is invoked and `phase == "awaiting_output_decision"`:
93
-
94
- 1. Check `state.analysisSpec.outputs.draftDir` exists on disk and contains the expected per-platform `.md` files.
95
- 2. If present, jump directly to Phase 3.5 (re-prompt the output picker; do not re-fetch evidence, do not re-synthesize).
96
- 3. If missing, print `WARN: scratch drafts at <draftDir> are gone; re-running Phase 2 synthesis from fetched evidence.` and restart from Phase 2 (cheap: evidence is still in state).
97
-
98
- When `phase == "awaiting_pass_b_approval"`:
99
-
100
- 1. Re-present the convention preview table (Phase 2a) with the same options.
101
- 2. Pass A synthesis results are kept in state; Phase 1b / 1c results are kept too.
102
- 3. Approval continues to Phase 2b without re-running anything.
103
-
104
- When `phase == "cancelled_at_pass_b_preview"`:
105
-
106
- 1. Print `state.analysisSpec.outputs.draftDir` (likely empty unless prior drafts exist from a previous run).
107
- 2. Show the convention preview that was rejected (for context).
108
- 3. Ask whether to restart from Phase 0, retry Phase 1c with fresh evidence, or abort.
85
+ Full procedure: `$HOME/.claude/multi-agent-refs/analysis/resume.md`. Read it when `/multi-agent:resume` is invoked on an analysis run (`state.analysisSpec.phase` enumeration and the re-entry rule per paused phase; evidence and synthesis already in state are never re-fetched).
109
86
 
110
87
  ## Reusable refs
111
88
 
112
- | Path | Reason |
113
- |------|--------|
114
- | `~/.claude/lib/submodule-detector.sh` | Phase 0 Step 4 repo discovery |
115
- | `~/.claude/lib/context-link-extractor.sh` | Phase 0 Step 5 source classifier for every question's Other input (handles `local-file`, `document`, `wiki`, `standards-confluence`, `generic-doc`, `firebase-events:names`, `firebase-events:schema`, `firebase-events:console` types) |
116
- | `~/.claude/lib/fetch-swagger.sh`, `fetch-confluence.sh` | Phase 1 fetchers |
117
- | Phase 1 wiki fetch chain (inline, no standalone script) | `git clone --depth 1 <repo>.wiki.git` first, `gh api repos/.../contents/<file>.md` second, WebFetch third - see the Phase 1 type table `wiki` row |
118
- | `~/.claude/lib/extract-conventions.sh` | Phase 1c convention extractor (7 pattern groups, JSON output, confidence levels) |
119
- | `~/.claude/lib/figma-screenshot.sh` | Phase 2b Tier 2 Figma image downloader (REST API, section drill, 2x scale PNG, manifest.json) |
120
- | `~/.claude/lib/md2confluence-v3.py` | Phase 4 Confluence dispatch (multipart attachments, `<ac:image>` injection, mermaid macro + fallback, tooltip footnote macro, punctuation gate) |
121
- | `ai-common-toolkit:humanizer` | Phase 3 tone pass |
122
- | 8-locale set (ar, de, en, es, fr, it, ru, tr) + localization-key naming (inline) | Section 10 localization generation |
123
- | `$HOME/.claude/multi-agent-refs/channels/confluence.md` | Phase 4 Confluence dispatch |
124
- | `$HOME/.claude/multi-agent-refs/channels/jira.md` | Phase 4 Jira dispatch |
125
- | `$HOME/.claude/rules/tdd.md` | Section 15 test naming |
126
- | `$HOME/.claude/multi-agent-refs/analysis-template.md` | Template master copy + language matrix (v3 - 23 sections) |
127
- | `$HOME/.claude/multi-agent-refs/conventions-defaults.md` | Pass B fallback defaults (4 platforms x 7 pattern groups) - applied when convention confidence is none AND standards binding is silent |
128
- | `$HOME/.claude/lib/jira-publish.sh` | Phase 4 Jira write: comment by default, description only on explicit choice - reads the current description first, backs it up, appends below a rule, refuses a non-empty replace without `--confirm-overwrite` |
129
- | `$HOME/.claude/scripts/validate-analysis-doc.mjs` | Phase 4 pre-dispatch gate: deterministic check of the emitted per-platform doc (front-matter, never-omitted sections, humanizer punctuation, BR traceability) |
130
- | a project-supplied Confluence-embedded API-table parser (optional) | Parse endpoints from a Confluence page's Request Path / Service Name / Response Body table columns |
131
- | `~/<project>-Standards.md` | Canonical home-dir standards reference (auto-detected by the Standards question's option 2; exact filename from `prefs.projects[<project>].standardsFile`) |
132
- | `~/.claude/rules/*.md` | Fallback rules when `evidence.standards[]` is empty |
89
+ Full table: `$HOME/.claude/multi-agent-refs/analysis/reusable-refs.md`. Read it when a phase needs a fetcher, extractor, dispatcher, validator or fallback ref and the phase ref does not name its path.
133
90
 
134
91
  ## Notes
135
92
 
136
- - Default `prefs.global.outputLanguage` is `tr` for this user.
137
93
  - The minimum possible output (per per-platform file) is `1. Scope` + `7. Development Plan` (both always-present).
138
94
  - If Confluence or Jira POST returns 401 / 403 during Phase 4, surface the error and offer Local fallback (the local drafts in `/tmp/` are still on disk; copying them into the repo working tree is always available).
139
95
  - The `analysis/` directory is not in `.gitignore`; the user can `git add analysis/` manually. No auto-commit.
@@ -173,34 +129,13 @@ bash $HOME/.claude/scripts/phase-tracker.sh tokens <N> <in> <out> [cached]
173
129
 
174
130
  ### Visual channel - Claude Code (native TaskList widget, required)
175
131
 
176
- In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Skipping these calls is the #1 source of "I don't see any phases" complaints.
177
-
178
- **TaskCreate ordering (strict)**: All TaskCreate calls in a registration batch fire in strict phase-number order BEFORE any TaskUpdate in that batch, and a later batch only ever appends phases numbered above everything already registered. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
179
-
180
- ```text
181
- # Register one tile per phase, capture the taskId, persist it:
182
- for each phase in 0:Init, 1:Plan, 3:Review, 4:Commit, 5:Report:
183
- TaskCreate({ subject: "Phase <N>: <Name>", activeForm: "<doing-form>" })
184
- -> returns taskId
185
- bash $HOME/.claude/scripts/phase-tracker.sh meta <N> tasklist_id "<taskId>"
186
-
187
- # Phase entry - flip the tile to in_progress alongside the state update:
188
- TaskUpdate({ taskId: <saved>, status: "in_progress" })
189
- bash $HOME/.claude/scripts/phase-tracker.sh update <N> in_progress
190
-
191
- # Active sub-step inside a phase - update activeForm so the spinner header reflects what's happening now:
192
- TaskUpdate({ taskId: <saved>, activeForm: "Editing TopBarView.swift" })
193
-
194
- # Phase exit - flip to completed/failed/skipped on both channels:
195
- TaskUpdate({ taskId: <saved>, status: "completed" })
196
- bash $HOME/.claude/scripts/phase-tracker.sh update <N> completed
197
- ```
132
+ In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Register one tile per phase of the active set (`0:Init 1:Plan 3:Review 4:Commit 5:Report`) with `TaskCreate`, persist each `taskId` via `phase-tracker.sh meta <N> tasklist_id "<taskId>"`, and at every phase entry, sub-step and exit pair a `TaskUpdate` (status or `activeForm`) with the matching `phase-tracker.sh update`. Call pattern: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "Call pattern". Mirror each with `phase-tracker.sh task` ("Mirroring the host's task list").
198
133
 
199
- `analysis` mode does NOT TaskCreate phases 2 - those are not part of the `analysis` phase set (`0:Init 1:Plan 3:Review 4:Commit 5:Report`). Only register tiles for the active set.
134
+ `analysis` mode does NOT TaskCreate phase 2: register tiles for the active set only.
200
135
 
201
136
  #### TaskCreate ordering (strict)
202
137
 
203
- **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied.** For `analysis` that means: Phase 0 → Phase 1 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
138
+ **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied**, and a later batch only ever appends phases numbered above everything already registered. For `analysis` that means: Phase 0 → Phase 1 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
204
139
 
205
140
  ### Visual channel - Copilot CLI / plain shell
206
141
 
@@ -2,8 +2,8 @@
2
2
  description: "Turn a rendered analysis document into a Jira story tree: derive stories from the document's own rule ids, check coverage both ways, preview every byte, then create only what does not already exist. Use when an analysis is final and the work needs tickets."
3
3
  description-tr: "Yazılmış bir analiz dokümanını Jira story ağacına çevirir: story'leri dokümanın kendi kural kimliklerinden türetir, kapsamı iki yönlü kontrol eder, yazılacak her baytı önizler, sonra yalnız var olmayanı açar."
4
4
  allowed-tools: Bash, Read, AskUserQuestion
5
- argument-hint: "[analysis.md] [--project KEY] - optional; with no argument, pick from the documents this run emitted"
6
- parameters: [{"name":"document","kind":"path"},{"name":"--project","kind":"text"}]
5
+ argument-hint: "[analysis.md] [--project KEY] [--epic KEY] - optional; with no argument, pick from the documents this run emitted"
6
+ parameters: [{"name":"document","kind":"path"},{"name":"--project","kind":"text"},{"name":"--epic","kind":"text"}]
7
7
  gui: form
8
8
  destructive: false
9
9
  confirm: none
@@ -22,13 +22,26 @@ invents a story: every node comes from an id the document defines.
22
22
  Contract, severities and reasoning:
23
23
  `$HOME/.claude/multi-agent-refs/features/analysis-jira.md`.
24
24
 
25
+ ## Gotchas
26
+
27
+ - An issue whose label already exists is skipped, never updated. Editing the document and re-running creates only what is missing; existing tickets keep their old text.
28
+ - A document with no `BR-`/`FG-` ids still plans, from its `4.N` sub-sections, but its coverage verdict is `unverifiable`: there is nothing to check the tree against.
29
+ - An open `EKLENECEK`/`TBD` marker or an open Section 20 row stops planning with exit 4. Resolve them with `/multi-agent:analysis-resolve` first.
30
+ - The epic must already exist: stories are linked to it, never an epic created. On Server/Data Center the Epic Link field is discovered from the site; when none is found the stories are created unlinked and the writer says so.
31
+ - Channel clones (`issueTree.cloneByChannel`) carry their own labels and are searched like stories, so a re-run never doubles them or their links.
32
+ - Story bodies hold only document text. A body warning (no user story, fewer than 2 criteria, no negative criterion) is a gap in the document; fix the document, not the ticket.
33
+
25
34
  ## Phase 1 - Plan, offline
26
35
 
27
36
  ```bash
28
- node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>" --json > /tmp/ma-plan.json
29
- node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>"
37
+ node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>" --json $PAGE > /tmp/ma-plan.json
38
+ node "$HOME/.claude/scripts/analysis-story-tree.mjs" "<analysis.md>" $PAGE
30
39
  ```
31
40
 
41
+ `$PAGE` is `--page-url <url>` when the document was published (the run's
42
+ `outputs.confluencePages[]`); without it the front-matter `confluence_url` is
43
+ used, and with neither the story bodies carry no analysis link.
44
+
32
45
  Exit 4 means the document still carries an open placeholder. Stop and report it:
33
46
  the step is `/multi-agent:analysis-resolve`, and a tree built from an open
34
47
  question publishes the gap as work somebody is now assigned.
@@ -52,12 +65,19 @@ what makes a preview meaningful:
52
65
  - every field beside the pref key it came from, so a wrong setting shows here
53
66
  rather than in Jira afterwards
54
67
  - the write count
68
+ - every story's full description, as it will be written, with its body
69
+ warnings; `--brief` gives the one-line-per-node view
70
+
71
+ Then ask for the epic, once. `AskUserQuestion`:
72
+
73
+ - **Link to an existing epic** - the user types its key (`--epic <KEY>`)
74
+ - **No epic** - the stories are created unlinked
55
75
 
56
76
  Then the dry run, which is what proves the writer agrees with the plan:
57
77
 
58
78
  ```bash
59
79
  bash "$HOME/.claude/lib/analysis-jira-write.sh" \
60
- --plan /tmp/ma-plan.json --project "<KEY>" --dry-run
80
+ --plan /tmp/ma-plan.json --project "<KEY>" [--epic "<EPIC>"] --dry-run
61
81
  ```
62
82
 
63
83
  ## Phase 3 - Approve
@@ -83,11 +103,14 @@ be reachable.
83
103
  invented id means the plan cites something the document does not define - treat
84
104
  that as a defect in the plan, not a warning to click past.
85
105
 
106
+ Body warnings are printed before the question too. They do not block: the
107
+ ticket says only what the document says, and the warning names the gap.
108
+
86
109
  ## Phase 4 - Write
87
110
 
88
111
  ```bash
89
112
  bash "$HOME/.claude/lib/analysis-jira-write.sh" \
90
- --plan /tmp/ma-plan.json --project "<KEY>"
113
+ --plan /tmp/ma-plan.json --project "<KEY>" [--epic "<EPIC>"]
91
114
  ```
92
115
 
93
116
  It searches by label first and skips what exists. Re-running is safe and is the
@@ -97,9 +120,36 @@ findable rather than duplicable.
97
120
  **Never pass `--force`-like flags, and never update an existing node.** Jira has
98
121
  no backup path for fields other than description.
99
122
 
123
+ ### Write the tickets back
124
+
125
+ The document lists what it produced. Local and idempotent: the table sits
126
+ between `<!-- tickets:start -->` and `<!-- tickets:end -->`, a re-run replaces
127
+ it, and only nodes with a key appear.
128
+
129
+ ```bash
130
+ LEDGER="$HOME/.claude/logs/multi-agent/_analysis-jira/$(jq -r '.document.id // "unidentified"' /tmp/ma-plan.json).jsonl"
131
+ node "$HOME/.claude/scripts/analysis-tickets-writeback.mjs" \
132
+ --doc "<analysis.md>" --ledger "$LEDGER" --plan /tmp/ma-plan.json
133
+ ```
134
+
135
+ When the document has a Confluence page, updating it is a **separate**
136
+ `AskUserQuestion`, never part of the tree approval:
137
+
138
+ - **Update the Confluence page** - publish the document with its new table
139
+ - **Keep it local** - the page stays as it is
140
+
141
+ ```bash
142
+ python3 "$HOME/.claude/lib/md2confluence-v3.py" update \
143
+ --page-id "<pageId>" --title "<page title>" \
144
+ --markdown "<analysis.md>" --attachments-dir "$(dirname "<analysis.md>")"
145
+ ```
146
+
147
+ Read its JSON envelope as the analysis render step does, and surface any
148
+ missing-attachment warning.
149
+
100
150
  ## Phase 5 - Report
101
151
 
102
- Keys created, keys skipped, the coverage verdict, and the ledger path. If the
152
+ Keys created, keys skipped, the epic linked (or none), the coverage verdict, and the ledger path. If the
103
153
  verdict was `unverifiable`, say that in the report too - not only at approval
104
154
  time, because the report is what gets pasted elsewhere.
105
155
 
@@ -45,7 +45,7 @@ Inherited decisions: `$HOME/.claude/multi-agent-refs/analysis/locked.md`.
45
45
  - 1 match: use it; echo the path, no question.
46
46
  - 0 or 2+ matches: AskUserQuestion, `header: "Doc"`, question `<localized: "Which analysis document should we resolve?">`, options = matches (max 3) + Other for a free-typed path.
47
47
 
48
- **Validate**: file exists; front-matter parses with `template_version: v3` (a `v2` doc gets `WARN: v2 doc has no resolvable Section 20 contract; re-run /multi-agent:analysis` and the run halts); a `## <n>. Riskler ve Acik Sorular` / `## <n>. Risks and Open Questions` heading exists (numbering may have re-flowed per the omission rule - match by title, not by the literal number 20).
48
+ **Validate**: file exists; front-matter parses with `template_version: v3` (a `v2` doc gets `WARN: v2 doc has no resolvable Section 20 contract; re-run /multi-agent:analysis` and the run halts); a `## <n>. Riskler ve Acik Sorular` / `## <n>. Risks and Open Questions` heading exists (match by title, not by the literal number 20: the profiles number the section differently).
49
49
 
50
50
  **Step 2 - Repo root for "from repo" candidates.** Default order: front-matter platform's repo from `state.analysisSpec.repos[]` if the session holds it, else the repo containing the doc, else cwd. Confirm via AskUserQuestion only when no default resolves (`header: "Repo"`, options `Use current working directory` + Other).
51
51
 
@@ -60,7 +60,7 @@ Inherited decisions: `$HOME/.claude/multi-agent-refs/analysis/locked.md`.
60
60
 
61
61
  | Path | Reason |
62
62
  |------|--------|
63
- | `$HOME/.claude/multi-agent-refs/analysis-template.md` | Section 20 / Section 23 table contracts, front-matter shape, omission re-flow |
63
+ | `$HOME/.claude/multi-agent-refs/analysis-template.md` | Section 20 / Section 23 table contracts, front-matter shape, section omission |
64
64
  | `$HOME/.claude/multi-agent-refs/conventions-defaults.md` | `convention-fallback` default values per platform |
65
65
  | `~/.claude/lib/extract-conventions.sh` | fresh single-field extraction for convention-fallback candidates |
66
66
  | `ai-common-toolkit:humanizer` | tone reference for longer merged fragments (short fragments only need the punctuation gate) |
@@ -18,6 +18,12 @@ confirm: none
18
18
 
19
19
  Run the task end-to-end with no confirmations.
20
20
 
21
+ ## Gotchas
22
+
23
+ - The guard decides within a 5-second internal deadline and fails closed when unattended. On a heavily loaded machine a correct command can be refused for time, not for policy.
24
+ - An unattended run never pushes or opens a PR itself: it records the request in `pr-request.json` and the runner publishes it.
25
+ - An unattended run cannot run `/multi-agent:stack` or write `.claude/` in the repo; a missing stack toolkit is read from a local marketplace clone instead.
26
+
21
27
  ## What changes
22
28
 
23
29
  | Phase | Normal | Autopilot |
@@ -87,34 +93,13 @@ bash $HOME/.claude/scripts/phase-tracker.sh tokens <N> <in> <out> [cached]
87
93
 
88
94
  ### Visual channel - Claude Code (native TaskList widget, required)
89
95
 
90
- In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Skipping these calls is the #1 source of "I don't see any phases" complaints.
91
-
92
- **TaskCreate ordering (strict)**: All TaskCreate calls in a registration batch fire in strict phase-number order BEFORE any TaskUpdate in that batch, and a later batch only ever appends phases numbered above everything already registered. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
93
-
94
- ```text
95
- # Register one tile per phase, capture the taskId, persist it:
96
- for each phase in 0:Init, 1:Plan, 2:Dev, 3:Review, 4:Commit, 5:Report:
97
- TaskCreate({ subject: "Phase <N>: <Name>", activeForm: "<doing-form>" })
98
- -> returns taskId
99
- bash $HOME/.claude/scripts/phase-tracker.sh meta <N> tasklist_id "<taskId>"
100
-
101
- # Phase entry - flip the tile to in_progress alongside the state update:
102
- TaskUpdate({ taskId: <saved>, status: "in_progress" })
103
- bash $HOME/.claude/scripts/phase-tracker.sh update <N> in_progress
104
-
105
- # Active sub-step inside a phase - update activeForm so the spinner header reflects what's happening now:
106
- TaskUpdate({ taskId: <saved>, activeForm: "Editing TopBarView.swift" })
107
-
108
- # Phase exit - flip to completed/failed/skipped on both channels:
109
- TaskUpdate({ taskId: <saved>, status: "completed" })
110
- bash $HOME/.claude/scripts/phase-tracker.sh update <N> completed
111
- ```
96
+ In Claude Code the agent MUST also drive the native TaskList widget so the user sees a sticky phase tile stack - this is the only progress signal Claude Code surfaces. Register one tile per phase of the active set (`0:Init 1:Plan 2:Dev 3:Review 4:Commit 5:Report`) with `TaskCreate`, persist each `taskId` via `phase-tracker.sh meta <N> tasklist_id "<taskId>"`, and at every phase entry, sub-step and exit pair a `TaskUpdate` (status or `activeForm`) with the matching `phase-tracker.sh update`. Call pattern: `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "Call pattern". Mirror each with `phase-tracker.sh task` ("Mirroring the host's task list").
112
97
 
113
98
  `autopilot` mode TaskCreates all 6 phases (no phase is skipped).
114
99
 
115
100
  #### TaskCreate ordering (strict)
116
101
 
117
- **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied.** For `autopilot` that means: Phase 0 → Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
102
+ **All TaskCreate calls in a batch fire in strict phase-number order BEFORE any TaskUpdate is applied**, and a later batch only ever appends phases numbered above everything already registered. For `autopilot` that means: Phase 0 → Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks (e.g. `1 ✓ · 2 ✓ · 4 ✓ · 0 ▶ · 3 ☐`) even when the underlying state is correct. Pre-marking phases as completed/skipped before Phase 0 starts is FORBIDDEN - register the tile in order, then flip status via TaskUpdate when the phase actually short-circuits. Full ordering contract in `$HOME/.claude/multi-agent-refs/tracker-contract.md` section "TaskCreate ordering (strict)".
118
103
 
119
104
  ### Visual channel - Copilot CLI / plain shell
120
105
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: "Turn off continuous mode on this machine: the schedule is removed, work already running finishes, the repo selection is kept. Use when the machine should stop picking work up."
3
+ disable-model-invocation: true
3
4
  description-tr: "Bu makinede sürekli modu kapatır: zamanlama kaldırılır, koşan iş biter, repo seçimi saklanır."
4
5
  argument-hint: "[--now] - --now also stops the item currently running"
5
6
  parameters: [{"name":"--now","kind":"flag"}]
@@ -26,61 +27,40 @@ When something is running, name it and how long it has been going. "Stopped"
26
27
  means something different when an item is 2 minutes from a PR than when the queue
27
28
  is idle, and the user is the one who knows which.
28
29
 
29
- ### 2. Remove the schedule
30
+ ### 2. Turn it off
30
31
 
31
32
  ```bash
32
- L="com.multi-agent.autopilot"
33
- launchctl bootout "gui/$(id -u)/$L" 2>/dev/null || launchctl unload "$HOME/Library/LaunchAgents/$L.plist" 2>/dev/null
34
- rm -f "$HOME/Library/LaunchAgents/$L.plist"
33
+ node "$HOME/.claude/scripts/autopilot-control.mjs" off
35
34
  ```
36
35
 
37
- The plist is removed rather than left disabled, because its presence is the
38
- definition of on: a disabled-but-present job is a third state nobody can read
39
- from the outside.
36
+ One script does every step, the same one `POST /v1/autopilot/off` runs, so the
37
+ command and a client turn the mode off the same way: the schedule's job is
38
+ booted out and its plist removed (its presence is the definition of on, so it is
39
+ removed rather than disabled), the awake agent goes with it (it would keep a Mac
40
+ awake for a mode that is off), an in-flight sleep lock is released only when the
41
+ tick that holds it has ended, and the menu bar indicator stops. It prints
42
+ `{"enabled": false, "stoppedInFlight": false}`.
40
43
 
41
- The awake agent goes with it, the same way:
44
+ ### 3. `--now` only: end the in-flight item deliberately
42
45
 
43
- ```bash
44
- . "$HOME/.claude/lib/autopilot-state.sh"
45
- node "$(ma_ap_asset scripts/autopilot-awake.mjs)" remove
46
- ```
47
-
48
- It holds sleep off for as long as it is loaded, and it has no meaning without
49
- the schedule: left behind, it keeps a Mac awake for a mode that is off.
50
-
51
- ### 3. Release the in-flight sleep lock and the indicator
46
+ Without `--now` nothing in flight is touched. With it, first name the item, its
47
+ worktree and whether it holds uncommitted work, and ask before stopping
48
+ anything; the command is declared `destructive: true` with `confirm: required`,
49
+ so a client confirms before it even starts. On a yes:
52
50
 
53
51
  ```bash
54
- INH="$HOME/.claude/autopilot/inhibitor.json"
55
- if [ -f "$INH" ]; then
56
- RP=$(jq -r '.runnerPid // empty' "$INH"); IP=$(jq -r '.pid // empty' "$INH")
57
- if [ -n "$RP" ] && kill -0 "$RP" 2>/dev/null; then
58
- echo "the tick in flight holds sleep until it ends"
59
- else
60
- [ -n "$IP" ] && kill "$IP" 2>/dev/null; rm -f "$INH"
61
- fi
62
- fi
63
- pkill -f "$HOME/.claude/autopilot/bin/menubar" 2>/dev/null || true
52
+ node "$HOME/.claude/scripts/autopilot-control.mjs" off --now
64
53
  ```
65
54
 
66
- The in-flight sleep lock belongs to a tick, not to the mode: the runner releases it
67
- when the tick ends and it exits with the runner's pid, so the only one left to
68
- stop is one whose runner is already gone - by the pid it recorded, never by name.
69
-
70
- ### 4. `--now` only: end the in-flight item deliberately
71
-
72
- Without `--now` nothing here runs. With it, first name the item, its worktree and
73
- whether it holds uncommitted work, and ask before stopping anything; the command
74
- is declared `destructive: true` with `confirm: required`, so a client confirms
75
- before it even starts. On a yes, the child session is stopped and the run is
76
- marked `abandoned`, its worktree is removed **unless it holds uncommitted
77
- work**, in which case the work goes into a stash entry labelled
78
- `autopilot/abandoned/<task-id>` (find it with `git stash list`) and the worktree
79
- is kept. Same contract as `gc-abandoned.sh` and `autopilot-runner.mjs`; losing a
80
- day of edits is worse than 750 MB. No branch is created - one made after
81
- `stash push` would point at HEAD and contain none of the work.
55
+ The child session is stopped and the run is marked `abandoned`; its worktree is
56
+ removed **unless it holds uncommitted work**, in which case the work goes into a
57
+ stash entry labelled `autopilot/abandoned/<task-id>` (find it with
58
+ `git stash list`) and the worktree is kept. Same contract as `gc-abandoned.sh`
59
+ and `autopilot-runner.mjs`; losing a day of edits is worse than 750 MB. No
60
+ branch is created - one made after `stash push` would point at HEAD and contain
61
+ none of the work. `stoppedInFlight` says whether a session was stopped.
82
62
 
83
- ### 5. Keep the selection
63
+ ### 4. Keep the selection
84
64
 
85
65
  `~/.claude/autopilot/config.json`, `queue.json` and `attempted.jsonl` all stay.
86
66
  Turning the mode back on must not re-ask which repos, and the attempt history is
@@ -89,7 +69,7 @@ what stops an item that already failed twice from being retried forever.
89
69
  To forget the selection as well: `rm -rf ~/.claude/autopilot`. Say that rather
90
70
  than doing it - "off" and "forget everything" are different requests.
91
71
 
92
- ### 6. Report
72
+ ### 5. Report
93
73
 
94
74
  State that it is off, what was left running or finishing, and that the repo
95
75
  selection is kept. If an item was stashed, name the stash entry
@@ -16,6 +16,13 @@ allowed-tools: Read, Write, Edit, Bash, Grep, WebFetch, AskUserQuestion
16
16
  **Claude Code invocation:** `/multi-agent:channels <target>`
17
17
  **Copilot CLI invocation:** `multi-agent-channels <target>` (top-level command, dash-separated per Copilot no-namespace convention)
18
18
 
19
+ ## Gotchas
20
+
21
+ - Nothing is posted before the Step 6 approval gate resolves, in every interactive mode. Under `MULTI_AGENT_UNATTENDED=1` nothing is posted at all.
22
+ - Jira renders `:)` `(x)` `(!)` as emoticons, so a Swift selector like `login(source:input:)` breaks. Post through `jira-publish.sh`, which escapes the body; never assemble the request by hand.
23
+ - A Bitbucket PR update must carry the reviewer list back, or the PUT removes every reviewer.
24
+ - With several repos, the PR description goes to every PR but Jira and Confluence get one post each.
25
+
19
26
  ## Input
20
27
 
21
28
  ```
@@ -90,42 +97,9 @@ When the preview renders:
90
97
  When the preview does NOT render (no state, or pref explicitly off at global level with no override):
91
98
  - Skip 3a silently, go straight to the channels picker. The workSummary row in 3b stays at its pref default (`false`).
92
99
 
93
- **Visual flow (TR, pref on + state available):**
94
-
95
- ```
96
- Yapılan iş özeti - PROJ-12345
97
- ──────────────────────────────────────────────────────────
98
- {rendered Work Summary block - header + scope + diffstat + review + phases}
99
- ──────────────────────────────────────────────────────────
100
-
101
- [done] İş özetini gördün. Şimdi nereye rapor gönderelim?
102
- ```
103
-
104
- Then 3b renders:
105
-
106
- ```
107
- ┌─ Kanallar ────────────────────────────────────────────
108
- │ Nereye rapor gönderilsin?
109
- │ [x] PR description (replace / append)
110
- │ [x] Jira comment (jiraId: PROJ-12345)
111
- │ [ ] Confluence page
112
- │ [ ] Wiki (taskType=component + wiki.enabled gerekli)
113
- │ [ ] Board (figmaConfig.board.enabled + projectV2Id gerekli)
114
- └───────────────────────────────────────────────────────
115
-
116
- ┌─ İçerik ──────────────────────────────────────────────
117
- │ Ne eklensin?
118
- │ [x] Normal analiz (Phase 1+2+4'ten - high-level impact + risks)
119
- │ [ ] Teknik analiz (Changes · Architecture · Dependencies - PR body'deki Technical Details özeti)
120
- │ [x] Test senaryoları (Phase 1+2+4'ten)
121
- │ [ ] PR diff'ten auto-gen (PR varsa diff'i summarize eder)
122
- │ [ ] Manuel not (--message / --message-file)
123
- │ [ ] Cost özeti (per-phase token + est. USD - tracker data gerekli)
124
- │ [x] Yapılan iş özeti (executive summary - yukarıda gösterilen block)
125
- └───────────────────────────────────────────────────────
126
- ```
100
+ After the preview prints, 3b renders the two pickers: **Channels** (PR description, Jira comment, Confluence page, Wiki, Board; each unavailable one greyed with its reason) and **Content** (normal analysis, technical analysis, test scenarios, PR auto-diff, manual note, cost summary, work summary).
127
101
 
128
- **Why auto-tick:** the user JUST saw the summary and is likely sending it somewhere - otherwise they would have stopped before running `/multi-agent:channels`. Auto-tick matches the 80% case; the 20% case (preview was enough, no remote post needed) is a single keystroke to uncheck.
102
+ **Why auto-tick:** the user just saw the summary and is most likely sending it; the explicit pref still wins.
129
103
 
130
104
  **Autopilot interaction (Step 4):** `state.autopilot === true` still pauses at channels (documented exception to zero-interaction contract), preview in-line. Under `MULTI_AGENT_UNATTENDED=1` it posts nothing: `$HOME/.claude/multi-agent-refs/features/unattended-security.md`.
131
105
 
@@ -370,19 +344,7 @@ Secondary artifacts ride along as one-line intents at the bottom of the preview:
370
344
 
371
345
  For each selected **channel**, call the corresponding adapter. Adapters run **in parallel** - one failure does not block others. Dispatch NEVER starts before the Step 6 gate resolves (`Approve & post`), except in the two documented skip cases (autopilot, `--dry-run`).
372
346
 
373
- **Multi-repo dispatch:** When `state.projects[].length > 1`, the dispatcher delegates per-channel rendering to `~/.claude/lib/channels-multi-repo.sh`:
374
-
375
- | Channel | Behavior | Adapter call |
376
- |---------|----------|--------------|
377
- | **PR description** | Posted to **every** target's PR. Primary's body lists extras as `Related: <url>`; each extra's body lists primary as `Part of: <url>`. | `channels-multi-repo.sh render-pr <state> <body> <repoName>` per target |
378
- | **Jira comment** | Posted **once** (Jira ticket is shared by all repos). Body prepended with bulleted `* PR:` list - primary first, extras after. | `channels-multi-repo.sh render-jira <state> <body>` once |
379
- | **Confluence page** | Posted **once** to the primary's component slug. `## Related PRs` heading block prepended. | `channels-multi-repo.sh render-conf <state> <body>` once |
380
- | **Wiki** | Posted **once** to the primary repo's wiki, since wiki scope is `figma-config.wikiRepo` (single repo). | No adapter - body unchanged |
381
- | **Board** | Posted **once** - board status is keyed off the GitHub Issue, not per-PR. Primary repo's issue is the target. | No adapter - single mutation |
382
-
383
- **Target enumeration:** `channels-multi-repo.sh targets <state>` returns a JSON array `[{repoName, prUrl, prNumber, isPrimary, crossLinks}]` for the dispatch loop. Single-repo tasks return one entry with empty `crossLinks` - every render-* call falls through to the body unchanged, so the loop is uniform across single-repo and multi-repo paths.
384
-
385
- **Logging hint:** `channels-multi-repo.sh summary <state>` produces a one-line autopilot log entry (`1 primary (foo) + 2 extras: <url> <url>` or `single-repo task`).
347
+ **Multi-repo dispatch** (`state.projects[].length > 1`): which channel posts once and which per repo, and the `channels-multi-repo.sh` calls: `$HOME/.claude/multi-agent-refs/channels/multi-repo.md`.
386
348
 
387
349
  #### Adapter: PR description
388
350
  Aggregated Markdown from Step 5 → PR description. GitHub uses `gh pr edit --body-file`; Bitbucket uses a **reviewer-preserving (required)** `PUT /pull-requests/{id}` payload (must re-send `reviewers`, `fromRef`, `toRef`, `draft`, `version` - omitting any one resets that field server-side). Default is **replace**; `--append` opt-in. Multi-repo cross-links handled by `channels-multi-repo.sh render-pr`.
@@ -409,21 +371,7 @@ Full contract: [`$HOME/.claude/multi-agent-refs/channels/confluence.md`]($HOME/.
409
371
 
410
372
  #### Adapter: Board (GitHub Projects v2 status move)
411
373
 
412
- **Precondition gate:** `figmaConfig.board.enabled === true` AND `figmaConfig.board.provider === "github-projects-v2"` AND `figmaConfig.github.projectV2Id` non-empty. If not met, the channel is greyed in the menu (Step 3b rule) and the adapter is skipped silently in flag-mode dispatch.
413
-
414
- **Default target column:** `inReview` - read from `figmaConfig.github.fieldOptions.status.inReview` (the option ID, e.g. `bdb0d8ef`). Other column targets (e.g. `done`, `bugfix`) overridable via flag `--board-status <key>` where `<key>` matches a key under `fieldOptions.status`.
415
-
416
- **Token:** `prefs.global.keychainMapping.github_projects` (preferred - must include `project,read:project` scopes). Fallback chain: `keychainMapping.github` → standard key `${USER}_Github_Access_Token`. Resolve via `~/.claude/lib/credential-store.sh get <key>` (reads the macOS Keychain). Token must NOT be passed on the CLI - export as `GH_TOKEN` env var only (per memory rule on token leakage).
417
-
418
- **Item lookup:** the issue's project item ID is fetched via GraphQL `repository.issue(number).projectItems(first:5)` filtered to `project.id === figmaConfig.github.projectV2Id`. If the issue is not yet in the project, dispatch silently no-ops with reason `"issue not on board"` in the summary.
419
-
420
- **Mutation:** GraphQL `updateProjectV2ItemFieldValue(input: { projectId, itemId, fieldId: figmaConfig.github.projectV2Fields.status, value: { singleSelectOptionId: <target> } })`. Verify by re-querying `fieldValueByName(name: "Status")` on the same item; assert `name === target column label` from `figmaConfig.board.columns`.
421
-
422
- **Multi-repo:** runs **once** (board status is keyed off the GitHub Issue, not per-PR). When `state.projects[].length > 1`, the primary repo's issue is the target; extras' PRs do not trigger additional moves.
423
-
424
- **Idempotency:** if the issue is already on the target column, the mutation is a no-op and the adapter reports `"already in <column>"` in the summary.
425
-
426
- **Additional behaviors handled inline by this adapter** (no separate contract file): token scope upgrade flow (`gh auth refresh -s project,read:project`), field-ID auto-discovery for repos missing `projectV2Fields.status` in figma-config, error-recovery (token expired vs scope insufficient).
374
+ Precondition, token, item lookup, mutation and idempotency: `$HOME/.claude/multi-agent-refs/channels/board.md`.
427
375
 
428
376
  #### Adapter: Wiki
429
377
  **Precondition gate:** `state.taskType === "component"` AND `figmaConfig.wiki.enabled === true`. If not met, shows the Case B menu from `$HOME/.claude/multi-agent-refs/wiki-capture.md` (setup / skip / disable / manual-note).