@mmerterden/multi-agent-pipeline 16.10.0 → 16.10.1

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 CHANGED
@@ -26,6 +26,14 @@ Internal file-layout changes that don't affect the slash-command surface are sti
26
26
 
27
27
  - **`smoke-website-deploy-identity.sh` (20 assertions).** It runs the script against throwaway repos with real remotes rather than grepping the doc: the happy path lands and pushes, an exported `GIT_AUTHOR_EMAIL` halts with the commit still local, an unchanged tree makes no empty commit, a matching config is preserved while a wrong name is corrected, and missing or non-repository arguments exit 2. Wiring is asserted separately, since a correct script nothing calls is its own failure mode.
28
28
 
29
+ ## [16.10.1] - 2026-08-26
30
+
31
+ ### Fixed
32
+
33
+ - **`write-state.mjs` could delete a live lock and lose a writer's update.** The stale-lock reclaim deleted by path: between judging a lock stale and unlinking it, the holder can release and a third writer can acquire a fresh one, so the unlink removed a *live* lock and two writers then held it. It is the same failure the PID-window comment in that file already describes, at a different point in the acquire loop, and it survived because it only reproduces under load - `smoke-write-state.sh` failed inside a full gate run and passed 12/12 when run alone. Reclaim is now by identity: the inode and mtime judged stale must still be the file at that path, otherwise it belongs to somebody else and is left alone. Twelve runs under artificial load are clean, which is evidence and not proof - a race cannot be proven absent.
34
+
35
+ - **Counts that had drifted from the tree.** `skills-index.md` and `skills/shared/README.md` still said 208 skills against 210 on disk; both are generated, so they were regenerated rather than hand-edited. `/multi-agent:update` quoted "245 scripts, 208 skills" for what an install lays down; it is 263 and 210. A comment in `smoke-command-inventory.sh` used "51 commands" as its example, which is the kind of number that goes stale the moment a command lands - it now says what it means without pinning a figure.
36
+
29
37
  ## [16.10.0] - 2026-08-26
30
38
 
31
39
  Three debts the last few releases kept naming, closed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmerterden/multi-agent-pipeline",
3
- "version": "16.10.0",
3
+ "version": "16.10.1",
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",
@@ -184,7 +184,7 @@ A git clone of the pipeline repo is a maintainer workspace, kept in sync by `/mu
184
184
  ```
185
185
  Current: v15.6.0 Latest: v15.6.1
186
186
  -> npm pack @{npm-scope}/multi-agent-pipeline@15.6.1
187
- -> node install.js --all (53 commands, 245 scripts, 208 skills)
187
+ -> node install.js --all (53 commands, 263 scripts, 210 skills)
188
188
  -> migrate-prefs.mjs (0 changes - already v2.6.0)
189
189
 
190
190
  ✓ Updated: v15.6.0 → v15.6.1
@@ -100,12 +100,26 @@ async function acquireLock(
100
100
  /* already gone */
101
101
  }
102
102
  if (err.code !== "EEXIST") throw err;
