@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.
- package/CHANGELOG.md +58 -0
- package/README.md +24 -13
- package/README.tr.md +21 -10
- package/docs/adr/0017-change-impact-from-the-graph.md +69 -0
- package/docs/adr/README.md +1 -0
- package/docs/ecosystem.md +7 -5
- package/docs/facts.json +6 -4
- package/docs/features.md +1 -0
- package/install/catalog-history.json +1 -1
- package/install/templates/copilot-instructions.md +1 -0
- package/manifest.json +71 -64
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review/SKILL.md +2 -1
- package/pipeline/commands/multi-agent/route-on/SKILL.md +32 -8
- package/pipeline/commands/multi-agent/route-status/SKILL.md +12 -2
- package/pipeline/commands/multi-agent/setup/SKILL.md +8 -16
- package/pipeline/lib/model-dispatch.sh +72 -24
- package/pipeline/lib/outbound-gate.mjs +2 -0
- package/pipeline/lib/route-state.sh +118 -10
- package/pipeline/lib/toolkit-llm.sh +30 -0
- package/pipeline/lib/unattended-profile-check.mjs +23 -2
- package/pipeline/multi-agent-refs/_dev-context.md +15 -0
- package/pipeline/multi-agent-refs/analysis/evidence.md +7 -3
- package/pipeline/multi-agent-refs/analysis/locked.md +1 -1
- package/pipeline/multi-agent-refs/cross-cli-contract.md +9 -3
- package/pipeline/multi-agent-refs/features/code-graph.md +27 -0
- package/pipeline/multi-agent-refs/features/doctor.md +11 -0
- package/pipeline/multi-agent-refs/features/free-models.md +111 -0
- package/pipeline/multi-agent-refs/features/model-fallback.md +21 -15
- package/pipeline/multi-agent-refs/features/product-context.md +238 -0
- package/pipeline/multi-agent-refs/features/unattended-security.md +4 -2
- package/pipeline/multi-agent-refs/knowledge.md +2 -0
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +7 -12
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-3-review.md +7 -6
- package/pipeline/multi-agent-refs/platform-parity.md +23 -9
- package/pipeline/multi-agent-refs/setup/free-models.md +22 -0
- package/pipeline/multi-agent-refs/setup/token-save-flow.md +24 -0
- package/pipeline/preferences-template.json +1 -0
- package/pipeline/schemas/agent-state.schema.json +31 -0
- package/pipeline/schemas/analysis-spec.schema.json +14 -0
- package/pipeline/schemas/code-graph.schema.json +12 -1
- package/pipeline/schemas/diff-risk.schema.json +2 -1
- package/pipeline/schemas/prefs.schema.json +68 -1
- package/pipeline/schemas/route-config.schema.json +33 -8
- package/pipeline/schemas/secret-patterns.json +14 -0
- package/pipeline/scripts/_code-graph.mjs +76 -3
- package/pipeline/scripts/_diff-impact.mjs +312 -0
- package/pipeline/scripts/bulk-read.sh +98 -12
- package/pipeline/scripts/capture-flush.sh +58 -3
- package/pipeline/scripts/cost-table.json +9 -1
- package/pipeline/scripts/diff-risk-score.mjs +80 -9
- package/pipeline/scripts/doctor.mjs +100 -0
- package/pipeline/scripts/graph-affected.mjs +167 -36
- package/pipeline/scripts/graph-query.mjs +16 -4
- package/pipeline/scripts/pre-commit-check.sh +1 -1
- package/pipeline/scripts/product-context.mjs +539 -0
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +39 -1
- package/pipeline/scripts/unattended_policy.py +20 -0
- package/pipeline/scripts/validate-code-graph.mjs +2 -1
- package/pipeline/scripts/validate-diff-risk.mjs +1 -0
- package/pipeline/skills/.skill-manifest.json +6 -6
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +2 -0
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +5 -1
- package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +31 -7
- package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +12 -2
- 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-
|
|
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": "
|
|
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": "
|
|
176
|
+
"sha256": "97c76d711454e6bc9edfd47344bbeab7f73cf72c116cca92cffacdcda7fe96b1"
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"path": "shared/core/multi-agent-route-status/SKILL.md",
|
|
180
|
-
"sha256": "
|
|
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": "
|
|
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": "
|
|
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.
|
|
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` |
|
|
46
|
-
| `cost-ceiling` |
|
|
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
|
|
65
|
-
only at `bulk-read` and `
|
|
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
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|