@mmerterden/multi-agent-pipeline 20.13.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 (153) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +8 -6
  3. package/README.tr.md +7 -5
  4. package/docs/architecture.md +3 -3
  5. package/docs/ecosystem.md +5 -5
  6. package/docs/facts.json +4 -4
  7. package/install/catalog-history.json +1 -1
  8. package/manifest.json +156 -96
  9. package/package.json +1 -1
  10. package/pipeline/commands/multi-agent/analysis/SKILL.md +11 -80
  11. package/pipeline/commands/multi-agent/autopilot/SKILL.md +2 -23
  12. package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +24 -45
  13. package/pipeline/commands/multi-agent/channels/SKILL.md +11 -63
  14. package/pipeline/commands/multi-agent/design-check/SKILL.md +43 -178
  15. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +2 -0
  16. package/pipeline/commands/multi-agent/estimate/SKILL.md +65 -0
  17. package/pipeline/commands/multi-agent/help/SKILL.md +5 -546
  18. package/pipeline/commands/multi-agent/kill/SKILL.md +13 -18
  19. package/pipeline/commands/multi-agent/refactor/SKILL.md +7 -76
  20. package/pipeline/commands/multi-agent/review-analysis/SKILL.md +1 -1
  21. package/pipeline/commands/multi-agent/scenario-audit/SKILL.md +79 -0
  22. package/pipeline/commands/multi-agent/serve/SKILL.md +6 -3
  23. package/pipeline/commands/multi-agent/setup/SKILL.md +12 -365
  24. package/pipeline/commands/multi-agent/status/SKILL.md +2 -0
  25. package/pipeline/commands/multi-agent/store-ready/SKILL.md +56 -184
  26. package/pipeline/commands/multi-agent/sync/SKILL.md +14 -267
  27. package/pipeline/contract/CHANGELOG.md +52 -0
  28. package/pipeline/contract/README.md +41 -1
  29. package/pipeline/contract/build.mjs +49 -7
  30. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  31. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  32. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  33. package/pipeline/contract/fixtures/launch-plan.json +1 -2
  34. package/pipeline/contract/fixtures/runs-awaiting-question.json +10 -3
  35. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  36. package/pipeline/contract/fixtures/runs-failed.json +19 -6
  37. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +25 -8
  38. package/pipeline/contract/fixtures/runs-pr-opened.json +25 -8
  39. package/pipeline/contract/fixtures/runs-running.json +31 -4
  40. package/pipeline/contract/frozen/toolbox.json +13 -0
  41. package/pipeline/contract/manifest.json +112 -10
  42. package/pipeline/contract/types/index.d.ts +186 -17
  43. package/pipeline/lib/claude-sessions.mjs +93 -0
  44. package/pipeline/lib/credential-resolve.mjs +39 -0
  45. package/pipeline/lib/gc-report.sh +64 -0
  46. package/pipeline/lib/unattended-settings-location.mjs +4 -0
  47. package/pipeline/lib/workspace-trust.mjs +73 -0
  48. package/pipeline/multi-agent-refs/analysis/intake.md +5 -3
  49. package/pipeline/multi-agent-refs/analysis/locked.md +8 -7
  50. package/pipeline/multi-agent-refs/analysis/render.md +4 -3
  51. package/pipeline/multi-agent-refs/analysis/resolve.md +1 -1
  52. package/pipeline/multi-agent-refs/analysis/resume.md +37 -0
  53. package/pipeline/multi-agent-refs/analysis/reusable-refs.md +25 -0
  54. package/pipeline/multi-agent-refs/channels/board.md +17 -0
  55. package/pipeline/multi-agent-refs/channels/multi-repo.md +15 -0
  56. package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -4
  57. package/pipeline/multi-agent-refs/design-check/build-launch.md +14 -0
  58. package/pipeline/multi-agent-refs/design-check/compare.md +44 -0
  59. package/pipeline/multi-agent-refs/design-check/drive-capture.md +35 -0
  60. package/pipeline/multi-agent-refs/design-check/export.md +37 -0
  61. package/pipeline/multi-agent-refs/design-check/figma-mapping.md +11 -0
  62. package/pipeline/multi-agent-refs/design-check/init-inventory.md +56 -0
  63. package/pipeline/multi-agent-refs/design-check/mcp-currency-gate.md +41 -0
  64. package/pipeline/multi-agent-refs/features/analysis-outline.md +55 -0
  65. package/pipeline/multi-agent-refs/features/analysis-sources.md +60 -0
  66. package/pipeline/multi-agent-refs/help/en.md +273 -0
  67. package/pipeline/multi-agent-refs/help/tr.md +271 -0
  68. package/pipeline/multi-agent-refs/orchestrator/operations.md +99 -0
  69. package/pipeline/multi-agent-refs/orchestrator/phase-0-projects.md +72 -0
  70. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +40 -0
  71. package/pipeline/multi-agent-refs/orchestrator/phase-4-5-projects.md +68 -0
  72. package/pipeline/multi-agent-refs/orchestrator/skill-loading.md +99 -0
  73. package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -2
  74. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +1 -1
  75. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
  76. package/pipeline/multi-agent-refs/picker-contract.md +29 -0
  77. package/pipeline/multi-agent-refs/refactor/drift.md +49 -0
  78. package/pipeline/multi-agent-refs/refactor/run-errors.md +46 -0
  79. package/pipeline/multi-agent-refs/setup/discovery.md +84 -0
  80. package/pipeline/multi-agent-refs/setup/figma.md +27 -0
  81. package/pipeline/multi-agent-refs/setup/identity-routing.md +60 -0
  82. package/pipeline/multi-agent-refs/setup/token-save-flow.md +201 -0
  83. package/pipeline/multi-agent-refs/store-ready/build.md +49 -0
  84. package/pipeline/multi-agent-refs/store-ready/gate-1-static.md +37 -0
  85. package/pipeline/multi-agent-refs/store-ready/gate-3-policy.md +31 -0
  86. package/pipeline/multi-agent-refs/store-ready/preflight.md +50 -0
  87. package/pipeline/multi-agent-refs/store-ready/report.md +40 -0
  88. package/pipeline/multi-agent-refs/sync/codex.md +43 -0
  89. package/pipeline/multi-agent-refs/sync/dev-toolkit.md +174 -0
  90. package/pipeline/multi-agent-refs/sync/stack-plugins.md +51 -0
  91. package/pipeline/multi-agent-refs/tracker-contract.md +29 -4
  92. package/pipeline/schemas/agent-state.schema.json +13 -4
  93. package/pipeline/schemas/analysis-spec.schema.json +56 -4
  94. package/pipeline/schemas/autopilot-off-request.schema.json +20 -0
  95. package/pipeline/schemas/autopilot-off.schema.json +24 -0
  96. package/pipeline/schemas/autopilot-status.schema.json +63 -0
  97. package/pipeline/schemas/contract-error.schema.json +13 -2
  98. package/pipeline/schemas/gc-request.schema.json +31 -0
  99. package/pipeline/schemas/gc.schema.json +116 -0
  100. package/pipeline/schemas/kill-request.schema.json +22 -0
  101. package/pipeline/schemas/kill.schema.json +118 -0
  102. package/pipeline/schemas/launch-plan.schema.json +11 -2
  103. package/pipeline/schemas/launch-request.schema.json +7 -2
  104. package/pipeline/schemas/launch.json +65 -4
  105. package/pipeline/schemas/launch.schema.json +23 -8
  106. package/pipeline/schemas/prefs.schema.json +3 -3
  107. package/pipeline/schemas/repos.schema.json +39 -0
  108. package/pipeline/schemas/resume-request.schema.json +37 -0
  109. package/pipeline/schemas/run-log.schema.json +32 -0
  110. package/pipeline/schemas/run-questions.json +5 -1
  111. package/pipeline/schemas/run-questions.schema.json +1 -1
  112. package/pipeline/schemas/runs-index.schema.json +59 -3
  113. package/pipeline/scripts/_run-paths.mjs +8 -2
  114. package/pipeline/scripts/analysis-conform-coverage.mjs +96 -0
  115. package/pipeline/scripts/analysis-sources.mjs +264 -0
  116. package/pipeline/scripts/autopilot-control.mjs +223 -0
  117. package/pipeline/scripts/autopilot-runner.mjs +14 -39
  118. package/pipeline/scripts/build-references.mjs +5 -1
  119. package/pipeline/scripts/confluence-readback.mjs +4 -23
  120. package/pipeline/scripts/contract-server.mjs +373 -7
  121. package/pipeline/scripts/doctor.mjs +5 -2
  122. package/pipeline/scripts/estimate.mjs +223 -0
  123. package/pipeline/scripts/gate-ledger.mjs +64 -3
  124. package/pipeline/scripts/gc-plan.mjs +288 -0
  125. package/pipeline/scripts/gc-refs.sh +33 -2
  126. package/pipeline/scripts/gc-tmp.sh +33 -2
  127. package/pipeline/scripts/gc-worktrees.sh +42 -3
  128. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -24
  129. package/pipeline/scripts/launch-request.mjs +182 -10
  130. package/pipeline/scripts/phase-tracker.sh +62 -1
  131. package/pipeline/scripts/run-kill.mjs +232 -0
  132. package/pipeline/scripts/run-log.mjs +111 -0
  133. package/pipeline/scripts/runs-index.mjs +177 -11
  134. package/pipeline/scripts/scenario-audit.mjs +245 -0
  135. package/pipeline/scripts/validate-analysis-doc.mjs +84 -6
  136. package/pipeline/skills/.skill-manifest.json +24 -16
  137. package/pipeline/skills/shared/README.md +5 -3
  138. package/pipeline/skills/shared/core/multi-agent/SKILL.md +51 -450
  139. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +7 -1
  140. package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +26 -44
  141. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +31 -127
  142. package/pipeline/skills/shared/core/multi-agent-estimate/SKILL.md +61 -0
  143. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +14 -19
  144. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +7 -76
  145. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
  146. package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +1 -1
  147. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
  148. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
  149. package/pipeline/skills/shared/core/multi-agent-scenario-audit/SKILL.md +77 -0
  150. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +6 -3
  151. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +205 -324
  152. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +5 -0
  153. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
