@mmerterden/multi-agent-pipeline 16.15.0 → 16.16.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 +19 -0
- package/README.md +5 -4
- package/README.tr.md +5 -4
- package/docs/adr/0011-dormant-ci.md +87 -0
- package/docs/adr/README.md +1 -0
- package/docs/architecture.md +2 -2
- package/docs/ecosystem.md +5 -5
- package/install/_common.mjs +0 -1
- package/install/_dev-only-files.mjs +1 -0
- package/install/claude.mjs +14 -4
- package/install/index.mjs +8 -1
- package/package.json +6 -5
- package/pipeline/commands/multi-agent/help/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/steer/SKILL.md +109 -0
- package/pipeline/commands/multi-agent/sync/SKILL.md +5 -7
- package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -4
- package/pipeline/multi-agent-refs/phases/operations.md +23 -0
- package/pipeline/multi-agent-refs/phases.md +38 -0
- package/pipeline/preferences-template.json +2 -10
- package/pipeline/schemas/agent-state.schema.json +35 -0
- package/pipeline/schemas/analysis-spec.schema.json +8 -2
- package/pipeline/schemas/conventions-output.schema.json +2 -13
- package/pipeline/scripts/build-references.mjs +22 -6
- package/pipeline/scripts/code-graph-rules/android.json +4 -21
- package/pipeline/scripts/code-graph-rules/go.json +4 -19
- package/pipeline/scripts/code-graph-rules/node.json +4 -21
- package/pipeline/scripts/feedback-send.mjs +3 -1
- package/pipeline/scripts/gate-linux.sh +62 -0
- package/pipeline/scripts/localize-commands.mjs +1 -2
- package/pipeline/scripts/pre-push-check.sh +6 -4
- package/pipeline/scripts/usage-report.mjs +16 -14
- package/pipeline/scripts/validate-analysis-doc.mjs +46 -27
- package/pipeline/scripts/validate-analysis.mjs +7 -1
- package/pipeline/scripts/validate-complaint-doc.mjs +24 -8
- package/pipeline/scripts/write-state.mjs +71 -12
- package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +111 -0
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,25 @@ Internal file-layout changes that don't affect the slash-command surface are sti
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [16.16.0] - 2026-08-31
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`/multi-agent:steer #N "<instruction>"` corrects a run without stopping it.** `kill` deletes a task and `resume` picks a stopped one back up; neither helps while a phase is in flight, so a correction that arrived mid-run had nowhere to go and the run finished in the wrong direction. The command queues one instruction into `state.pendingSteer`, written through `write-state.mjs` rather than by editing a file the running task is also writing to, and the next phase reads it at entry, applies it, and marks it consumed with `appliedAt`/`appliedPhase` while keeping the record as a trace. Entry rather than mid-phase on purpose: a phase that changes target halfway discards the work it already did, which is the outcome the command exists to avoid. An instruction that contradicts an approved plan halts for the user instead of silently rewriting it. `smoke-steer.sh` walks the whole path - schema, writer, phase-entry contract, help and both READMEs - because a command whose only value is a phase reading the field back is exactly the shape that ships green and dead.
|
|
24
|
+
- **`state.rev`, a monotonic revision counter.** The advisory lock makes a single write atomic and nothing more; it does not cover the gap between a phase reading state and writing it back, and `steer` above puts a deliberate second writer inside that gap. A reader that keeps the `rev` it read can tell the record moved underneath it instead of silently dropping whatever landed in between. Every successful write bumps `rev`; the writer takes the higher of the on-disk value and the incoming patch, so a stale patch cannot walk the counter backwards. A record written before this has none - treat a missing `rev` as 0.
|
|
25
|
+
- **`npm run gate:linux`** runs the ci-lite job on a real Ubuntu image through `act`, covering the Linux leg and a clean `npm ci` that the macOS pre-push gate cannot answer. Deliberately not part of `npm run gate`: `act` is not installed everywhere, and a required gate that cannot run is the failure ADR-0011 exists to avoid.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **A live lock holder could lose its lock to the age rule.** `write-state.mjs` judged a lock stale when its holder PID was dead **or** the file was older than 30 seconds - age checked first, and returning on its own. So a writer that was demonstrably alive had its lock deleted the moment the file aged out, and the next writer overwrote the update behind it. Liveness now outranks age: an alive holder keeps its lock, `WRITE_STATE_LOCK_STALE_MS` applies only to a lock with no readable PID, and a new `WRITE_STATE_LOCK_ABANDON_MS` (default ten times that) is the last-resort ceiling for a recycled PID. No heartbeat: the writer holds the lock across one synchronous write, so there is no window for a timer to refresh anything, and a refreshed timestamp is weaker evidence than the liveness probe already gives.
|
|
30
|
+
- **Prettier was enforced nowhere, and `main` was failing it.** `format:check` was declared in `package.json`, wired into ci-lite, and ci-lite has not executed since 2026-07-02; `eslint-config-prettier` only disables conflicting rules, it does not check formatting. Twenty-five files were failing the project's own declared style. `format:check` now runs inside `npm test`, so the pre-push gate carries it, and a `.prettierignore` exempts two trees with reasons: git worktrees checked out inside the repo, and `pipeline/skills/shared/external/`, which stays byte-identical to upstream so a re-derivation diff remains readable.
|
|
31
|
+
- **The installed-tree leak sweep was running against a private copy of the pattern list, drifted to under half of it.** `smoke-install-leak-gate.sh` carried its own patterns under a comment saying it mirrored `smoke-personal-data.sh`. It did not: personal domains, the maintainer's name, one spelling of the machine username, corporate symbol prefixes and product literals were all missing, so the sweep that runs on every `npm test` was weaker than the one in ci-lite - which has not executed since 2026-07-02. The step now delegates to the file that owns the list, and ci-lite's inline copy of the same dance was replaced by a call to that smoke. Three shapes the private copy caught and the owner did not (a trailing-underscore username compound, the bare organisation name, an address with no local part) were added to the owner, so the union is preserved rather than traded away - and the first of them immediately caught a real leak that had been sitting in `docs/internal/`, which the narrower pattern could not match. That file is not in the published tarball, so nothing reached a user.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **CI is dormant in the repository, not only in platform state.** `test.yml` and `ci-lite.yml` still declared `on: push` and `on: pull_request` while both had already been disabled from the Actions UI - true only for a fork, or for whoever re-enables one without reading further. Both trigger blocks are commented out with the reason beside them, `workflow_dispatch` stays live, and [ADR-0011](./docs/adr/0011-dormant-ci.md) records why, what stays unverified while they sleep (the `windows-test` job, a clean Linux runner, a clean `npm ci` from the lockfile) and the two-line wake-up. `CONTRIBUTING.md` now tells an outside contributor that no workflow will run on their PR and to paste the `npm run gate` output instead of waiting for a green tick.
|
|
36
|
+
- **The scorecard covers moderate advisories and registry signatures.** It measured high and critical only; `--audit-level=moderate` and `npm audit signatures` lived in ci-lite and stopped running with it. Both are scorecard metrics now, the moderate ceiling locked at the measured value of 0. An unreachable registry fails the signature metric rather than skipping it: a supply-chain check that reports green when it could not reach the registry is worse than no check.
|
|
37
|
+
|
|
19
38
|
## [16.15.0] - 2026-08-30
|
|
20
39
|
|
|
21
40
|
### Fixed
|
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ Depth, autopilot and `--local` are the only knobs on the run itself; everything
|
|
|
89
89
|
|
|
90
90
|
## Commands
|
|
91
91
|
|
|
92
|
-
`/multi-agent` plus
|
|
92
|
+
`/multi-agent` plus 55 sub-commands. `/multi-agent:help` renders the same catalog in your terminal, in your `outputLanguage`.
|
|
93
93
|
|
|
94
94
|
### Pipeline entries
|
|
95
95
|
|
|
@@ -109,6 +109,7 @@ Depth, autopilot and `--local` are the only knobs on the run itself; everything
|
|
|
109
109
|
| `/multi-agent:log [#N]` | Show a task's `agent-log.md` (most recent by default) |
|
|
110
110
|
| `/multi-agent:resume [#N]` | Carry a stopped or failed task on from its last phase |
|
|
111
111
|
| `/multi-agent:kill [#N]` | Stop a task, remove its worktree and branch |
|
|
112
|
+
| `/multi-agent:steer #N "<instruction>"` | Correct a running task without stopping it; applied at the next phase boundary |
|
|
112
113
|
| `/multi-agent:search` | Ranked search across every task log; `--semantic` queries the triage corpus |
|
|
113
114
|
| `/multi-agent:garbage-collect` | Sweep leftover scratch, orphan worktrees and offloaded payloads. Dry-run first |
|
|
114
115
|
| `/multi-agent:prune-logs` | Delete per-task logs by age / project / task. Audit trail and metrics kept |
|
|
@@ -208,13 +209,13 @@ This enables the matching plugin (+ the shared `ai-common` plugin) in the repo's
|
|
|
208
209
|
|
|
209
210
|
## Tool support
|
|
210
211
|
|
|
211
|
-
The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same
|
|
212
|
+
The pipeline runs natively on **Claude Code**, **Copilot CLI** and **Codex CLI** - all three install from the same `pipeline/` source and get the same 55 commands.
|
|
212
213
|
|
|
213
214
|
| Tool | Flag | What it installs |
|
|
214
215
|
|---|---|---|
|
|
215
216
|
| Claude Code | `--claude` (default) | slash commands + skills + agents + `PreToolUse` secret-scan hook |
|
|
216
|
-
| Copilot CLI | `--copilot` | instructions +
|
|
217
|
-
| Codex CLI | `--codex` | one router skill +
|
|
217
|
+
| Copilot CLI | `--copilot` | instructions + 55 sub-command skills + scripts |
|
|
218
|
+
| Codex CLI | `--codex` | one router skill + 55 specs as refs + 8 agent TOML + `AGENTS.md` block + `codex mcp add` |
|
|
218
219
|
|
|
219
220
|
Filter skills by stack with `--platform=ios\|android\|all`.
|
|
220
221
|
|
package/README.tr.md
CHANGED
|
@@ -89,7 +89,7 @@ Koşunun kendisinde ayarlanabilen tek şey derinlik, autopilot ve `--local`; ger
|
|
|
89
89
|
|
|
90
90
|
## Komutlar
|
|
91
91
|
|
|
92
|
-
`/multi-agent` ve
|
|
92
|
+
`/multi-agent` ve 55 alt komut. `/multi-agent:help` aynı katalogu terminalde, `outputLanguage` ayarına göre gösterir.
|
|
93
93
|
|
|
94
94
|
### Pipeline girişleri
|
|
95
95
|
|
|
@@ -109,6 +109,7 @@ Koşunun kendisinde ayarlanabilen tek şey derinlik, autopilot ve `--local`; ger
|
|
|
109
109
|
| `/multi-agent:log [#N]` | Görevin `agent-log.md` dosyası (varsayılan: en son görev) |
|
|
110
110
|
| `/multi-agent:resume [#N]` | Durmuş ya da hata almış görevi kaldığı fazdan sürdürür |
|
|
111
111
|
| `/multi-agent:kill [#N]` | Görevi durdurur, worktree'sini ve branch'ini siler |
|
|
112
|
+
| `/multi-agent:steer #N "<talimat>"` | Koşan bir görevi durdurmadan düzeltir; talimat bir sonraki faz sınırında uygulanır |
|
|
112
113
|
| `/multi-agent:search` | Tüm görev loglarında sıralamalı arama; `--semantic` triyaj corpus'unu sorgular |
|
|
113
114
|
| `/multi-agent:garbage-collect` | Artık scratch, sahipsiz worktree ve offload edilmiş payload'ları süpürür. Önce dry-run |
|
|
114
115
|
| `/multi-agent:prune-logs` | Görev loglarını yaş / proje / görev filtresiyle siler. Denetim izi ve metrikler kalır |
|
|
@@ -208,13 +209,13 @@ Bu, ilgili plugin'i (+ ortak `ai-common` plugin'ini) repo'nun `.claude/settings.
|
|
|
208
209
|
|
|
209
210
|
## Araç desteği
|
|
210
211
|
|
|
211
|
-
Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı
|
|
212
|
+
Pipeline **Claude Code**, **Copilot CLI** ve **Codex CLI** üzerinde native çalışır - üçü de aynı `pipeline/` kaynağından kurulur ve aynı 55 komutu alır.
|
|
212
213
|
|
|
213
214
|
| Araç | Bayrak | Ne kurar |
|
|
214
215
|
|---|---|---|
|
|
215
216
|
| Claude Code | `--claude` (varsayılan) | slash komutları + skill'ler + agent'lar + `PreToolUse` secret-scan hook'u |
|
|
216
|
-
| Copilot CLI | `--copilot` | talimatlar +
|
|
217
|
-
| Codex CLI | `--codex` | bir router skill + ref olarak
|
|
217
|
+
| Copilot CLI | `--copilot` | talimatlar + 55 alt-komut skill'i + script'ler |
|
|
218
|
+
| Codex CLI | `--codex` | bir router skill + ref olarak 55 spec + 8 agent TOML + `AGENTS.md` bloğu + `codex mcp add` |
|
|
218
219
|
|
|
219
220
|
Skill'leri stack'e göre filtrele: `--platform=ios\|android\|all`.
|
|
220
221
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# 11. CI stays in the repository but dormant; the pre-push gate is primary
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted · 2026-08-31
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The repository carries four workflows. `test.yml` runs the full chain across a
|
|
8
|
+
macOS/Ubuntu matrix plus a separate `windows-test` job, `ci-lite.yml` runs a
|
|
9
|
+
single cheap Ubuntu job, `release.yml`
|
|
10
|
+
publishes on a version tag and `live-eval.yml` is a manual, budgeted evaluation.
|
|
11
|
+
|
|
12
|
+
None of the first three has executed since 2026-07-02. That day's last run took
|
|
13
|
+
318 seconds and passed; every attempt after it - five, the last on 2026-07-25 -
|
|
14
|
+
finished in about four seconds with zero steps recorded, which is the shape of a
|
|
15
|
+
quota block rather than a test failure. All three were then disabled from the
|
|
16
|
+
Actions UI. That stopped the noise but moved the fact out of the repository:
|
|
17
|
+
the files still declared `on: push` and `on: pull_request`, so anyone reading
|
|
18
|
+
them, forking them, or re-enabling the workflow inherited a promise the project
|
|
19
|
+
does not keep.
|
|
20
|
+
|
|
21
|
+
Meanwhile the gate did not disappear. `pipeline/scripts/pre-push-check.sh` runs
|
|
22
|
+
the canonical `npm test` chain, stamps the exact tree it verified, and refuses
|
|
23
|
+
any push whose tree carries no stamp. It is installed as `.git/hooks/pre-push`.
|
|
24
|
+
So the question was never "is this code verified" but "verified where, and what
|
|
25
|
+
does that leave uncovered".
|
|
26
|
+
|
|
27
|
+
There is no plan to run this on a server in the near term. There is a possible
|
|
28
|
+
later direction (an issue-triggered run that starts development automatically),
|
|
29
|
+
which argues for keeping the workflow files rather than deleting them.
|
|
30
|
+
|
|
31
|
+
## Decision
|
|
32
|
+
|
|
33
|
+
Keep every workflow file. Comment out the `push` and `pull_request` triggers in
|
|
34
|
+
`test.yml` and `ci-lite.yml`, leaving `workflow_dispatch` live, and state the
|
|
35
|
+
dormancy in the file header next to the triggers.
|
|
36
|
+
|
|
37
|
+
Treat `npm run gate` as the primary gate, not as a fallback, and close the parts
|
|
38
|
+
of the ci-lite job that had no local equivalent: `format:check` joins the `npm
|
|
39
|
+
test` chain, the install dry-run plus personal-data audit moves onto the
|
|
40
|
+
existing `smoke-install-leak-gate.sh` (which was already doing the same install
|
|
41
|
+
into a temp HOME, against a private copy of the pattern list that had drifted to
|
|
42
|
+
less than half of it), the scorecard gains the two dependency checks that lived
|
|
43
|
+
only in ci-lite - moderate advisories and `npm audit signatures` - and the Linux
|
|
44
|
+
leg is reachable as `npm run gate:linux` through `act`.
|
|
45
|
+
|
|
46
|
+
Waking CI is a two-line edit: uncomment the trigger blocks and re-enable the
|
|
47
|
+
workflow in the Actions UI. Nothing else in the files changes.
|
|
48
|
+
|
|
49
|
+
## Consequences
|
|
50
|
+
|
|
51
|
+
A reader of the repository now sees what actually runs. A fork does not
|
|
52
|
+
inherit surprise runs that fail for a reason belonging to this account.
|
|
53
|
+
|
|
54
|
+
The local gate runs the canonical chain rather than a hand-picked subset: the
|
|
55
|
+
hook calls `npm test`, so a step added to that script is a step the hook runs.
|
|
56
|
+
`ci-lite.yml` still enumerates its steps one by one and can therefore drift
|
|
57
|
+
behind the script - which is a further reason the local gate, not the workflow,
|
|
58
|
+
is the one being trusted.
|
|
59
|
+
|
|
60
|
+
What stays unverified while the workflows sleep, stated rather than implied:
|
|
61
|
+
|
|
62
|
+
- Windows. `lib/credential-store.sh` has a Windows branch exercised only by
|
|
63
|
+
`test.yml`'s separate `windows-test` job (the matrix itself is Ubuntu and
|
|
64
|
+
macOS).
|
|
65
|
+
- A clean `npm ci` from the lockfile into an empty tree. The local gate runs
|
|
66
|
+
against an installed `node_modules` that has accumulated across months.
|
|
67
|
+
- Linux, unless someone actually runs `npm run gate:linux`. It is deliberately
|
|
68
|
+
not a required step: `act` is not installed everywhere, and a required gate
|
|
69
|
+
that cannot run is the failure this ADR exists to avoid.
|
|
70
|
+
|
|
71
|
+
`release.yml` keeps its tag trigger and stays disabled in the UI. Publishing is
|
|
72
|
+
done locally from a clean tag clone, so the tag flow is what a future wake-up
|
|
73
|
+
would want unchanged.
|
|
74
|
+
|
|
75
|
+
## Alternatives
|
|
76
|
+
|
|
77
|
+
**Pay for Actions minutes.** Buys the matrix and the clean room. Rejected for
|
|
78
|
+
now: there is no server-side plan to justify a recurring cost, and the local
|
|
79
|
+
gate already covers everything except the three items listed above.
|
|
80
|
+
|
|
81
|
+
**Make this machine a self-hosted runner.** Free and real. Rejected: it covers
|
|
82
|
+
only macOS, disappears when the laptop is closed, and a self-hosted runner on a
|
|
83
|
+
public repository executes code from any fork's pull request.
|
|
84
|
+
|
|
85
|
+
**Delete the workflows.** Honest but lossy. The files encode which steps matter
|
|
86
|
+
and in what order, and the possible issue-triggered direction would have to
|
|
87
|
+
rebuild them from nothing.
|
package/docs/adr/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Format: lightly adapted from [Michael Nygard's ADR template](https://cognitect.c
|
|
|
20
20
|
| [0008](./0008-installer-modularization-and-secret-leak-defense.md) | Installer modularization + secret-leak defense | Accepted (amended v10.7.0: adapter module removed) |
|
|
21
21
|
| [0009](./0009-claude-stack-skills-plugin-only.md) | Claude Code stack skills are plugin-only; local copy retired | Accepted (supersedes ADR-0006 install-destination clause) |
|
|
22
22
|
| [0010](./0010-own-code-graph.md) | Own code graph, referenced from graphify, not forked | Accepted |
|
|
23
|
+
| [0011](./0011-dormant-ci.md) | CI dormant in-repo; pre-push gate is primary | Accepted |
|
|
23
24
|
|
|
24
25
|
## Writing a New ADR
|
|
25
26
|
|
package/docs/architecture.md
CHANGED
|
@@ -117,7 +117,7 @@ graph TB
|
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
subgraph "Pipeline Specs"
|
|
120
|
-
CMD[commands/<br/>
|
|
120
|
+
CMD[commands/<br/>55 command files]
|
|
121
121
|
AGT[agents/<br/>8 agent personas]
|
|
122
122
|
RUL[rules/<br/>12 domain rules]
|
|
123
123
|
PHS[multi-agent-refs/phases/<br/>phase specs + contracts]
|
|
@@ -170,7 +170,7 @@ revisions of this diagram - Codex CLI and the two independently-shipped repos
|
|
|
170
170
|
graph TD
|
|
171
171
|
CC["Claude Code<br/>(source of truth)"]
|
|
172
172
|
COP["Copilot CLI<br/>(instructions + 51 skills)"]
|
|
173
|
-
COD["Codex CLI<br/>(1 router skill +
|
|
173
|
+
COD["Codex CLI<br/>(1 router skill + 55 refs)"]
|
|
174
174
|
REPO["Pipeline Repo<br/>(npm package)"]
|
|
175
175
|
WEB["Website"]
|
|
176
176
|
PLUGREPO["multi-agent-plugins<br/>(5 stack plugins, own repo)"]
|
package/docs/ecosystem.md
CHANGED
|
@@ -5,7 +5,7 @@ separately, wired together at install time and at run time:
|
|
|
5
5
|
|
|
6
6
|
| Repo | What it owns | Ships as |
|
|
7
7
|
|---|---|---|
|
|
8
|
-
| **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the
|
|
8
|
+
| **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 55 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
|
|
9
9
|
| **`multi-agent-plugins`** | Stack knowledge: per-platform component/lifecycle skills (iOS, Android, Frontend, Backend) + shared knowledge | Claude Code marketplace, 5 independently-versioned plugins |
|
|
10
10
|
| **`multi-agent-toolkit-mcp`** | The pipeline's hands on devices and browsers: 80 MCP tools across 6 categories (simulator/emulator control, accessibility audit, store compliance, web automation, Figma-vs-mock design audit, an agent-DSL batch runner) | npm package, registered as a standard stdio MCP server on every host |
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ Either can be swapped or removed without touching the other two's source.
|
|
|
18
18
|
graph LR
|
|
19
19
|
subgraph PIPE ["multi-agent-pipeline (orchestrator)"]
|
|
20
20
|
direction TB
|
|
21
|
-
PHASES["8 phases ·
|
|
21
|
+
PHASES["8 phases · 55 commands"]
|
|
22
22
|
GATES["deterministic gates + review triage"]
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -64,8 +64,8 @@ only those:
|
|
|
64
64
|
graph TD
|
|
65
65
|
CC["Claude Code<br/>~/.claude/commands/multi-agent/<br/>(source of truth)"]
|
|
66
66
|
|
|
67
|
-
CC -->|"Step 2: copy + reformat<br/>
|
|
68
|
-
CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill +
|
|
67
|
+
CC -->|"Step 2: copy + reformat<br/>55 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
|
|
68
|
+
CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 55 refs<br/>+ 8 agent TOML"]
|
|
69
69
|
CC -->|"Step 3: genericize<br/>(strip personal data)"| REPO["multi-agent-pipeline repo<br/>pipeline/"]
|
|
70
70
|
CC -->|"Step 4: version + feature sync"| WEB["Website<br/>projects.ts / i18n.tsx"]
|
|
71
71
|
|
|
@@ -153,7 +153,7 @@ measurements behind this table):
|
|
|
153
153
|
|
|
154
154
|
| | Claude Code | Copilot CLI | Codex CLI |
|
|
155
155
|
|---|---|---|---|
|
|
156
|
-
| **Pipeline commands** |
|
|
156
|
+
| **Pipeline commands** | 55 slash-command skills, native | 55 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 55 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
|
|
157
157
|
| **Stack plugins** | Marketplace plugin, loaded natively, resolved by `.claude/settings.json` enabled-list | Enabled plugin's authored skills copied flat into `~/.copilot/skills/`; `knowledge/` **not** re-copied (already delivered via `shared/external`) | Copied as reference files under `~/.codex/multi-agent-refs/skills/`, plugin-prefixed on name clash (e.g. `architecture` → `ai-ios-toolkit-architecture`) |
|
|
158
158
|
| **Component dispatch (Phase 3)** | Marketplace plugin's `create-component`/`create-screen` skill via the Skill tool | No plugin loader - the enabled stack plugin's authored skills (incl. `create-component`) are copied flat into `~/.copilot/skills/` at install time (the old frozen `figma-*` copies are pruned, they were never a fallback) | Not part of the enforced parity axis; classification + state-shape must match, skill *inventory* does not |
|
|
159
159
|
| **multi-agent-toolkit-mcp** | `claude mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `copilot mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `codex mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` (skipped with a warning if `codex` isn't on `PATH`) |
|
package/install/_common.mjs
CHANGED
|
@@ -64,6 +64,7 @@ const DEV_ONLY_TOOLING = Object.freeze([
|
|
|
64
64
|
"validate-schemas.mjs", // validates the repo's own schema files, needs ajv
|
|
65
65
|
"sync-parity-check.sh",
|
|
66
66
|
"benchmark-phase-0.sh",
|
|
67
|
+
"gate-linux.sh", // drives .github/workflows/ci-lite.yml through act; no consumer has either
|
|
67
68
|
]);
|
|
68
69
|
|
|
69
70
|
/** Eval harnesses (`eval-*.mjs`) read `pipeline/eval/**`, which never ships. */
|
package/install/claude.mjs
CHANGED
|
@@ -97,7 +97,14 @@ export function installClaude(ctx) {
|
|
|
97
97
|
installSchemas(pipelineSrc, CLAUDE_SCHEMAS, useSymlinks);
|
|
98
98
|
installLib(pipelineSrc, CLAUDE_LIB, useSymlinks);
|
|
99
99
|
runPreDeployScans(pipelineSrc);
|
|
100
|
-
installSkills({
|
|
100
|
+
installSkills({
|
|
101
|
+
pipelineSrc,
|
|
102
|
+
dest: CLAUDE_SKILLS,
|
|
103
|
+
indexOnly,
|
|
104
|
+
useSymlinks,
|
|
105
|
+
platformFlag,
|
|
106
|
+
pruneExternal,
|
|
107
|
+
});
|
|
101
108
|
ensureClaudeMd(home, pipelineSrc);
|
|
102
109
|
ensurePreferences(PREFS_PATH, pipelineSrc);
|
|
103
110
|
configureSettings(home);
|
|
@@ -458,7 +465,9 @@ function installSkills(opts) {
|
|
|
458
465
|
console.log(` -> pruned ${orphans} stale flat skill file(s) from an older layout`);
|
|
459
466
|
}
|
|
460
467
|
|
|
461
|
-
console.log(
|
|
468
|
+
console.log(
|
|
469
|
+
` -> ${claudeSkillCount} skill files installed to ${dest} (stack skills: marketplace plugins)`,
|
|
470
|
+
);
|
|
462
471
|
|
|
463
472
|
// The shared skills README described the full local catalog; with the catalog
|
|
464
473
|
// gone it would document skills that are not here. Drop it, including copies
|
|
@@ -604,7 +613,9 @@ function migratePreManifestExternalSkills(dest, externalSrc, opts) {
|
|
|
604
613
|
);
|
|
605
614
|
}
|
|
606
615
|
if (flagged > 0) {
|
|
607
|
-
console.log(
|
|
616
|
+
console.log(
|
|
617
|
+
` -> --prune-external: removed ${flagged} catalog-named skill dir(s) that had local differences`,
|
|
618
|
+
);
|
|
608
619
|
}
|
|
609
620
|
if (leftover.length > 0) {
|
|
610
621
|
console.log(
|
|
@@ -614,7 +625,6 @@ function migratePreManifestExternalSkills(dest, externalSrc, opts) {
|
|
|
614
625
|
}
|
|
615
626
|
}
|
|
616
627
|
|
|
617
|
-
|
|
618
628
|
function ensureClaudeMd(home, pipelineSrc) {
|
|
619
629
|
console.log(" [Claude Code] Checking CLAUDE.md template...");
|
|
620
630
|
const CLAUDE_MD = join(home, ".claude", "CLAUDE.md");
|
package/install/index.mjs
CHANGED
|
@@ -46,7 +46,14 @@ export async function runInstall(argv) {
|
|
|
46
46
|
// `multi-agent-pipeline install --all` (via bin, argv[2]="install")
|
|
47
47
|
const flags = argv.slice(2).filter((a) => a !== "install");
|
|
48
48
|
|
|
49
|
-
const KNOWN_FLAGS = [
|
|
49
|
+
const KNOWN_FLAGS = [
|
|
50
|
+
...TOOL_FLAGS,
|
|
51
|
+
"--all",
|
|
52
|
+
"--link",
|
|
53
|
+
"--index-only",
|
|
54
|
+
"--dry-run",
|
|
55
|
+
"--prune-external",
|
|
56
|
+
];
|
|
50
57
|
const KNOWN_PREFIXES = ["--target=", "--platform="];
|
|
51
58
|
const unknown = flags.filter(
|
|
52
59
|
(f) =>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.16.0",
|
|
4
4
|
"description": "8-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"start": "node index.js",
|
|
17
|
-
"test": "node --test test/*.test.mjs && node pipeline/scripts/run-smokes.mjs && node pipeline/scripts/lint-skills.mjs && node pipeline/scripts/lint-mcp-refs.mjs && node pipeline/scripts/eval-triage.mjs && node pipeline/scripts/eval-golden-tasks.mjs && node pipeline/scripts/eval-intent.mjs && node pipeline/scripts/eval-recall.mjs && node pipeline/scripts/validate-schemas.mjs && node pipeline/scripts/validate-prefs.mjs && node pipeline/scripts/scorecard.mjs",
|
|
17
|
+
"test": "npm run format:check && node --test test/*.test.mjs && node pipeline/scripts/run-smokes.mjs && node pipeline/scripts/lint-skills.mjs && node pipeline/scripts/lint-mcp-refs.mjs && node pipeline/scripts/eval-triage.mjs && node pipeline/scripts/eval-golden-tasks.mjs && node pipeline/scripts/eval-intent.mjs && node pipeline/scripts/eval-recall.mjs && node pipeline/scripts/validate-schemas.mjs && node pipeline/scripts/validate-prefs.mjs && node pipeline/scripts/scorecard.mjs",
|
|
18
18
|
"test:unit": "node --test test/*.test.mjs",
|
|
19
19
|
"test:smoke": "node pipeline/scripts/run-smokes.mjs",
|
|
20
20
|
"lint:skills": "node pipeline/scripts/lint-skills.mjs",
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
"test:coverage": "c8 --clean --reporter=none node --test test/*.test.mjs && c8 --clean=false --check-coverage --reporter=text --reporter=lcov node pipeline/scripts/run-smokes.mjs",
|
|
23
23
|
"lint": "eslint .",
|
|
24
24
|
"lint:fix": "eslint . --fix",
|
|
25
|
-
"format": "prettier --write \"**/*.{js,mjs,json,yml}\" --ignore-path .gitignore",
|
|
26
|
-
"format:check": "prettier --check \"**/*.{js,mjs,json,yml}\" --ignore-path .gitignore",
|
|
25
|
+
"format": "prettier --write \"**/*.{js,mjs,json,yml}\" --ignore-path .gitignore --ignore-path .prettierignore",
|
|
26
|
+
"format:check": "prettier --check \"**/*.{js,mjs,json,yml}\" --ignore-path .gitignore --ignore-path .prettierignore",
|
|
27
27
|
"scorecard": "node pipeline/scripts/scorecard.mjs",
|
|
28
|
-
"gate": "bash pipeline/scripts/pre-push-check.sh --run"
|
|
28
|
+
"gate": "bash pipeline/scripts/pre-push-check.sh --run",
|
|
29
|
+
"gate:linux": "bash pipeline/scripts/gate-linux.sh"
|
|
29
30
|
},
|
|
30
31
|
"keywords": [
|
|
31
32
|
"multi-agent",
|
|
@@ -108,6 +108,7 @@ Status & Resume:
|
|
|
108
108
|
/multi-agent:log [#id] Show task log (defaults to most recent)
|
|
109
109
|
/multi-agent:resume [#id] Resume a paused or failed task from where it stopped
|
|
110
110
|
/multi-agent:kill [#id] Stop task + delete worktree (logs preserved)
|
|
111
|
+
/multi-agent:steer #id "..." Correct a running task without stopping it (applied at the next phase)
|
|
111
112
|
/multi-agent:prune-logs Delete per-task project logs (audit + metrics kept; age/project/task filters, dry-run first)
|
|
112
113
|
/multi-agent:prune-prompts Zero-base prompt review: measure always-on instruction footprint, propose keep/trial/delete per rule (report first, apply on approval)
|
|
113
114
|
/multi-agent:garbage-collect Sweep leftover /tmp scratch from past runs (dry-run first)
|
|
@@ -384,6 +385,7 @@ Status & Resume:
|
|
|
384
385
|
/multi-agent:log [#id] Task log'unu göster (varsayılan: en son task)
|
|
385
386
|
/multi-agent:resume [#id] Duraklamış / hata almış task'ı kaldığı yerden devam ettir
|
|
386
387
|
/multi-agent:kill [#id] Task'ı durdur + worktree'yi sil (log'lar korunur)
|
|
388
|
+
/multi-agent:steer #id "..." Koşan task'ı durdurmadan düzelt (sonraki fazda uygulanır)
|
|
387
389
|
/multi-agent:prune-logs Task bazlı proje log'larını sil (audit + metrics korunur; yaş/proje/task filtresi, önce dry-run)
|
|
388
390
|
/multi-agent:prune-prompts Sıfır-tabanlı prompt incelemesi: sürekli yüklü talimat yükünü ölç, kural başına tut/dene/sil öner (önce rapor, onayla uygula)
|
|
389
391
|
/multi-agent:garbage-collect Geçmiş koşumların /tmp artıklarını süpür (önce dry-run)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Queue an instruction for a task that is already running. It is applied at the next phase boundary, not mid-phase. Use when a run is going the wrong way and killing it would throw away good work."
|
|
3
|
+
description-tr: "Zaten koşmakta olan bir göreve talimat bırakır. Talimat faz ortasında değil, bir sonraki faz sınırında uygulanır. Koşu yanlış yöne gidiyorsa ve kill etmek iyi işi de çöpe atacaksa kullanılır."
|
|
4
|
+
argument-hint: "#id \"<instruction>\" - e.g. #3 \"the field is called web, not frontend\". With no instruction, you are asked for it."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# multi-agent steer - correct a run without stopping it
|
|
8
|
+
|
|
9
|
+
**Input**: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
Leave one instruction for a running task. The next phase reads it before it
|
|
12
|
+
starts work, applies it, and marks it consumed.
|
|
13
|
+
|
|
14
|
+
This exists because the alternative was losing the run. `kill` stops a task and
|
|
15
|
+
deletes its worktree; `resume` picks a stopped one back up. Neither helps while
|
|
16
|
+
a phase is in flight, so a correction that arrived mid-run - "that field is
|
|
17
|
+
called `web`, not `frontend`", "keep the analysis, drop the rest" - had nowhere
|
|
18
|
+
to go, and the run carried on in the wrong direction until it finished.
|
|
19
|
+
|
|
20
|
+
**Not a second prompt.** One instruction is queued at a time. Steering a task
|
|
21
|
+
that already has an unconsumed instruction replaces it, after showing you what
|
|
22
|
+
is being replaced.
|
|
23
|
+
|
|
24
|
+
## Steps
|
|
25
|
+
|
|
26
|
+
1. **Find the task** - parse `#N` or `{JIRA-KEY}-XXXXX` from the argument,
|
|
27
|
+
the same way `kill` and `resume` do. Locate its `agent-state.json`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
find {repo}/.worktrees/ -name "agent-state.json" -maxdepth 2
|
|
31
|
+
find $HOME/.claude/logs/multi-agent -maxdepth 4 -name agent-state.json -path '*/artifacts/*'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Not found → `ERR: no task #N. '/multi-agent:status' lists what is running.`
|
|
35
|
+
|
|
36
|
+
2. **Check it can still be steered** - read `status` and `currentPhase`:
|
|
37
|
+
|
|
38
|
+
| State | What to do |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `in_progress` | Queue it. This is the case the command is for. |
|
|
41
|
+
| `paused` / `failed` | Say the task is not running, and that `/multi-agent:resume #N` will re-enter with the instruction applied at that phase's entry. Queue it. |
|
|
42
|
+
| `complete` | Refuse. Nothing will read it. Point at `/multi-agent` for a follow-up run. |
|
|
43
|
+
|
|
44
|
+
`currentPhase` is 7 and status is `in_progress` → warn that Phase 7 is the
|
|
45
|
+
last one, so an instruction queued now may never be consumed.
|
|
46
|
+
|
|
47
|
+
3. **Read the instruction** - from the argument, or ask for it when the
|
|
48
|
+
argument carries only an id. Verbatim, up to 4000 characters. Do not
|
|
49
|
+
summarize or rewrite it: the phase that consumes it needs the user's own
|
|
50
|
+
words, and a paraphrase is where the meaning goes.
|
|
51
|
+
|
|
52
|
+
4. **Show what will be queued, and ask**:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Steer #3 ({JIRA-KEY}-12345, Phase 3 Dev, in_progress)
|
|
56
|
+
|
|
57
|
+
"the field is called web, not frontend"
|
|
58
|
+
|
|
59
|
+
Applied at the entry to Phase 4. The current phase finishes as it is.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Already carrying an unconsumed `pendingSteer` → print the old text above the
|
|
63
|
+
new one and ask whether to replace it.
|
|
64
|
+
|
|
65
|
+
5. **Write it** - through the state writer, never by editing the file, because
|
|
66
|
+
the running task is writing to it too. `$STATE_FILE` is the path from step 1
|
|
67
|
+
and `$INSTRUCTION` the text from step 3:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
printf '{"pendingSteer":{"text":%s,"at":"%s","appliedAt":null,"appliedPhase":null}}' \
|
|
71
|
+
"$(node -e 'process.stdout.write(JSON.stringify(process.argv[1]))' "$INSTRUCTION")" \
|
|
72
|
+
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
73
|
+
| node $HOME/.claude/scripts/write-state.mjs "$STATE_FILE"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The instruction is JSON-encoded by `node -e`, not by hand: it is arbitrary
|
|
77
|
+
user text, and a quote or newline in it would otherwise produce invalid JSON
|
|
78
|
+
or, worse, a payload that merges into fields nobody meant to touch.
|
|
79
|
+
|
|
80
|
+
Exit 2 (lock timeout) → the task is mid-write. Retry once, then report it
|
|
81
|
+
rather than forcing the write.
|
|
82
|
+
|
|
83
|
+
6. **Confirm**: `🧭 Steer queued for #N - applies at the entry to Phase {N+1}`
|
|
84
|
+
|
|
85
|
+
## What the phase does with it
|
|
86
|
+
|
|
87
|
+
Phase entry, before any work: read a `pendingSteer` that has no `appliedAt`.
|
|
88
|
+
When present, apply it to that phase's context, set `appliedAt` and
|
|
89
|
+
`appliedPhase` - which is what stops it being read a second time - and write a
|
|
90
|
+
`Steer applied` line into `agent-log.md`. The record itself stays, so the run
|
|
91
|
+
keeps the trace of what was asked and when. The contract lives in
|
|
92
|
+
`$HOME/.claude/multi-agent-refs/phases.md` under "Phase entry - pending
|
|
93
|
+
steer" (the file has a second, unrelated "Phase entry" line inside the tracker
|
|
94
|
+
block).
|
|
95
|
+
|
|
96
|
+
Applied at entry rather than the moment it arrives, on purpose: a phase that
|
|
97
|
+
changes target halfway through throws away the work it already did, which is
|
|
98
|
+
the outcome this command exists to avoid.
|
|
99
|
+
|
|
100
|
+
An instruction that contradicts the plan is not silently obeyed. The phase says
|
|
101
|
+
what it is changing, and a contradiction that would invalidate an approved plan
|
|
102
|
+
halts for the user instead of quietly rewriting it.
|
|
103
|
+
|
|
104
|
+
**One limit worth knowing.** The reader is the phase contract, so a task started
|
|
105
|
+
by an install that predates it will not consume the field: the instruction is
|
|
106
|
+
written and nothing picks it up. There is no version stamp on a state file to
|
|
107
|
+
detect this from, so the honest advice is that steer applies to runs started
|
|
108
|
+
after the install carrying it. A run already in flight from an older install is
|
|
109
|
+
still a `kill` or a wait.
|
|
@@ -59,7 +59,7 @@ Run every step automatically:
|
|
|
59
59
|
```
|
|
60
60
|
Step 1: PLATFORM Detect macOS / Linux / Windows (Git Bash / WSL); export PLATFORM env
|
|
61
61
|
Step 1.5: DETECT Compare timestamps, find stale targets
|
|
62
|
-
Step 2: COPILOT Claude Code -> Copilot CLI (instructions +
|
|
62
|
+
Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 55 sub-command skills)
|
|
63
63
|
Step 2b: CODEX Claude Code -> Codex CLI (1 router skill + 51 specs as refs + 8 agent TOML)
|
|
64
64
|
Step 3: REPO Claude Code -> pipeline repo (genericized, personal data scrub, bash -n on all sh)
|
|
65
65
|
Step 3c: PLUGINS pipeline shared/external -> multi-agent-plugins marketplace (rebuild knowledge/,
|
|
@@ -166,7 +166,7 @@ If nothing is stale → report "All targets up to date" and stop.
|
|
|
166
166
|
Unlike the Copilot step, this one does **not** hand-copy files. The Codex tree is a
|
|
167
167
|
*transform* of the Claude tree, not a mirror of it, and the transform is real work:
|
|
168
168
|
|
|
169
|
-
- the
|
|
169
|
+
- the 55 sub-command specs become reference files, because Codex silently truncates
|
|
170
170
|
its skills block (see `cross-cli-contract.md` 2.6 for the measurement)
|
|
171
171
|
- every `$HOME/.claude/...` reference to a CLI-owned tree is retargeted, with
|
|
172
172
|
`agents/<persona>.md` becoming `.toml` and the dispatcher becoming the router skill
|
|
@@ -479,17 +479,15 @@ When invoked with the `release` argument:
|
|
|
479
479
|
|
|
480
480
|
## Sub-Command Sync (Claude Code <-> Copilot CLI Skills)
|
|
481
481
|
|
|
482
|
-
> Codex takes the Step 2b path instead; see that section.
|
|
483
|
-
|
|
484
482
|
This runs on the Claude <-> Copilot axis. Codex is NOT synced here: it receives the
|
|
485
|
-
same
|
|
483
|
+
same 55 specs as reference files rather than as peer skills, via Step 2b - see
|
|
486
484
|
`cross-cli-contract.md` 2.6 for why the parity axis differs per host.
|
|
487
485
|
|
|
488
486
|
| Claude Code | Copilot CLI |
|
|
489
487
|
|-------------|-------------|
|
|
490
488
|
| `~/.claude/commands/multi-agent/{cmd}/SKILL.md` | `~/.copilot/skills/multi-agent-{cmd}/SKILL.md` |
|
|
491
489
|
|
|
492
|
-
**
|
|
490
|
+
**55 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
|
|
493
491
|
|
|
494
492
|
```
|
|
495
493
|
analysis, analysis-resolve, autopilot, build-optimize, channels,
|
|
@@ -498,7 +496,7 @@ dev-local-autopilot, diff-explain, feedback, forget, garbage-collect,
|
|
|
498
496
|
graph, help, ios-coding-standard, issue, jira, kill, language, local,
|
|
499
497
|
local-autopilot, log, manual-test, prune-logs, prune-prompts, purge,
|
|
500
498
|
refactor, resume, resume-local, review, review-analysis, review-issue,
|
|
501
|
-
review-jira, routines, save, scan, search, setup, stack, status,
|
|
499
|
+
review-jira, routines, save, scan, search, setup, stack, status, steer,
|
|
502
500
|
store-ready, sync, test, test-accessibility, test-dark-mode,
|
|
503
501
|
test-dynamic-type, test-screenshots, testflight-validation, uninstall, update
|
|
504
502
|
```
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## 1. Command Inventory (
|
|
9
|
+
## 1. Command Inventory (55 files, 51 live commands)
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
analysis, analysis-resolve, autopilot, build-optimize, channels,
|
|
@@ -15,7 +15,7 @@ dev-local-autopilot, diff-explain, feedback, forget, garbage-collect,
|
|
|
15
15
|
graph, help, ios-coding-standard, issue, jira, kill, language, local,
|
|
16
16
|
local-autopilot, log, manual-test, prune-logs, prune-prompts, purge,
|
|
17
17
|
refactor, resume, resume-local, review, review-analysis, review-issue,
|
|
18
|
-
review-jira, routines, save, scan, search, setup, stack, status,
|
|
18
|
+
review-jira, routines, save, scan, search, setup, stack, status, steer,
|
|
19
19
|
store-ready, sync, test, test-accessibility, test-dark-mode,
|
|
20
20
|
test-dynamic-type, test-screenshots, testflight-validation, uninstall, update
|
|
21
21
|
```
|
|
@@ -27,12 +27,12 @@ Categories:
|
|
|
27
27
|
- **Pipeline entries**: `autopilot`, `local`, `local-autopilot` (plus the bare `/multi-agent` in the dispatcher). Depth is not a command: `/multi-agent` and `local` ask Full or Short at Phase 0 Step 7.5; the two autopilot entries never ask and always run Full.
|
|
28
28
|
- **Retired stubs** (v16.0.0, deleted next minor - they print a redirect and run no phase): `dev`, `dev-local` redirect to the picker entries with Short; `dev-autopilot`, `dev-local-autopilot` have no equivalent, because fast-plus-unattended no longer exists
|
|
29
29
|
- **Tail modes** (run the pipeline tail over already-done local work): `resume-local`
|
|
30
|
-
- **Ops commands** (one-shot, no worktree): `status`, `log`, `kill`, `purge`, `uninstall`, `resume`, `review`, `review-jira`, `review-issue`, `analysis`, `analysis-resolve`, `complaint-analysis`, `build-optimize`, `channels`, `scan`, `search`, `diff-explain`, `garbage-collect`, `graph`, `prune-logs`, `prune-prompts`
|
|
30
|
+
- **Ops commands** (one-shot, no worktree): `status`, `log`, `kill`, `steer`, `purge`, `uninstall`, `resume`, `review`, `review-jira`, `review-issue`, `analysis`, `analysis-resolve`, `complaint-analysis`, `build-optimize`, `channels`, `scan`, `search`, `diff-explain`, `garbage-collect`, `graph`, `prune-logs`, `prune-prompts`
|
|
31
31
|
- **Local audits** (worktree only to build; no commit, push, PR or channels): `design-check`, `testflight-validation`, `ios-coding-standard`. `testflight-validation` additionally never invokes `altool --upload-app` - a validation run must not be able to ship a build by accident.
|
|
32
32
|
- **Meta-ops**: `setup`, `sync`, `update`, `help`, `refactor`, `test`, `stack`, `manual-test`, `language`
|
|
33
33
|
- **Routines** (user-defined routine registry; the routines they create are local-only and never synced): `save`, `routines`, `forget`
|
|
34
34
|
|
|
35
|
-
The count is
|
|
35
|
+
The count is 55 files and 51 live commands until the four stubs are deleted, at which point both numbers become 51. A stub is still installed and still invocable, so counting it as absent would be wrong; counting it as a command would be worse.
|
|
36
36
|
|
|
37
37
|
> **Inventory drift is a contract violation.** Adding a slash command under `pipeline/commands/multi-agent/` without updating this list + its counterpart Copilot dir (`pipeline/skills/shared/core/multi-agent-<cmd>/`) is a merge blocker. `smoke-commands-skills-parity.sh` enforces command ↔ skill directory parity; `smoke-cross-cli-behavior.sh` enforces behavior parity. This doc is the authoritative command list - bump the count + table together.
|
|
38
38
|
|
|
@@ -95,6 +95,29 @@ halt per the halt-visibility rule), `3` I/O error.
|
|
|
95
95
|
Reads need no wrapper; the rename makes any read see either the old or the new
|
|
96
96
|
document, never a truncated one.
|
|
97
97
|
|
|
98
|
+
**`rev`, and reading before writing back.** Every successful write bumps
|
|
99
|
+
`state.rev`, a counter that only increases. It exists because a read and the
|
|
100
|
+
write that follows it are not one operation. The lock above makes a single write
|
|
101
|
+
atomic and nothing more; the concurrent worktrees named there, and
|
|
102
|
+
`/multi-agent:steer`, which writes into the state file of a task that is still
|
|
103
|
+
running, both land inside the gap between a phase's read and its write-back.
|
|
104
|
+
|
|
105
|
+
A phase that will write back what it read keeps the `rev` it read, re-reads
|
|
106
|
+
immediately before writing, and re-derives its patch when the number has moved.
|
|
107
|
+
`write-state.mjs` takes the higher of the on-disk `rev` and the one in the
|
|
108
|
+
incoming patch, so a stale patch can never walk the counter backwards - but that
|
|
109
|
+
only protects the counter, not the fields. Deciding what to do about a
|
|
110
|
+
concurrent change is the caller's job.
|
|
111
|
+
|
|
112
|
+
A record written before `rev` existed has none: treat a missing `rev` as 0.
|
|
113
|
+
|
|
114
|
+
**Stale locks: liveness outranks age.** A lock is reclaimed when its holder PID
|
|
115
|
+
is no longer alive. A holder that is alive keeps its lock however old the file
|
|
116
|
+
is - the reverse order (age first) is what let a writer delete a live lock and
|
|
117
|
+
lose the update behind it. `WRITE_STATE_LOCK_STALE_MS` now applies only to a
|
|
118
|
+
lock with no readable PID, and `WRITE_STATE_LOCK_ABANDON_MS` (default ten times
|
|
119
|
+
that) is the last-resort ceiling for a PID that has been recycled.
|
|
120
|
+
|
|
98
121
|
**Halt visibility (required, autopilot included).** A halt is never silent. Whenever a phase halts on a hard error (validator failed twice, no subagent returned, dispatch error past fallback, lock irrecoverable), in addition to the `agent-log.md` line: (a) write `state.status = "paused"` and `state.haltReason = "<phase>:<cause>"`; (b) record the cause on the tracker via `phase-tracker.sh meta <phase> halt "<cause>"` and `phase-tracker.sh update <phase> failed`; (c) emit one `>&2` alert line `HALT phase <N>: <cause> - resume with /multi-agent:resume #<id>`; (d) if `prefs.global.usageLog.enabled` is true, emit the end-of-run report so a run that never reaches Phase 7 is still recorded with the phase it stopped at (`state.currentPhase` + `haltReason`) - the emitter no-ops when it is off or unconfigured:
|
|
99
122
|
|
|
100
123
|
```bash
|