103
- if (isLockStale(lockPath, staleMs)) {
104
- // Holder crashed or the lock outlived any plausible writer - reclaim it.
103
+ // Reclaim by identity, never by path. Between judging a lock stale and
104
+ // deleting it, the holder can release and a THIRD writer can acquire a
105
+ // fresh one - and an unlink by path deletes that live lock, after which
106
+ // two writers hold it and one update is lost. Same failure the PID window
107
+ // above once caused, at a different point in the loop; it survived because
108
+ // it only reproduces under load, where the gap is wide enough to lose.
109
+ //
110
+ // The inode is the identity: a newly acquired lock is a different file
111
+ // even at the same path. Delete only if the file we judged is still the
112
+ // file that is there.
113
+ const stale = lockIdentityIfStale(lockPath, staleMs);
114
+ if (stale) {
105
115
  try {
106
- unlinkSync(lockPath);
116
+ const now = statSync(lockPath);
117
+ if (now.ino === stale.ino && now.mtimeMs === stale.mtimeMs) {
118
+ unlinkSync(lockPath);
119
+ }
120
+ // Changed under us: somebody else's live lock. Leave it and retry.
107
121
  } catch {
108
- /* another writer won the race - fall through and retry */
122
+ /* vanished on its own - fall through and retry */
109
123
  }
110
124
  continue;
111
125
  }
@@ -128,28 +142,32 @@ async function acquireLock(
128
142
  * @param {number} staleMs
129
143
  * @returns {boolean}
130
144
  */
131
- function isLockStale(lockPath, staleMs) {
145
+ function lockIdentityIfStale(lockPath, staleMs) {
132
146
  let pid;
133
147
  let mtimeMs;
148
+ let ino;
134
149
  try {
135
150
  pid = parseInt(readFileSync(lockPath, "utf-8").trim(), 10);
136
- mtimeMs = statSync(lockPath).mtimeMs;
151
+ const st = statSync(lockPath);
152
+ mtimeMs = st.mtimeMs;
153
+ ino = st.ino;
137
154
  } catch {
138
155
  // Lock vanished between EEXIST and our read - let the retry re-open it.
139
- return false;
156
+ return null;
140
157
  }
141
- if (Date.now() - mtimeMs > staleMs) return true;
158
+ const identity = { ino, mtimeMs };
159
+ if (Date.now() - mtimeMs > staleMs) return identity;
142
160
  // An unreadable PID is NOT proof of staleness. Treating it as such is what
143
161
  // let a writer delete a live lock and lose another writer's update. With the
144
162
  // link-based acquire above a lock is never observable without its PID, so
145
163
  // this can only be genuine corruption - which the staleMs check reclaims
146
164
  // anyway, without racing a writer that is merely mid-flight.
147
- if (!Number.isInteger(pid) || pid <= 0) return false;
165
+ if (!Number.isInteger(pid) || pid <= 0) return null;
148
166
  try {
149
167
  process.kill(pid, 0); // probe liveness without signalling
150
- return false; // holder alive
168
+ return null; // holder alive
151
169
  } catch (err) {
152
- return err.code === "ESRCH"; // no such process - stale
170
+ return err.code === "ESRCH" ? identity : null; // no such process - stale
153
171
  }
154
172
  }
155
173
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "skillCount": 208,
3
+ "skillCount": 210,
4
4
  "entries": [
5
5
  {
6
6
  "name": "accessibility-compliance-accessibility-audit",
@@ -961,7 +961,7 @@
961
961
  },
962
962
  {
963
963
  "name": "multi-agent-analysis",
964
- "description": "Standalone feature-spec analysis (v3 template). Platform-agnostic concept layer with repo-driven convention extraction and per-platform Pass B render. 23 sections in Full mode; 8 of them in Lite mode (auto for small features). Collects Figma / Swagger / Confluence / Jira / Standards / Firebase / rep",
964
+ "description": "Standalone feature-spec analysis. Two profiles picked at intake: global (23-section development handoff, 8 of them in Lite mode) or corporate (IG/UC/FG requirements document with traceability matrices). Platform-agnostic concept layer with repo-driven convention extraction and per-platform Pass B re",
965
965
  "platform": null,
966
966
  "group": "core",
967
967
  "plugin": null,
@@ -1102,6 +1102,17 @@
1102
1102
  "triggerPaths": [],
1103
1103
  "relativePath": "shared/core/multi-agent-diff-explain/SKILL.md"
1104
1104
  },
1105
+ {
1106
+ "name": "multi-agent-feedback",
1107
+ "description": "Send one message to the maintainer: a bug, an idea or a question. Only the text you type is sent - no logs, no repo names, no paths. Shows the payload and asks before sending. Use when a run went wrong and the maintainer should know.",
1108
+ "platform": null,
1109
+ "group": "core",
1110
+ "plugin": null,
1111
+ "invokeAs": "multi-agent-feedback",
1112
+ "triggerKeywords": [],
1113
+ "triggerPaths": [],
1114
+ "relativePath": "shared/core/multi-agent-feedback/SKILL.md"
1115
+ },
1105
1116
  {
1106
1117
  "name": "multi-agent-forget",
1107
1118
  "description": "Remove a saved /multi-agent routine (created by /multi-agent:save): deletes its local-only command and its registry entry. Asks which one and confirms. Use when a saved routine is no longer wanted and should be removed.",
@@ -1311,6 +1322,17 @@
1311
1322
  "triggerPaths": [],
1312
1323
  "relativePath": "shared/core/multi-agent-review/SKILL.md"
1313
1324
  },
1325
+ {
1326
+ "name": "multi-agent-review-analysis",
1327
+ "description": "Review a written analysis document instead of a diff: resolve it from a path, a Confluence page or a Jira issue, run the deterministic gates first, then a parallel model review. Findings cite the Locked rule they break. Never edits the document. Use when an analysis needs judging before development ",
1328
+ "platform": null,
1329
+ "group": "core",
1330
+ "plugin": null,
1331
+ "invokeAs": "multi-agent-review-analysis",
1332
+ "triggerKeywords": [],
1333
+ "triggerPaths": [],
1334
+ "relativePath": "shared/core/multi-agent-review-analysis/SKILL.md"
1335
+ },
1314
1336
  {
1315
1337
  "name": "multi-agent-review-issue",
1316
1338
  "description": "Assess whether a GitHub issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / stack readiness, then (after confirm) post the gaps as an issue comment. Read-only on code. Use when deciding whether a GitHub issue is specified well enough to ha",
@@ -2,11 +2,11 @@
2
2
 
3
3
  Single source of truth for skills delivered to both Claude Code (`~/.claude/skills/`) and Copilot CLI (`~/.copilot/skills/`) by the installer.
4
4
 
5
- **Total:** 208 skills (54 core + 154 external). Auto-generated by `scripts/gen-skills-index.mjs` - do not edit by hand.
5
+ **Total:** 210 skills (56 core + 154 external). Auto-generated by `scripts/gen-skills-index.mjs` - do not edit by hand.
6
6
 
7
7
  ## Directory layout
8
8
 
9
- - **`core/`** - 54 `multi-agent*` orchestration skills that are pipeline-critical. Edits here are core-code changes.
9
+ - **`core/`** - 56 `multi-agent*` orchestration skills that are pipeline-critical. Edits here are core-code changes.
10
10
  - **`external/`** - 154 iOS / Android / generic skills imported from the upstream skill library. Mirrors of third-party guidance.
11
11
  - Install destinations (ADR-0009): Claude Code gets NO local copy of `external/` - it loads those skills from the `multi-agent-plugins` marketplace, namespaced (`ai-<stack>-toolkit:<name>`); only the two compliance catalogs from `core/` land in `~/.claude/skills/`. Copilot CLI and Codex CLI receive a flat copy filtered to the enabled stacks. `external/` remains the single authoring source that `build-stack-plugins.mjs` publishes from.
12
12
 
@@ -14,7 +14,7 @@ Source layout is logical grouping only - skill discovery at runtime is unchang
14
14
 
15
15
  ## Categories
16
16
 
17
- - [Pipeline Orchestration](#pipeline-orchestration) - 54
17
+ - [Pipeline Orchestration](#pipeline-orchestration) - 56
18
18
  - [iOS / Apple Ecosystem](#ios-apple-ecosystem) - 90
19
19
  - [Android / Kotlin](#android-kotlin) - 13
20
20
  - [Web / Frontend](#web-frontend) - 10
@@ -28,7 +28,7 @@ Source layout is logical grouping only - skill discovery at runtime is unchang
28
28
  | [`apple-archive-compliance`](./core/apple-archive-compliance/) | `core` | Apple App Store Review compliance - wraps the multi-agent-toolkit-mcp `ios_app_store_audit` tool (18-rule deep scan) with ITMS error code |
29
29
  | [`google-play-compliance`](./core/google-play-compliance/) | `core` | Google Play Store publication compliance - bundletool + aapt2 + apksigner orchestration + 21-rule policy catalog with Play Console error c |
30
30
  | [`multi-agent`](./core/multi-agent/) | `core` | Task orchestrator: runs the full pipeline from a Jira ID or GitHub Issue URL - analysis → plan → TDD development → parallel review (Fable |
31
- | [`multi-agent-analysis`](./core/multi-agent-analysis/) | `core` | Standalone feature-spec analysis (v3 template). Platform-agnostic concept layer with repo-driven convention extraction and per-platform Pass |
31
+ | [`multi-agent-analysis`](./core/multi-agent-analysis/) | `core` | Standalone feature-spec analysis. Two profiles picked at intake: global (23-section development handoff, 8 of them in Lite mode) or corporat |
32
32
  | [`multi-agent-analysis-resolve`](./core/multi-agent-analysis-resolve/) | `core` | Resolve the Section 20 Risks and Open Questions of an analysis v3 document one row at a time: up to 3 source-labeled answer candidates per r |
33
33
  | [`multi-agent-autopilot`](./core/multi-agent-autopilot/) | `core` | Launch any task in autopilot mode: skips every confirmation, runs end-to-end autonomously. Use when a task should run end to end with no con |
34
34
  | [`multi-agent-build-optimize`](./core/multi-agent-build-optimize/) | `core` | Wrapper that dispatches to xcode-build-orchestrator on iOS repos. Benchmarks the current Xcode build, runs compilation / project / SPM analy |
@@ -41,6 +41,7 @@ Source layout is logical grouping only - skill discovery at runtime is unchang
41
41
  | [`multi-agent-dev-local`](./core/multi-agent-dev-local/) | `core` | Removed in v16.0.0. Its worktree-free twin is /multi-agent:local, which asks the same depth question; answer Short there. Invoke only to see |
42
42
  | [`multi-agent-dev-local-autopilot`](./core/multi-agent-dev-local-autopilot/) | `core` | Retired alongside its worktree twin in v16.0.0, with nothing standing in for it. Invoke only to be pointed at /multi-agent:local-autopilot o |
43
43
  | [`multi-agent-diff-explain`](./core/multi-agent-diff-explain/) | `core` | Map Phase 4 triage findings to branch diff lines. Read-only post-hoc command, used after review to answer 'which finding lines up with which |
44
+ | [`multi-agent-feedback`](./core/multi-agent-feedback/) | `core` | Send one message to the maintainer: a bug, an idea or a question. Only the text you type is sent - no logs, no repo names, no paths. Shows t |
44
45
  | [`multi-agent-forget`](./core/multi-agent-forget/) | `core` | Remove a saved /multi-agent routine (created by /multi-agent:save): deletes its local-only command and its registry entry. Asks which one an |
45
46
  | [`multi-agent-garbage-collect`](./core/multi-agent-garbage-collect/) | `core` | Sweep leftover /tmp scratch (picker state, review diffs, channel payloads, analysis drafts) from past runs. Dry-run first; confirms before d |
46
47
  | [`multi-agent-help`](./core/multi-agent-help/) | `core` | Multi-agent pipeline usage guide - renders in EN or TR per prefs.global.outputLanguage (falls back to promptLanguage for backward compatib |
@@ -60,6 +61,7 @@ Source layout is logical grouping only - skill discovery at runtime is unchang
60
61
  | [`multi-agent-resume`](./core/multi-agent-resume/) | `core` | Resume a stopped or failed task from the phase where it left off. Use when a task stopped or failed and should carry on from where it left o |
61
62
  | [`multi-agent-resume-local`](./core/multi-agent-resume-local/) | `core` | Continue already-done LOCAL work through the pipeline tail: Review → Build+Test → Commit/PR → Report (technical analysis + Jira test-scenari |
62
63
  | [`multi-agent-review`](./core/multi-agent-review/) | `core` | Run parallel review on a branch diff or a Pull Request: 2 models on Claude Code (Fable + Sonnet), 3 models on Copilot CLI (GPT + Opus + Sonn |
64
+ | [`multi-agent-review-analysis`](./core/multi-agent-review-analysis/) | `core` | Review a written analysis document instead of a diff: resolve it from a path, a Confluence page or a Jira issue, run the deterministic gates |
63
65
  | [`multi-agent-review-issue`](./core/multi-agent-review-issue/) | `core` | Assess whether a GitHub issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / sta |
64
66
  | [`multi-agent-review-jira`](./core/multi-agent-review-jira/) | `core` | Assess whether a Jira issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / stack |
65
67
  | [`multi-agent-routines`](./core/multi-agent-routines/) | `core` | List your saved /multi-agent routines (from /multi-agent:save) with what each one does, rendered in outputLanguage. Use when asked which sav |
@@ -3,7 +3,7 @@
3
3
  > Auto-generated by `pipeline/scripts/build-skills-index.mjs` - do not hand-edit.
4
4
  > Regenerate with `node pipeline/scripts/build-skills-index.mjs`.
5
5
 
6
- **208 skills** across 2 groups.
6
+ **210 skills** across 2 groups.
7
7
 
8
8
  | Group | Name | Platform | Description |
9
9
  |-------|------|----------|-------------|
@@ -94,7 +94,7 @@
94
94
  | external | `metrickit-diagnostics` | - | Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMet |
95
95
  | external | `monorepo-architect` | - | Expert in monorepo architecture, build systems, and dependency management at scale. Masters Nx, Turborepo, Bazel, and Lerna for efficient mu |
96
96
  | core | `multi-agent` | - | Task orchestrator: runs the full pipeline from a Jira ID or GitHub Issue URL - analysis → plan → TDD development → parallel review (Fable |
97
- | core | `multi-agent-analysis` | - | Standalone feature-spec analysis (v3 template). Platform-agnostic concept layer with repo-driven convention extraction and per-platform Pass |
97
+ | core | `multi-agent-analysis` | - | Standalone feature-spec analysis. Two profiles picked at intake: global (23-section development handoff, 8 of them in Lite mode) or corporat |
98
98
  | core | `multi-agent-analysis-resolve` | - | Resolve the Section 20 Risks and Open Questions of an analysis v3 document one row at a time: up to 3 source-labeled answer candidates per r |
99
99
  | core | `multi-agent-autopilot` | - | Launch any task in autopilot mode: skips every confirmation, runs end-to-end autonomously. Use when a task should run end to end with no con |
100
100
  | core | `multi-agent-build-optimize` | - | Wrapper that dispatches to xcode-build-orchestrator on iOS repos. Benchmarks the current Xcode build, runs compilation / project / SPM analy |
@@ -107,6 +107,7 @@
107
107
  | core | `multi-agent-dev-local` | - | Removed in v16.0.0. Its worktree-free twin is /multi-agent:local, which asks the same depth question; answer Short there. Invoke only to see |
108
108
  | core | `multi-agent-dev-local-autopilot` | - | Retired alongside its worktree twin in v16.0.0, with nothing standing in for it. Invoke only to be pointed at /multi-agent:local-autopilot o |
109
109
  | core | `multi-agent-diff-explain` | - | Map Phase 4 triage findings to branch diff lines. Read-only post-hoc command, used after review to answer 'which finding lines up with which |
110
+ | core | `multi-agent-feedback` | - | Send one message to the maintainer: a bug, an idea or a question. Only the text you type is sent - no logs, no repo names, no paths. Shows t |
110
111
  | core | `multi-agent-forget` | - | Remove a saved /multi-agent routine (created by /multi-agent:save): deletes its local-only command and its registry entry. Asks which one an |
111
112
  | core | `multi-agent-garbage-collect` | - | Sweep leftover /tmp scratch (picker state, review diffs, channel payloads, analysis drafts) from past runs. Dry-run first; confirms before d |
112
113
  | core | `multi-agent-help` | - | Multi-agent pipeline usage guide - renders in EN or TR per prefs.global.outputLanguage (falls back to promptLanguage for backward compatib |
@@ -126,6 +127,7 @@
126
127
  | core | `multi-agent-resume` | - | Resume a stopped or failed task from the phase where it left off. Use when a task stopped or failed and should carry on from where it left o |
127
128
  | core | `multi-agent-resume-local` | - | Continue already-done LOCAL work through the pipeline tail: Review → Build+Test → Commit/PR → Report (technical analysis + Jira test-scenari |
128
129
  | core | `multi-agent-review` | - | Run parallel review on a branch diff or a Pull Request: 2 models on Claude Code (Fable + Sonnet), 3 models on Copilot CLI (GPT + Opus + Sonn |
130
+ | core | `multi-agent-review-analysis` | - | Review a written analysis document instead of a diff: resolve it from a path, a Confluence page or a Jira issue, run the deterministic gates |
129
131
  | core | `multi-agent-review-issue` | - | Assess whether a GitHub issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / sta |
130
132
  | core | `multi-agent-review-jira` | - | Assess whether a Jira issue is ready for multi-agent development: fetch it, grade scope / acceptance criteria / repro / design / API / stack |
131
133
  | core | `multi-agent-routines` | - | List your saved /multi-agent routines (from /multi-agent:save) with what each one does, rendered in outputLanguage. Use when asked which sav |