@@ -72,46 +72,12 @@ Roll the high-impact + low/med-effort survivors into the Step 4 plan as band-A i
72
72
 
73
73
  Some skills/components in this project (or in the marketplace plugins it ships) were derived from an upstream source. Upstream keeps evolving - it fixes bugs and adds features. This step detects upstream drift so we can decide whether to pull the improvements back.
74
74
 
75
- The upstream mapping is **configuration, never hardcoded** (it can reference private sources, so it stays out of the shipped skill). Read it from `~/.claude/multi-agent-preferences.json` at `global.derivedSkillSources` (an array). Each entry:
76
-
77
- ```jsonc
78
- {
79
- "label": "<human name for this derivation>",
80
- "localPath": "<repo-relative dir where our derived copy lives>",
81
- "upstreamMarketplace": "<installed marketplace name>", // resolved under ~/.claude/plugins/cache/<marketplace>/
82
- "upstreamPlugin": "<plugin name>",
83
- "upstreamSkills": ["<skill-a>", "<skill-b>"], // the upstream skills we took
84
- "derivedFromVersion": "<x.y.z>", // the version we last synced from
85
- "upstreamVersionSource": "marketplace.json", // which manifest is authoritative; default marketplace.json
86
- "upstreamLocalClone": "<optional path>", // working copy of the upstream repo, preferred over the cache
87
- "upstreamRepoUrl": "<optional https url>" // used when neither a clone nor the marketplace is available
88
- }
89
- ```
90
-
91
- **The plugin cache is a mirror, not the authority.** `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/` only holds whatever the last `claude plugin marketplace update` fetched. Reading it as the current upstream version is how this step reported "up to date" while the derivation was four releases behind: the cache sat at 0.2.1 and upstream was at 0.4.1. Resolve in the order below and never let the cache alone produce an "up to date" verdict.
92
-
93
- **Which manifest carries the version** is `upstreamVersionSource`, default `marketplace.json`. That is what a marketplace consumer actually resolves, and some upstreams keep per-plugin `plugin.json` versions deliberately unused - reading those records a version nobody ships. An entry here was recorded at 0.7.0 from `plugin.json` while the upstream marketplace said 0.6.0 and its CHANGELOG stated in as many words that `plugin.json` is not used.
94
-
95
- Procedure:
96
- 1. If `global.derivedSkillSources` is missing or empty -> **skip** this step and report "no derived-skill sources configured" (nothing to check). Never invent a source.
97
- 2. For each entry, resolve the current upstream version, in this order, stopping at the first that answers:
98
- - **`upstreamLocalClone`** if set: read `<clone>/.claude-plugin/<upstreamVersionSource>`. Also run `git -C <clone> fetch --dry-run` (or compare against `@{u}`) and say so when the clone is itself behind, so a stale working copy is not silently trusted either.
99
- - **`upstreamRepoUrl`**: read the same manifest over the API (`gh api` / `WebFetch`). A private upstream can 404 for the currently active account even when the repo exists - that is an unreachable result, not a "no drift" result.
100
- - **Plugin cache** under `~/.claude/plugins/cache/<upstreamMarketplace>/<upstreamPlugin>/*/`: last resort only. When the cache is the only source that answered, report the entry as **`unverified (cache only)`**, never as "up to date", and add a plan item to configure `upstreamLocalClone`.
101
- - If nothing is reachable, record the entry as "upstream unreachable" and move on (do not fail the whole run).
102
- 3. Compare the resolved upstream version to `derivedFromVersion`:
103
- - equal, from an authoritative source -> "up to date" (no drift)
104
- - equal, from the cache only -> "unverified (cache only)"
105
- - newer -> **drift**: read the CHANGELOG entries between the two versions, and diff each `upstreamSkills` SKILL.md (+ any templates) against our `localPath` copy. Summarize what changed upstream (bug fixes, new sections, new templates, renamed inputs). Ignore changelog entries that only touch skills outside `upstreamSkills` - they are not ours to port.
106
- 4. Emit the drift table (plan band D):
107
-
108
- ```
109
- | Derivation | Our copy (localPath) | Derived-from | Upstream now | Drift | What changed upstream |
110
- |------------|----------------------|--------------|--------------|-------|-----------------------|
111
- | <label> | <path> | 0.2.1 | 0.3.0 | YES | <changelog + diff summary> |
112
- ```
75
+ Rules that hold for every entry:
76
+ - The upstream mapping is **configuration, never hardcoded**: `global.derivedSkillSources` in `~/.claude/multi-agent-preferences.json`. Missing or empty -> **skip** and report "no derived-skill sources configured". Never invent a source.
77
+ - **The plugin cache is a mirror, not the authority.** Never let the cache alone produce an "up to date" verdict; report it as **`unverified (cache only)`**. An unreachable upstream is recorded as "upstream unreachable" and the run continues.
78
+ - Each drifted entry becomes a band-D plan item. Do not auto-apply upstream changes - they go through Step 5 approval like everything else, and after porting, bump the entry's `derivedFromVersion`.
113
79
 
