@mmerterden/multi-agent-pipeline 20.20.0 → 20.22.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 (68) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +24 -13
  3. package/README.tr.md +21 -10
  4. package/docs/adr/0017-change-impact-from-the-graph.md +69 -0
  5. package/docs/adr/README.md +1 -0
  6. package/docs/ecosystem.md +7 -5
  7. package/docs/facts.json +6 -4
  8. package/docs/features.md +1 -0
  9. package/install/catalog-history.json +1 -1
  10. package/install/templates/copilot-instructions.md +1 -0
  11. package/manifest.json +71 -64
  12. package/package.json +1 -1
  13. package/pipeline/commands/multi-agent/SKILL.md +1 -1
  14. package/pipeline/commands/multi-agent/review/SKILL.md +2 -1
  15. package/pipeline/commands/multi-agent/route-on/SKILL.md +32 -8
  16. package/pipeline/commands/multi-agent/route-status/SKILL.md +12 -2
  17. package/pipeline/commands/multi-agent/setup/SKILL.md +8 -16
  18. package/pipeline/lib/model-dispatch.sh +72 -24
  19. package/pipeline/lib/outbound-gate.mjs +2 -0
  20. package/pipeline/lib/route-state.sh +118 -10
  21. package/pipeline/lib/toolkit-llm.sh +30 -0
  22. package/pipeline/lib/unattended-profile-check.mjs +23 -2
  23. package/pipeline/multi-agent-refs/_dev-context.md +15 -0
  24. package/pipeline/multi-agent-refs/analysis/evidence.md +7 -3
  25. package/pipeline/multi-agent-refs/analysis/locked.md +1 -1
  26. package/pipeline/multi-agent-refs/cross-cli-contract.md +9 -3
  27. package/pipeline/multi-agent-refs/features/code-graph.md +27 -0
  28. package/pipeline/multi-agent-refs/features/doctor.md +11 -0
  29. package/pipeline/multi-agent-refs/features/free-models.md +111 -0
  30. package/pipeline/multi-agent-refs/features/model-fallback.md +21 -15
  31. package/pipeline/multi-agent-refs/features/product-context.md +238 -0
  32. package/pipeline/multi-agent-refs/features/unattended-security.md +4 -2
  33. package/pipeline/multi-agent-refs/knowledge.md +2 -0
  34. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +7 -12
  35. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
  36. package/pipeline/multi-agent-refs/phases/phase-3-review.md +7 -6
  37. package/pipeline/multi-agent-refs/platform-parity.md +23 -9
  38. package/pipeline/multi-agent-refs/setup/free-models.md +22 -0
  39. package/pipeline/multi-agent-refs/setup/token-save-flow.md +24 -0
  40. package/pipeline/preferences-template.json +1 -0
  41. package/pipeline/schemas/agent-state.schema.json +31 -0
  42. package/pipeline/schemas/analysis-spec.schema.json +14 -0
  43. package/pipeline/schemas/code-graph.schema.json +12 -1
  44. package/pipeline/schemas/diff-risk.schema.json +2 -1
  45. package/pipeline/schemas/prefs.schema.json +68 -1
  46. package/pipeline/schemas/route-config.schema.json +33 -8
  47. package/pipeline/schemas/secret-patterns.json +14 -0
  48. package/pipeline/scripts/_code-graph.mjs +76 -3
  49. package/pipeline/scripts/_diff-impact.mjs +312 -0
  50. package/pipeline/scripts/bulk-read.sh +98 -12
  51. package/pipeline/scripts/capture-flush.sh +58 -3
  52. package/pipeline/scripts/cost-table.json +9 -1
  53. package/pipeline/scripts/diff-risk-score.mjs +80 -9
  54. package/pipeline/scripts/doctor.mjs +100 -0
  55. package/pipeline/scripts/graph-affected.mjs +167 -36
  56. package/pipeline/scripts/graph-query.mjs +16 -4
  57. package/pipeline/scripts/pre-commit-check.sh +1 -1
  58. package/pipeline/scripts/product-context.mjs +539 -0
  59. package/pipeline/scripts/smoke-cross-cli-behavior.sh +39 -1
  60. package/pipeline/scripts/unattended_policy.py +20 -0
  61. package/pipeline/scripts/validate-code-graph.mjs +2 -1
  62. package/pipeline/scripts/validate-diff-risk.mjs +1 -0
  63. package/pipeline/skills/.skill-manifest.json +6 -6
  64. package/pipeline/skills/shared/core/multi-agent/SKILL.md +2 -0
  65. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +5 -1
  66. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +31 -7
  67. package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +12 -2
  68. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +9 -6
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-11T20:10:05Z",
3
+ "generatedAt": "2026-10-12T21:38:23Z",
4
4
  "skillCount": 228,