114
- 5. For each drifted entry, add a band-D plan item: "port upstream <plugin> <version> changes into <localPath>", with the specific skills to update. Do not auto-apply upstream changes - they go through Step 5 approval like everything else, and after porting, bump the entry's `derivedFromVersion`.
80
+ Full procedure: `$HOME/.claude/multi-agent-refs/refactor/drift.md`. Read it when `global.derivedSkillSources` has at least one entry (entry schema, source resolution order, version manifest, comparison, band-D table).
115
81
 
116
82
  ## Step 0c: DEV-TOOLKIT - current MCP practice for the companion toolkit
117
83
 
@@ -121,44 +87,9 @@ Full procedure - resolution (configuration first, never a hardcoded path; skip
121
87
 
122
88
  ## Step 0d: RUN-ERRORS - what the pipeline actually failed on
123
89
 
124
- Before speculating about improvements, read what real runs already failed on. When usage logging is enabled, every terminated run appends its errors to a local ledger:
125
-
126
- ```bash
127
- LEDGER="$HOME/.claude/logs/multi-agent/errors-ledger.jsonl"
128
- [ -f "$LEDGER" ] || echo "no run-error ledger yet - skip band F"
129
- ```
130
-
131
- Each line is one run: `{ t, id, u, c, rp, ph, v, errs[] }`. The `errs[]` entries are cause tags (`<phase>:<cause>` halt reasons, `phase-<id>-failed`, `run-failed`).
132
-
133
- 1. Read the ledger (best-effort; a missing or unreadable file means skip band F, not a failure).
134
- 2. Group by error tag. For each tag compute: occurrences, distinct users affected, distinct repos, the phase it usually strikes, first + last seen, and which pipeline versions it spans (a tag that persists across versions is unfixed; one that stopped at a version is already resolved - do not re-raise it).
135
- 3. Rank by `occurrences x users-affected`. A failure that recurs across users or tasks is lived evidence, not a hypothesis - it outranks a speculative improvement.
136
- 4. For each surviving tag, trace it to the phase doc / script that emits that cause and propose the concrete fix.
137
-
138
- This band mirrors the admin dashboard's "Gelişim alanları" panel, but reads the local ledger so it needs no auth and works offline. If `$ARGUMENTS` names a focus area, still read the ledger - a recurring run error in that area is the strongest possible signal.
139
-
140
- Then read what the transcripts themselves record, which is the half no model noticed:
141
-
142
- ```bash
143
- node "$HOME/.claude/scripts/learn-from-transcripts.mjs" --json
144
- ```
145
-
146
- It correlates rather than interprets - a failed read against the read that then worked, an identical invocation that kept failing, a search that was too narrow, a call the user refused twice, a file too big to read whole. Dry run by default; `--apply` writes them to the learnings ledger as `source: transcript-mining` and renders a marked block in `CLAUDE.local.md`. Zero candidates alongside a non-zero `toolResultsExamined` means there was nothing to find; zero of both means the read is broken.
147
-
148
- Output (plan band F):
149
-
150
- ```
151
- | # | Error tag | Occurrences | Users | Usual phase | Versions | Root cause (file) | Fix | In plan? |
152
- |---|-----------|-------------|-------|-------------|----------|-------------------|-----|----------|
153
- | 1 | 4:reviewer-json-invalid | 12 | 3 | 4 | 14.x-15.x | reviewer prompt lets prose leak | tighten schema instruction in phase-3-review.md | Yes (P0) |
154
- | 2 | phase-3-failed | 5 | 2 | 3 | 15.0.x | build step misses a stack toolchain | add preflight in phase-2-dev.md | Yes (P1) |
155
- ```
156
-
157
- Rules for this band:
90
+ Before speculating about improvements, read what real runs already failed on. When usage logging is enabled, every terminated run appends its errors to a local ledger at `$HOME/.claude/logs/multi-agent/errors-ledger.jsonl`. A missing, unreadable or empty ledger means skip band F silently - it is additive signal, never a gate. If `$ARGUMENTS` names a focus area, still read the ledger - a recurring run error in that area is the strongest possible signal. A tag that stopped recurring after a version bump is resolved: report it, do not re-raise it. Never quote a user's identity as blame.
158
91
 
159
- - The ledger is evidence of the past, not a spec. A tag that stopped recurring after a version bump is resolved - report it as resolved, do not add a plan item.
160
- - Never quote a user's identity as blame. The `u` field is for counting distinct affected users, not for naming anyone in the plan.
161
- - If the ledger is empty or absent, skip band F silently - it is additive signal, never a gate.
92
+ Full procedure: `$HOME/.claude/multi-agent-refs/refactor/run-errors.md`. Read it when the ledger exists (record shape, grouping and ranking, transcript mining, band-F table).
162
93
 
163
94
  ## Step 0e: BACKLOG - friction this pipeline already noticed
164
95
 
@@ -32,7 +32,7 @@ Read `$HOME/.claude/multi-agent-refs/analysis/review.md` and execute it:
32
32
 
33
33
  ## Why it cites Locked decisions
34
34
 
35
- The analysis flow already declares 36 Locked decisions and two deterministic validators. A reviewer that says "I would have written this differently" gives the author nothing to act on; one that says "Locked 33: the Confluence page is in the evidence record but not in Section 21" gives them a fix and a reason. Findings that map to no rule are still allowed, but they are marked as judgement, not dressed up as a violation.
35
+ The analysis flow already declares 37 Locked decisions and two deterministic validators. A reviewer that says "I would have written this differently" gives the author nothing to act on; one that says "Locked 33: the Confluence page is in the evidence record but not in Section 21" gives them a fix and a reason. Findings that map to no rule are still allowed, but they are marked as judgement, not dressed up as a violation.
36
36
 
37
37
  ## What it never does
38
38
 
@@ -0,0 +1,79 @@
1
+ ---
2
+ description: "Audit test scenarios from a CSV against the code: mark each PRESENT, PARTIAL, ABSENT or UNCLEAR, every PRESENT backed by a file:line that resolves at HEAD. Read-only. Use when a test set or acceptance list has to be checked against what the code does."
3
+ description-tr: "Test senaryolarını koda karşı denetler: CSV'deki (ya da CSV'ye aktarılmış Jira test setindeki) her senaryo için kodun onu nerede karşıladığını bulur ve VAR, KISMEN, YOK ya da BELİRSİZ olarak işaretler; her VAR, HEAD'de çözülen bir dosya:satır ile desteklenir. Salt-okunur."
4
+ allowed-tools: Bash, Read, Grep, AskUserQuestion
5
+ argument-hint: "<scenarios.csv> [--repo <path>]"
6
+ parameters: [{"name":"scenarios","kind":"path","required":true},{"name":"--repo","kind":"path"}]
7
+ gui: form
8
+ destructive: false
9
+ confirm: none
10
+ not-for: test, manual-test, review
11
+ ---
12
+
13
+ # multi-agent scenario-audit
14
+
15
+ **Input**: $ARGUMENTS
16
+
17
+ Checks a list of test scenarios against a repository and says, per scenario,
18
+ whether the code implements it. The judgement is yours; the evidence rule is
19
+ the script's. Nothing is written and nothing leaves the machine.
20
+
21
+ Script: `$HOME/.claude/scripts/scenario-audit.mjs`.
22
+
23
+ ## Gotchas
24
+
25
+ - A verdict without a resolving `file:line` is not PRESENT. `verify` turns it into UNCLEAR and says why; do not argue with it, find the line.
26
+ - ABSENT is a claim about a search. Record the terms you searched; an ABSENT with no terms becomes UNCLEAR.
27
+ - Scenario text is usually business language and the code is not. Search for identifiers, localization keys, endpoint paths and error codes, not for the scenario's words.
28
+ - The audit reads HEAD. Uncommitted work is not seen; say so when the working tree is dirty.
29
+
30
+ ## Step 1 - Inventory
31
+
32
+ The scenarios file is a CSV with an id column and a title column (`id`/`no`/`key`,
33
+ `title`/`scenario`/`senaryo`/`başlık`; optional `steps`/`adımlar` and
34
+ `expected`/`beklenen`). Comma or semicolon. A Jira test set is exported to this
35
+ shape first.
36
+
37
+ ```bash
38
+ node "$HOME/.claude/scripts/scenario-audit.mjs" inventory --csv "<scenarios.csv>" > /tmp/ma-scenarios.json
39
+ ```
40
+
41
+ Exit 2 names the missing column. With no `--repo`, the repository is the
42
+ current directory; confirm it in one line before searching.
43
+
44
+ ## Step 2 - Search
45
+
46
+ For each scenario, write the code-level terms that would implement it into
47
+ `/tmp/ma-terms.json` (`{"<id>": ["term", ...]}`), then:
48
+
49
+ ```bash
50
+ node "$HOME/.claude/scripts/scenario-audit.mjs" search --terms /tmp/ma-terms.json --repo "<repo>"
51
+ ```
52
+
53
+ Read the candidate lines it returns. A term nothing matched is listed under
54
+ `missing`; try a second term before concluding anything.
55
+
56
+ ## Step 3 - Verdict
57
+
58
+ Write `/tmp/ma-verdicts.json`: `[{id, status, citations, searched, note}]`.
59
+
60
+ | Status | When | Needs |
61
+ |---|---|---|
62
+ | `PRESENT` | the code does what the scenario expects | `citations`: the `file:line` that does it |
63
+ | `PARTIAL` | part of it, e.g. the happy path without the error case | `citations`, and `note` saying what is missing |
64
+ | `ABSENT` | nothing implements it | `searched`: the terms that found nothing relevant |
65
+ | `UNCLEAR` | the code exists but its behaviour cannot be told from reading | `note` |
66
+
67
+ ```bash
68
+ node "$HOME/.claude/scripts/scenario-audit.mjs" verify --csv "<scenarios.csv>" \
69
+ --verdicts /tmp/ma-verdicts.json --repo "<repo>" --lang "<outputLanguage>"
70
+ ```
71
+
72
+ ## Step 4 - Report
73
+
74
+ Print the table `verify` produced, verbatim, and its count line. Then the
75
+ scenarios that moved to UNCLEAR during verification, with the reason. State
76
+ which verdicts rest on a resolved citation (mechanical) and that the reading of
77
+ the code behind them is judgement.
78
+
79
+ **Stop. No issue, no comment, no worktree.**
@@ -56,7 +56,10 @@ Or leave it: it exits on its own when idle.
56
56
  ## What it will not do
57
57
 
58
58
  There is no route that merges, marks ready, runs a command or starts a host.
59
- `POST /v1/launch` validates a launch request, writes it (0600) and returns the
60
- argv and environment `launch.json` declares; the client starts the process.
59
+ `POST /v1/launch` and `POST /v1/runs/{id}/resume` return the argv and
60
+ environment `launch.json` declares; the client starts the process.
61
61
  `POST /v1/runs/{id}/answer` accepts only an option the run's pending question
62
- offered.
62
+ offered. `POST /v1/runs/{id}/kill` and `POST /v1/gc` act only on a second
63
+ request carrying the single-use confirm token the first one returned, and a
64
+ kill never deletes the remote branch or the logs. Autopilot can be turned off
65
+ over HTTP, never on.
@@ -9,6 +9,13 @@ confirm: none
9
9
  allowed-tools: Bash, Read, Write, AskUserQuestion, WebFetch
10
10
  ---
11
11
 
12
+ ## Gotchas
13
+
14
+ - A token is read and written only through `~/.claude/lib/credential-store.sh`. Never echo it, never pass it on argv, never paste it back to the user.
15
+ - A mapping in `keychainMapping` with no value in the store is not onboarded: offer the Token Save Flow, do not ask for the secret in chat.
16
+ - Hosts are stored without a scheme (`jira.example.com`); the callers add `https://`.
17
+ - Publishing tokens differ by registry: npmjs takes an npm token, GitHub Packages a classic PAT with `write:packages` from the account that owns the scope.
18
+
12
19
  ## Step 0 - What is actually wrong
13
20
 
14
21
  ```bash
@@ -89,88 +96,7 @@ command -v pdftotext >/dev/null 2>&1 || echo "pdftotext: MISSING"
89
96
 
90
97
  ### Step 1 - Dynamic Credential Discovery
91
98
 
92
- Instead of checking only hardcoded key names, discover ALL user keys and intelligently map them to services. Uses `credential-store.sh list`:
93
-
94
- **1a. Discover all keys:**
95
- ```bash
96
- DISCOVERED=$(~/.claude/lib/credential-store.sh list 2>/dev/null | grep -i "^${USER}" | sort -u)
97
- echo "$DISCOVERED"
98
- ```
99
-
100
- **1b. Search keywords (per service):**
101
-
102
- Standard key names - the ones to use when creating a NEW key - live in `$HOME/.claude/multi-agent-refs/keychain.md` "Standard key names"; read the name for a service from there. Existing keys under other names are perfectly valid, which is what these keywords are for.
103
-
104
- | Service ID | Search Keywords |
105
- |------------|-----------------|
106
- | `jira` | `jira` |
107
- | `bitbucket_token` | `bitbucket` + (`token` or `access` or `pass`) |
108
- | `bitbucket_user` | `bitbucket` + (`user` or `name`) |
109
- | `github` | `github` or `gh` (exclude `ssh`) |
110
- | `confluence` | `confluence` |
111
- | `figma` | `figma` + (`token` or `pat` or `access`) + NOT `mcp` |
112
- | `figma_mcp` | `figma` + `mcp` |
113
- | `fortify` | `fortify` |
114
- | `graylog` | `graylog` |
115
- | `graylog_test` | `graylog` + `test` |
116
- | `firebase` | `firebase` (any variant: `sa`, `service`, `account`, `access`, `json`) |
117
- | `jenkins` | `jenkins` |
118
- | `appstore_connect_key_id` | (`appstore` or `asc` or `app_store`) + (`key` or `keyid`) |
119
- | `appstore_connect_issuer_id` | (`appstore` or `asc` or `app_store`) + `issuer` |
120
- | `appstore_connect_private_key` | (`appstore` or `asc` or `app_store`) + (`private` or `p8`) |
121
- | `appstore_connect_apple_id` | (`appstore` or `asc`) + (`apple` or `account` or `user`) |
122
- | `appstore_connect_password_item` | (`appstore` or `asc` or `altool`) + (`password` or `app_specific`) |
123
- | `google_play` | (`googleplay` or `google_play` or `play_console` or `play`) + (`service` or `account` or `access` or `json` or `console`), NOT `firebase` |
124
-
125
- > Multi-agent setup onboards **both** Figma tokens because the pipeline's 3-tier Figma access chain (see `$HOME/.claude/rules/figma-pipeline.md`) uses them in priority order: Tier 1 = MCP (`figma_mcp`), Tier 2 = REST PAT (`figma`), Tier 3 = user screenshot fallback. Missing either token forces a downshift; missing both leaves Tier 3 as the only path. The Tier 2 logical key is `figma`, not `figma_pat`: `figma_pat` is the pre-v13.6 name that `migrate-prefs.mjs` consolidates away, and writing a new mapping under it means the next migration deletes it.
126
-
127
- > The five App Store Connect entries are **iOS-only and optional** - skipping them all reports Gate 2 of `/multi-agent:store-ready` as `SKIPPED`, never as a pass. Two hold identifiers, one an email, one a keychain ITEM NAME, and `appstore_connect_private_key` the `.p8` itself; all go through the mapping layer. `google_play` is the Android-only counterpart (Step 3d). Tiers and mechanics: Step 3b and `$HOME/.claude/multi-agent-refs/setup/app-store-connect.md`.
128
-
129
- > The `firebase` entry is **optional and any-platform**. Discovery maps a stored service-account JSON like any other credential but cannot see what decides whether Crashlytics is readable: a fresh `firebase-adminsdk-*` account authenticates perfectly and holds no Crashlytics role. Step 3c measures the tier rather than assuming it.
130
-
131
- **1c. Resolution logic (per service):**
132
-
133
- For each service in the table above, follow this order:
134
-
135
- 1. **Check standard key** -> `~/.claude/lib/credential-store.sh get "<standard_key>" 2>/dev/null`
136
- - Found (non-empty stdout, exit 0) -> auto-map, done
137
- 3. **Search discovered keys** -> filter `$DISCOVERED` by the service's search keywords (case-insensitive)
138
- - Exactly 1 match -> show: `"Found '${matched_key}' for ${service} - use this? (enter=yes / n=skip)"` -> if yes, map it
139
- - Multiple matches -> show numbered list, user picks:
140
- ```
141
- Multiple keys found for GitHub:
142
- 1. ${USER}_Github
143
- 2. ${USER}_Github_Access_Token_Old
144
- 3. ${USER}_Github_Access_Token
145
- Select [number] or skip:
146
- ```
147
- - 0 keyword matches -> go to Step 4
148
- 4. **Suggest candidates from full keychain** -> When keyword search yields 0 results, do NOT immediately mark as MISSING. Show broad candidates from `$DISCOVERED_ALL` and ask the user:
149
- ```
150
- No exact match found for Jira in your keychain.
151
-
152
- These entries might be your Jira token - do any look right?
153
- 1. MyPersonalJiraToken
154
- 2. work_jira_pat
155
- 3. JiraPAT_2024
156
- n. None of these (skip)
157
-
158
- Select [number] or n to skip:
159
- ```
160
-
161
- Candidate selection:
162
- - Show entries that partially match the service name, common token suffixes (`token`, `pat`, `key`, `secret`, `access`, `password`), or relaxed keyword matching (substring instead of prefix)
163
- - Exclude entries already mapped to other services and system entries (Apple, com.apple.*, iCloud, etc.)
164
- - Cap at 10 candidates, sorted by relevance (shortest edit distance to service keywords)
165
- - If 0 candidates even after broad search -> MISSING (truly not in keychain)
166
-
167
- **Important:** Steps 3-4 search the FULL `$DISCOVERED` list (both passes from 1a), not just user-prefixed entries. This catches tokens saved under any naming convention.
168
-
169
- **1d. Check preferences for existing mapping:**
170
-
171
- Before running discovery, check `prefs.global.keychainMapping`. If a mapping already exists for a service AND the mapped key still exists in Keychain -> skip discovery for that service (show as already mapped from preferences).
172
-
173
- If a previously mapped key NO LONGER exists in Keychain -> clear the stale mapping, re-run discovery for that service.
99
+ Full procedure: `$HOME/.claude/multi-agent-refs/setup/discovery.md`. Read it for Step 1.
174
100
 
175
101
  ### Step 2 - Show Discovery Summary + Save Mapping
176
102
 
@@ -294,131 +220,7 @@ Loop rules:
294
220
 
295
221
  ### Token Save Flow (reusable)
296
222
 
297
- This flow is used in TWO contexts:
298
- - **Setup Step 4** - for missing tokens during first-time onboarding
299
- - **Phase 0 token pre-check** - when a token is missing or expired (401/403) at runtime
300
-
301
- **Trigger**: token missing (`keychainMapping` is `null`) OR token expired (API returned 401/403).
302
-
303
- **Step A - Ask** (options depend on whether the token is missing or expired):
304
-
305
- Missing token (first-time / unmapped):
306
- ```
307
- {Service} token missing.
308
- Where to get it: {source URL/instructions}
309
-
310
- [1] Add now - I'll generate the token and copy it
311
- [2] Skip - I'll set it up later
312
-
313
- Select:
314
- ```
315
-
316
- Expired / rejected token (401 / 403 mid-run) - the Expired-token decision from `$HOME/.claude/multi-agent-refs/keychain.md` Rule 1:
317
- ```
318
- {Service} token expired (the service returned 401/403).
319
- Where to get a fresh one: {source URL/instructions}
320
-
321
- [1] Regenerate - replace {KEY_NAME} in place, then retry
322
- [2] Use a different token - map another Keychain entry, then retry
323
- [3] Skip and continue - drop this source (halts only if the token is required for the input)
324
-
325
- Select:
326
- ```
327
-
328
- Render `question` + `label` + `description` in `outputLanguage`; `header` English. Names below are option semantics, not strings to print. The picked option is a choice, never the secret: the value enters via Step B clipboard.
329
-
330
- - **Skip** (missing `[2]` / expired `[3]`) → skip semantics. During setup: `keychainMapping` stays `null`. During Phase 0 / mid-run: abort that service's contribution, warn and continue if non-critical, halt if critical (e.g. Jira token for Jira input).
331
- - **Add now** / **Regenerate** → proceed to Step B (clipboard save). Regenerate reuses the same `{KEY_NAME}`.
332
- - **Use a different token** → proceed to Step B, then re-run Step C identity binding for the new entry.
333
-
334
- **Step B - Clipboard save** (token NEVER appears in terminal):
335
-
336
- For PAT / API key / username:
337
- ```
338
- Copy the token to your clipboard, then press Enter.
339
- (Token will be read from clipboard and saved to Keychain automatically)
340
-
341
- Press Enter when ready...
342
- ```
343
-
344
- Pipeline runs silently - value is piped via stdin (`-` sentinel) so it never lands on argv / shell history:
345
- ```bash
346
- pbpaste | ~/.claude/lib/credential-store.sh set "<KEY_NAME>" -
347
- pbcopy < /dev/null
348
- ```
349
-
350
- (The shell driver auto-delegates to `~/.claude/scripts/keychain.py`, which writes both `-l` (label) and `-s` (service) attributes so callers using either convention find the same entry.)
351
-
352
- For JSON file (Firebase) - same clipboard flow, JSON content never lands in argv or shell history:
353
- ```
354
- Open the Service Account JSON, copy its FULL contents to your clipboard,
355
- then press Enter.
356
- (Contents are saved to the Keychain exactly as issued)
357
-
358
- Press Enter when ready...
359
- ```
360
-
361
- The pipeline then runs the same `pbpaste | ... set "<KEY_NAME>" -` and `pbcopy < /dev/null` as above. A key that arrives as a file (the App Store Connect `.p8`, the Google Play JSON) skips the clipboard: `set <key> - < <file>`.
362
-
363
- **Firebase repeats per project.** Teams own several Firebase projects (legacy plus redesign, staging plus prod), each with its own key, and a crash URL from the second one used to fail the `project_id` check as if it were misconfigured. After each saved key, read `project_id` from the stored JSON (never ask) and offer another round: `Saved: <project_id>. Add another Firebase project? [y/N]`.
364
-
365
- - Every key appends `{projectId, keychainKey, label?}` to `prefs.global.firebase.accounts`; the first one also fills `keychainMapping.firebase`, so a one-project setup is unchanged.
366
- - Keys after the first are named `${USER}_Firebase_Access_Json_<projectId>` so they cannot collide.
367
- - At run time `fetch-crashlytics.sh` picks the account matching the console URL's projectId, falling back to `keychainMapping.firebase`.
368
-
369
- For GitHub (special case):
370
- ```
371
- ! gh auth login
372
- ```
373
-
374
- **Step C - Identity binding** (after token saved):
375
-
376
- ```
377
- ✓ Saved to Keychain as <KEY_NAME>
378
- ✓ Clipboard cleared
379
-
380
- Which git identity uses this token?
381
-
382
- Existing identities:
383
- 1. Ada Lovelace <ada@example.com>
384
- 2. Ada Lovelace <ada@personal.com>
385
- n. Create new identity
386
-
387
- Select:
388
- ```
389
-
390
- - Existing identity selected → add `{service}: <KEY_NAME>` to that identity's `servicePatMap`
391
- - `n` (create new) → ask name + email → create identity → add to `prefs.global.identities[]` → map token
392
- - First token ever (no identities exist) → skip picker, go straight to name + email
393
- - `bitbucket_user` is excluded from identity binding (it's a username, not a PAT)
394
-
395
- **Step D - Confirm + update**:
396
-
397
- ```
398
- ✓ Token mapped to identity: Ada Lovelace <ada@example.com>
399
- ```
400
-
401
- Update `prefs.global.keychainMapping.{service}` with the key name.
402
- Update `identity.servicePatMap.{service}` with the key name.
403
- Update `serviceStatus.{service} = { ok: true, checkedAt: <now> }`.
404
-
405
- **→ Next: if `{service}` is `jira` / `confluence` / `bitbucket` / `fortify` / `graylog` AND the corresponding
406
- `prefs.global.hosts.{service}` is unset, run Step 3.5 (Host Prompt) inline before
407
- the Auto-routing rule below. required - the pipeline cannot build API URLs without
408
- the host. Firebase is exempt (see Step 3.5).**
409
-
410
- **Auto-routing rule** (optional, on first token per platform):
411
-
412
- If `platformIdentityRouting` has no rule for this platform yet, auto-suggest one:
413
- ```
414
- Auto-add routing rule?
415
- bitbucket.example.com/* → Ada Lovelace <ada@example.com>
416
- [enter=yes / n=skip]
417
- ```
418
-
419
- This builds `platformIdentityRouting` incrementally - no separate Step 7 needed for most users.
420
-
421
- ---
223
+ Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for every token prompt (Steps 3, 3b, 3c and any command that saves a token).
422
224
 
423
225
  ### Step 3b - App Store Connect onboarding (iOS only, optional)
424
226
 
@@ -434,81 +236,7 @@ Runs inside Step 3, only when the target repo is Android. One entry, `google_pla
434
236
 
435
237
  ### Step 3.5 - Host Prompt (embedded in Token Save Flow)
436
238
 
437
- **Not a standalone step** - runs inline at the end of the Token Save Flow whenever the saved token belongs to a **hosted service** (Jira, Confluence, Bitbucket, Fortify, Graylog) AND the host is not yet in `prefs.global.hosts`. Firebase tokens skip this step - Crashlytics is always on Google's fixed domains and `project_id` is embedded in the service-account JSON.
438
-
439
- Right after Step D (identity mapping confirmed), ask:
440
-
441
- ```
442
- Service host - needed to build API URLs for this token.
443
-
444
- {Service} host (e.g. jira.example.com): ___
445
- ```
446
-
447
- Save to `prefs.global.hosts.{service}`. For Fortify, also ask `Fortify project version ids (optional, comma-separated - e.g. 1234,5678)` → `prefs.global.fortify.versionIds`. A ticket naming only an instance id carries no version, so the lookup silently no-ops without these; URL-referenced findings resolve either way.
448
-
449
- For Jira, **discover the project keys instead of asking the user to recall them.** The token is already saved and the host is already known, so ask Jira which projects this person actually works in - a corporate instance has thousands of projects, and a typed key is a typo waiting to route branches and new issues at the wrong board:
450
-
451
- ```bash
452
- printf 'Authorization: Bearer %s\n' "$TOKEN" | curl -s -H @- \
453
- "https://{JIRA_HOST}/rest/api/2/search?jql=assignee%3DcurrentUser()%20OR%20reporter%3DcurrentUser()%20ORDER%20BY%20updated%20DESC&fields=project&maxResults=100" \
454
- | jq -r '[.issues[].fields.project | "\(.key)\t\(.name)"] | unique | .[]'
455
- ```
456
-
457
- Present the distinct keys, most-recently-worked first, as a picker; fall back to the free-text prompt `Default Jira project key (e.g. PROJ)` when the call fails or returns nothing (no VPN, fresh account). The picked key → `prefs.global.defaultJiraKey`. From the Jira host, derive `corpDomain` (`jira.example.com` → `example.com`) and pre-fill it so the Confluence / Bitbucket prompts only need the subdomain.
458
-
459
- `defaultJiraKey` is a single global fallback, but one Jira host usually serves several repos with DIFFERENT keys, so the pass continues with a per-repo mapping. Show the repos, and let the key come from the discovered list rather than being typed again:
460
-
461
- ```
462
- Per-repo Jira keys (optional) - repos whose project key differs from {defaultJiraKey}:
463
-
464
- [ ] 1. my-ios-app (current: PROJA)
465
- [ ] 2. my-other-app (current: - )
466
-
467
- Toggle repos, then pick a project for each - discovered: PROJA, PROJB, PROJC. Enter to skip.
468
- ```
469
-
470
- - The repo list comes from `prefs.projects` + `recentProjects` (when Step 5 already ran); a free-text repo path is accepted for repos not discovered yet, and a free-text key for a project the search did not surface.
471
- - Each answer is PREPENDED to `prefs.projects[{slug}].jiraProjectKeys` (deduped, max 10 per schema). Example: `my-ios-app` → `PROJA`, `my-other-app` → `PROJB` - two repos on the same Jira host, two different project keys.
472
- - Resolution order everywhere a Jira key is needed (placeholder replacement, branch names, new-issue creation): `prefs.projects[{slug}].jiraProjectKeys[0]` first, `global.defaultJiraKey` as fallback.
473
- - **Re-run / update**: `/multi-agent:setup jira-keys` re-opens only this mapping without touching tokens or hosts.
474
-
475
- Resulting shape:
476
-
477
- ```json
478
- {
479
- "global": {
480
- "hosts": {
481
- "jira": "jira.example.com",
482
- "confluence": "confluence.example.com",
483
- "bitbucket": "bitbucket.example.com",
484
- "fortify": "ssc.example.com",
485
- "graylog": "graylog.example.com",
486
- "graylogTest": "graylog-test.example.com",
487
- "corpDomain": "example.com"
488
- },
489
- "defaultJiraKey": "PROJ"
490
- }
491
- }
492
- ```
493
-
494
- Placeholders `{JIRA_HOST}`, `{CONFLUENCE_HOST}`, `{BITBUCKET_HOST}`, `{FORTIFY_HOST}`, `{GRAYLOG_HOST}`, `{GRAYLOG_TEST_HOST}`, `{CORP_DOMAIN}`, `{JIRA_KEY}` in skills/commands are resolved from this block at runtime. If a host is ever missing when a phase needs it, Phase 0 prompts the same Host Prompt inline.
495
-
496
- Graylog uses a **PAT** whose API auth is HTTP Basic with the token as username and the literal `token` as password - no separate username entry. It is optional by the null-mapping convention: `keychainMapping.graylog` or `hosts.graylog` left `null` degrades the log fetch to empty and never blocks a run.
497
-
498
- Graylog is asked **twice** - test and production are separate instances, and a tester-minted trx id does not exist in production. After the production host:
499
-
500
- ```
501
- Graylog test host (optional - Enter to skip): ___
502
- Does the test instance use a different token? [y/N]
503
- ```
504
-
505
- Test host → `hosts.graylogTest` (`{GRAYLOG_TEST_HOST}`); skipped means production-only search, which degrades nothing. Yes to the token question runs one more Token Save Flow pass for `graylog_test`; no (default) leaves it null and the fetcher reuses the production key. Run-time order is `--env auto`: production first, test on empty or unreachable, and the payload names which answered.
506
-
507
- **Re-run / update**: `/multi-agent:setup hosts` re-opens the prompt to edit values without touching tokens.
508
-
509
- Team-sharing note: Hosts are the only corporate metadata the pipeline needs. Tokens live in macOS Keychain (encrypted, never on disk inside the repo). Preferences file lives in `~/.claude/` - fully outside the repo clone. A teammate cloning the repo runs `/multi-agent:setup` once; host + token prompts run naturally together.
510
-
511
- ---
239
+ Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for the host question inside the Token Save Flow.
512
240
 
513
241
  ### Step 3.6 - Per-account host overrides (optional)
514
242
 
@@ -635,64 +363,7 @@ Repo identifiers in the label are the human label from `recentProjects` (basenam
635
363
 
636
364
  ### Step 7 - Platform Identity Routing (optional)
637
365
 
638
- Map repo URL **glob patterns** to a named identity from `prefs.global.identities`. Phase 0 consults this map in Step 5 to auto-pick the git author and the right `servicePatMap` for the target repo - preventing corporate identity leakage into personal repos and vice versa.
639
-
640
- Auto-skipped if `identities` has fewer than 2 entries (single-identity case has nothing to route).
641
-
642
- **9a. Auto-suggest from `servicePatMap` ownership**
643
-
644
- For each identity, derive a default routing rule from where its PATs work:
645
- - Identity owns `bitbucket` PAT → propose `<bitbucket-host>/*` glob, mapped to that identity.
646
- - Identity owns `github` PAT → propose `github.com/<gh-username>/*` if known (from `identities[].username`), else `github.com/*`.
647
- - Identity owns `confluence` / `jira` only → no URL routing applies (those aren't repo origins) - skip.
648
-
649
- Auto-suggestions are **proposals**, not forced. User confirms or edits each one.
650
-
651
- **9b. Confirm or edit each suggested rule**
652
-
653
- ```
654
- Step 7 - Platform Identity Routing (optional)
655
- Auto-suggested rules:
656
-
657
- 1. bitbucket.{corp-domain}/* -> corporate [confirm/edit/skip]
658
- 2. github.com/{personal-username}/* -> personal [confirm/edit/skip]
659
- 3. github.com/{org-name}/* -> corporate [confirm/edit/skip]
660
-
661
- Add another rule? [Add another / Done]
662
- ```
663
-
664
- Each rule answer:
665
- - `Enter` or `c` → confirm
666
- - `e` → edit (prompt for new glob and/or new identity name)
667
- - `s` → skip this rule
668
- - `n` (final question) → finish
669
-
670
- **9c. Save**
671
-
672
- ```json
673
- {
674
- "global": {
675
- "platformIdentityRouting": {
676
- "bitbucket.{corp-domain}/*": "corporate",
677
- "github.com/{personal-username}/*": "personal",
678
- "github.com/{org-name}/*": "corporate"
679
- }
680
- }
681
- }
682
- ```
683
-
684
- Glob matching semantics (Phase 0 implementation):
685
- - `*` matches any characters except `/`
686
- - `**` matches any characters including `/`
687
- - Most-specific match wins (longer literal prefix > shorter)
688
- - No match → Phase 0 falls back to the interactive identity picker
689
-
690
- **9d. Skip / degrade rules**
691
-
692
- - Zero rules saved is valid - Phase 0 always falls back to the identity picker.
693
- - A rule may point to an identity name that doesn't (yet) exist in `identities`; on Phase 0 lookup, an unknown identity name surfaces as a warning and the picker is shown.
694
- - Step 7 is idempotent - re-running merges new rules; existing rules are preserved unless the user explicitly edits them.
695
- - Routing is **advisory**: the user can always override the auto-picked identity in Phase 0.
366
+ Full procedure: `$HOME/.claude/multi-agent-refs/setup/identity-routing.md`. Read it for Step 7.
696
367
 
697
368
  ### Cross-Platform Notes (Step 1-9)
698
369
 
@@ -729,31 +400,7 @@ pbpaste | ~/.claude/scripts/keychain.py set "<SERVICE_NAME>" -
729
400
 
730
401
  ### Figma MCP Setup (Remote / Local question)
731
402
 
732
- The `figma_mcp` pass of the Step 3 loop opens with a mode question BEFORE any token is collected:
733
-
734
- ```
735
- Figma MCP mode?
736
-
737
- [1] Remote - mcp.figma.com, OAuth token (figu_) (recommended)
738
- [2] Local - @anthropic-ai/figma-mcp via npx, uses the Figma PAT
739
- ```
740
-
741
- **Remote** (`figu_` OAuth token - generate it FOR the current user, never just point at docs):
742
- - No OAuth app and no client_id/secret needed: Dynamic Client Registration against `api.figma.com/v1/oauth/mcp/register` + PKCE, the browser opens, the user clicks Allow, and the resulting access + refresh token pair is saved to the credential store under a name the user confirms. Map that entry to `keychainMapping.figma_mcp` (Token Save Flow Step D applies as usual).
743
- - If `prefs.global.figmaMcp.remoteGeneratorScript` is set, run that script - it drives the whole flow end to end (registration, browser, keychain save) for the current user. Otherwise guide the flow inline.
744
- - Renewal is silent afterwards via `$HOME/.claude/lib/figma-mcp-refresh.sh` (refresh token). Never echo token values.
745
-
746
- **Local** (PAT-based):
747
- - Validates the Figma PAT against the REST API, saves it to the credential store (reusing the `figma` mapping when present), and writes the `@anthropic-ai/figma-mcp` server block into Claude Code `settings.json` `mcpServers`:
748
- ```bash
749
- # stdin sentinel keeps the value out of shell history
750
- pbpaste | ~/.claude/scripts/keychain.py set "${USER}_Figma_Access_Token" -
751
- pbcopy < /dev/null
752
- # then: ~/.claude/settings.json -> mcpServers -> figma
753
- ```
754
- - If `prefs.global.figmaMcp.localGeneratorScript` is set, run that script instead.
755
-
756
- Choosing Remote does NOT skip the `figma` PAT pass (Tier 2 still uses the PAT); choosing Local leaves `keychainMapping.figma_mcp` null and Tier 1 unavailable until Remote is onboarded.
403
+ Full procedure: `$HOME/.claude/multi-agent-refs/setup/figma.md`. Read it for the Figma MCP question.
757
404
 
758
405
  ### Security Rules
759
406
 
@@ -5,6 +5,8 @@ parameters: []
5
5
  gui: button
6
6
  destructive: false
7
7
  confirm: none
8
+ context: fork
9
+ agent: Explore
8
10
  ---
9
11
 
10
12
  # multi-agent status - Task Status Dashboard