5
5
  "entries": [
6
6
  {
@@ -165,7 +165,7 @@
165
165
  },
166
166
  {
167
167
  "path": "shared/core/multi-agent-review/SKILL.md",
168
- "sha256": "2b6934d6086a467bdf145b326061ab4b83d5479bfb1a2fb36420ff8012a02e5d"
168
+ "sha256": "1a22618e6d3d9d07b267bd61fc591bb33726e1d7ef8567285401f61bc7be0ad5"
169
169
  },
170
170
  {
171
171
  "path": "shared/core/multi-agent-route-off/SKILL.md",
@@ -173,11 +173,11 @@
173
173
  },
174
174
  {
175
175
  "path": "shared/core/multi-agent-route-on/SKILL.md",
176
- "sha256": "a807767460b09455087d48a7dd45036be788f67997475360acab29f2422f425b"
176
+ "sha256": "97c76d711454e6bc9edfd47344bbeab7f73cf72c116cca92cffacdcda7fe96b1"
177
177
  },
178
178
  {
179
179
  "path": "shared/core/multi-agent-route-status/SKILL.md",
180
- "sha256": "b473b670b3f8535b295752eb5aed8b01cba8d1ed6763ae4d80d9cc2dbb1f7794"
180
+ "sha256": "869689dbf84edece67168a892a61b51459ff6c15cbf7dafe40c2b774f875b9f0"
181
181
  },
182
182
  {
183
183
  "path": "shared/core/multi-agent-routines/SKILL.md",
@@ -213,7 +213,7 @@
213
213
  },
214
214
  {
215
215
  "path": "shared/core/multi-agent-setup/SKILL.md",
216
- "sha256": "427df811e5130da1ab6e23ff78202eb9134fb76bcd601924fba5668cbd630158"
216
+ "sha256": "79a4afa655df12221a25bc386a32e61c38016d2de660dd618b404ca8bb0b28d3"
217
217
  },
218
218
  {
219
219
  "path": "shared/core/multi-agent-stack/SKILL.md",
@@ -269,7 +269,7 @@
269
269
  },
270
270
  {
271
271
  "path": "shared/core/multi-agent/SKILL.md",
272
- "sha256": "3dd44ccc00e41c09e59ad223900a391f80158bd3f69e45d67c684285bc42418d"
272
+ "sha256": "a39f712426638e7955db9171c950be720f11c861621884e628c81a0b6a49de5d"
273
273
  },
274
274
  {
275
275
  "path": "shared/external/accessibility-compliance-accessibility-audit/SKILL.md",
@@ -122,6 +122,8 @@ export CLAUDE_CODE_SUBAGENT_MODEL="$resolved_model"
122
122
 
123
123
  **Precedence:** per-dispatch `PHASE_MODEL_OVERRIDE` > `prefs.global.modelRouting` rule > persona `preferredModel` > global default (`opus`). Routing here is Anthropic-only: features/model-fallback.md "Routing at dispatch".
124
124
 
125
+ **Simple text tasks (`delegate`):** before summarizing a log or document, extracting fields, labelling or drafting a translation or commit body in-session, ask `"$HOME/.claude/lib/model-dispatch.sh" delegate --default host`. `free` means call `llm_delegate`; `ESCALATE_TO_CLAUDE` or any other answer means do it in-session. Never for code, plans, reviews or triage. Task list and rules: `$HOME/.claude/multi-agent-refs/features/free-models.md`.
126
+
125
127
  **Observability:** emit `phase.agent.dispatch` OTel span with `{persona, resolved_model, override_source}` attributes when `MULTI_AGENT_OTEL_SPANS=1` (see `phase-tracker.sh`).
126
128
 
127
129
  ## Skill loading and injection
@@ -76,7 +76,11 @@ Skip Phase 0-3 and review a diff only. Input shapes: a PR (`#N`, `repo#N`, GitHu
76
76
  resolves whose `stack` is the other mobile platform and the diff touches a screen, a
77
77
  service, a request model or a localization file, compare the change against that repo
78
78
  on four axes: endpoints called, parameters sent, business rules around the call,
79
- localization keys used. The counterpart is resolved automatically and in both
79
+ localization keys used. When the project belongs to a product
80
+ (`prefs.global.products`), the counterparts are the product's other repositories,
81
+ resolved with `product-context.mjs refs` and compared at their latest integration
82
+ branch through the toolkit's `repo_*` tools, pinned to a sha
83
+ (`features/product-context.md`). Otherwise the counterpart is resolved automatically and in both
80
84
  directions (ios ↔ android) from four sources in this order, first hit wins:
81
85
  `--with <path|owner/repo>` (a one-off override, remembered like any other resolution),
82
86
  then a remembered `prefs.projects[<slug>].counterpartRoots[]`, then the primary
@@ -2,7 +2,7 @@
2
2
  name: multi-agent-route-on
3
3
  description: "Enable policy-driven model routing: pick a strategy, a scope, and the rules that say which rung a call lands on. Use when asked to turn model routing on."
4
4
  user-invocable: true
5
- argument-hint: "[--strategy=manual|task-fit|cost-ceiling] [--scope=subagent,bulk-read,research]"
5
+ argument-hint: "[--free [--allow-training] | --no-free] [--strategy=manual|task-fit|cost-ceiling] [--scope=subagent,bulk-read,delegate,research]"
6
6
  metadata:
7
7
  language: en
8
8
  ---
@@ -24,7 +24,8 @@ Routing ships **off**. This is the command that turns it on, and it writes to
24
24
  ```
25
25
 
26
26
  Ordered, first match wins. `when` matches on `persona`, `phase` (0..5) or
27
- `taskKind`; `prefer` lists rungs in descending preference.
27
+ `taskKind`; `prefer` lists rungs in descending preference. `free` is a rung too,
28
+ honoured only at `bulk-read` and `delegate` and only while `--free` is on.
28
29
 
29
30
  **Rung names are the contract; model ids are not.** `opus` is a rung here and a
30
31
  model id in `cost-table.json`, and the second can change without anyone editing
@@ -37,18 +38,41 @@ Set rules with:
37
38
  bash "$HOME/.claude/lib/route-state.sh" set-rules path/to/rules.json
38
39
  ```
39
40
 
41
+ ## Free models: `--free`
42
+
43
+ ```bash
44
+ bash "$HOME/.claude/lib/route-state.sh" on --free
45
+ ```
46
+
47
+ Layer 2. Simple text work the pipeline does itself - a large-file read, a log or
48
+ document summary, field extraction, a label, a translation or commit-body draft -
49
+ goes to the multi-agent-toolkit's verified free-model chain first. Every answer
50
+ is checked against its source before it is used; when none passes, Claude does
51
+ the task as before. Decisions, plans, code, reviews and triage never leave Claude.
52
+
53
+ `--free` turns on `modelRouting.free`, adds `bulk-read` and `delegate` to the
54
+ scope, and lists which providers are usable. With none, it says exactly which key
55
+ to add: one free Groq key is enough. `--allow-training` also admits free tiers
56
+ that may train on prompts; leave it off for corporate code and tickets.
57
+ `--no-free` turns only the free chain off. Full contract, the task list for
58
+ development and analysis, and unattended behaviour:
59
+ `$HOME/.claude/multi-agent-refs/features/free-models.md`.
60
+
40
61
  ## Strategies
41
62
 
42
63
  | Strategy | What it does |
43
64
  |---|---|
44
65
  | `manual` | only the explicit rules apply, nothing is inferred. The default, because a router that guesses is a router nobody can predict |
45
- | `task-fit` | a rule may match on `taskKind`, and the cheapest rung clearing it is chosen |
46
- | `cost-ceiling` | rungs downgrade as the run approaches `budgetCeilingUsd` |
66
+ | `task-fit` | the matched rule's rungs are tried cheapest first (cost-table prices, `free` first) |
67
+ | `cost-ceiling` | the rule's order holds until the run reaches the warn threshold of `budgetCeilingUsd`, then the cheapest rung is tried first |
68
+
69
+ `set-rules` checks every rule against the schema and the cost table and writes
70
+ nothing if one fails: an unknown rung, a phase outside 0-5, an unknown key.
47
71
 
48
72
  ## Scope, and the value that is not in it
49
73
 
50
74
  `scope` names the call sites routing may act on: `subagent`, `bulk-read`,
51
- `research`. Every one of them is a call **this pipeline makes itself**.
75
+ `delegate`, `research`. Every one of them is a call **this pipeline makes itself**.
52
76
 
53
77
  There is no `host-session` value, and that absence is enforced by that schema
54
78
  rather than written as advice. Routing a host session means rewriting the CLI's
@@ -61,8 +85,8 @@ Passing `--scope=host-session` is refused with that reason, not ignored.
61
85
 
62
86
  On Claude Code a subagent cannot be dispatched to a non-Anthropic model: subagent
63
87
  dispatch belongs to the host, not to us. So Phase 1, 2 and 3 personas stay inside
64
- the Anthropic ladder no matter what the rules say, and external providers apply
65
- only at `bulk-read` and `research`, where the pipeline makes the HTTP call.
88
+ the Anthropic ladder no matter what the rules say, and the `free` rung applies
89
+ only at `bulk-read` and `delegate`, where the pipeline makes the call itself.
66
90
 
67
91
  This is printed by `route-status` on every invocation instead of living in a doc,
68
92
  because the question it answers - "routing is on, why is the reviewer still on
@@ -28,13 +28,23 @@ A disabled router with rules is deliberately not reported as "off" alone: that
28
28
  reads as "unconfigured" and sends the user through `route-on`'s questions a
29
29
  second time.
30
30
 
31
+ ## Free models and what they saved
32
+
33
+ With `route-on --free`, status also prints `free: true` with its data policy,
34
+ where the free chain answers first (`bulk-read`, `delegate`), and the last seven
35
+ days from the toolkit's usage log: tasks answered free and verified, answers
36
+ served from cache, tasks handed back to Claude, and the input and output tokens
37
+ kept off Claude with an estimated saving at haiku rates. The estimate is labelled
38
+ as one: it prices the tokens at the rung the task would otherwise have used.
39
+
31
40
  ## The limit, printed every time
32
41
 
33
42
  On Claude Code a subagent cannot be sent to a non-Anthropic model. Subagent
34
43
  dispatch belongs to the host; the pipeline asks for a persona and the host
35
44
  decides what answers. So Phase 1, 2 and 3 personas stay inside the Anthropic
36
- ladder whatever the rules say, and an external provider is only reachable where
37
- the pipeline makes the HTTP call itself - `bulk-read.sh` and `research_ask`.
45
+ ladder whatever the rules say, and a free model answers only where the pipeline
46
+ makes the call itself - `bulk-read.sh` and the `delegate` call site - and only
47
+ after the toolkit verified its answer against the source.
38
48
 
39
49
  This paragraph is output, not documentation, because the alternative is the
40
50
  question arriving later as "routing is on but the reviewer is still on Opus, is
@@ -24,6 +24,10 @@ node "$HOME/.copilot/scripts/doctor.mjs"
24
24
 
25
25
  Run it before the first question and again at the end. The first run makes setup targeted: never ask for a token that is already mapped and answering. The second run is how setup ends - "setup complete" is a claim, and the doctor's exit code is the evidence. Report both in `outputLanguage`; if the second run still shows a BLOCK, say so plainly rather than closing on the word "complete".
26
26
 
27
+ ## Sections
28
+
29
+ `/multi-agent-setup hosts`: the Step 3.5 host prompt per mapped hosted service, then Token Save Flow Step 3.7 per mapped GitHub/Bitbucket token. `accounts`: Step 3.6. `jira-keys`: the Jira key mapping. Tokens are left alone.
30
+
27
31
  ## Setup (Credential Store + Git Identity Onboarding)
28
32
 
29
33
  Uses `~/.copilot/lib/credential-store.sh` to read/write secrets in the macOS Keychain (`security`, built in); the pipeline is macOS only (ADR-0012). Run `~/.copilot/lib/credential-store.sh doctor` first - it prints the platform and whether the backend is usable. The shell driver auto-delegates `get`/`set`/`delete` to the deterministic Python helper at `$HOME/.copilot/scripts/keychain.py` (Python 3 stdlib only, no external deps). The Python path writes both `-l` (label) and `-s` (service) attributes so items are findable regardless of how callers look them up. Set `KEYCHAIN_DELEGATE=0` to force the raw shell path.
@@ -189,11 +193,12 @@ The Step 2 discovery summary is never the end of setup. Immediately after showin
189
193
  10. `jenkins`
190
194
  11. App Store Connect block (Step 3b; only when the target repo is iOS)
191
195
  12. Google Play block (Step 3d; only when the target repo is Android)
196
+ 13. Free-model keys `llm-<id>` (only after `route-on --free`): `$HOME/.claude/multi-agent-refs/setup/free-models.md`
192
197
 
193
198
  Loop rules:
194
199
 
195
200
  - **One prompt per service.** Never collapse the list into a single "add missing tokens now?" yes/no, and never offer one multi-select covering all services: each service has its own source URL, key name, identity binding and host prompt, so each gets its own Token Save Flow pass.
196
- - **Each service pass asks, in order: token → author → host.** Step A/B collect the secret, Step C binds the git identity (author) - Bitbucket and GitHub included; every saved token gets an author - and Step 3.5 asks the host domain inline for hosted services (jira, confluence, bitbucket, fortify, graylog) - plus the Fortify project versions and the optional Graylog test instance. GitHub and Figma skip the host question (fixed domains); `bitbucket_user` skips author binding (username, not a PAT). Never end a service pass with the token saved but the author or a required host unasked.
201
+ - **Each service pass asks, in order: token → author → host → read binding (GitHub, Bitbucket; Token Save Flow Step 3.7).** Step A/B collect the secret, Step C binds the git identity (author) - Bitbucket and GitHub included; every saved token gets an author - and Step 3.5 asks the host domain inline for hosted services (jira, confluence, bitbucket, fortify, graylog) - plus the Fortify project versions and the optional Graylog test instance. GitHub and Figma skip the host question (fixed domains); `bitbucket_user` skips author binding (username, not a PAT). Never end a service pass with the token saved but the author or a required host unasked.
197
202
  - **Skip is per-service.** A Skip answer leaves that service's `keychainMapping` at `null` and the loop continues with the next service. Skips never abort the loop.
198
203
  - **`figma` and `figma_mcp` are distinct credentials for distinct tiers - ask both.** Skipping the PAT does not imply skipping MCP, and vice versa. The `figma_mcp` pass opens with a Remote / Local mode question instead of a clipboard paste (see "Figma MCP Setup" below): Remote generates a `figu_` OAuth token for the current user, Local wires the PAT-based local server.
199
204
  - The loop ends only when every missing service has been asked exactly once; then continue to Step 4 (Verify all).
@@ -218,17 +223,15 @@ Runs inside Step 3, only when the target repo is Android. One entry, `google_pla
218
223
 
219
224
  ### Step 3.5 - Host Prompt (embedded in Token Save Flow)
220
225
 
221
- Full procedure: `$HOME/.claude/multi-agent-refs/setup/token-save-flow.md`. Read it for the host question inside the Token Save Flow.
226
+ Part of the Token Save Flow reference above.
222
227
 
223
228
  ### Step 3.6 - Per-account host overrides (optional)
224
229
 
225
230
  **Runs only when** `~/.copilot/lib/account-resolver.sh` returns **more than one** account AND at least one account has Jira or Bitbucket tokens.
226
231
 
227
- Use case: one user with two identities (e.g. agency + client), each with its own Jira host; `prefs.global.hosts.jira` holds only one default.
228
-
229
- For each non-default account, ask once: "Account {label} has Jira/Bitbucket tokens but no host override yet. Use the global default ({hosts.jira}) or set a per-account host?" with options **1) Use global default** / **2) Set per-account host**. On `2`, prompt for `jiraHost` / `bitbucketHost` / `confluenceHost` (each optional) and save to `prefs.global.accounts[]`, e.g. `{ "id": "client-x", "jiraHost": "jira.client-x.example.com", "bitbucketHost": "bitbucket.client-x.example.com" }`.
232
+ For each non-default account (two identities, each with its own Jira host), ask once: "Account {label} has Jira/Bitbucket tokens but no host override yet. Use the global default ({hosts.jira}) or set a per-account host?" with options **1) Use global default** / **2) Set per-account host**. On `2`, prompt for `jiraHost` / `bitbucketHost` / `confluenceHost` (each optional) and save to `prefs.global.accounts[]`, e.g. `{ "id": "client-x", "jiraHost": "jira.client-x.example.com", "bitbucketHost": "bitbucket.client-x.example.com" }`.
230
233
 
231
- `account-resolver.sh` reads this on every invocation; per-account override wins over `global.hosts.*`. Skip this step on autopilot - `accounts[]` stays empty until the user opts in via `/multi-agent-setup accounts`, which opens this editor without re-running token discovery.
234
+ `account-resolver.sh` reads this on every invocation; per-account override wins over `global.hosts.*`. Skip this step on autopilot; `/multi-agent-setup accounts` opens it later.
232
235
 
233
236
  ---
234
237