@mmerterden/multi-agent-pipeline 20.13.0 → 20.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +8 -6
  3. package/README.tr.md +7 -5
  4. package/docs/architecture.md +3 -3
  5. package/docs/ecosystem.md +5 -5
  6. package/docs/facts.json +4 -4
  7. package/install/catalog-history.json +1 -1
  8. package/manifest.json +156 -96
  9. package/package.json +1 -1
  10. package/pipeline/commands/multi-agent/analysis/SKILL.md +11 -80
  11. package/pipeline/commands/multi-agent/autopilot/SKILL.md +2 -23
  12. package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +24 -45
  13. package/pipeline/commands/multi-agent/channels/SKILL.md +11 -63
  14. package/pipeline/commands/multi-agent/design-check/SKILL.md +43 -178
  15. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +2 -0
  16. package/pipeline/commands/multi-agent/estimate/SKILL.md +65 -0
  17. package/pipeline/commands/multi-agent/help/SKILL.md +5 -546
  18. package/pipeline/commands/multi-agent/kill/SKILL.md +13 -18
  19. package/pipeline/commands/multi-agent/refactor/SKILL.md +7 -76
  20. package/pipeline/commands/multi-agent/review-analysis/SKILL.md +1 -1
  21. package/pipeline/commands/multi-agent/scenario-audit/SKILL.md +79 -0
  22. package/pipeline/commands/multi-agent/serve/SKILL.md +6 -3
  23. package/pipeline/commands/multi-agent/setup/SKILL.md +12 -365
  24. package/pipeline/commands/multi-agent/status/SKILL.md +2 -0
  25. package/pipeline/commands/multi-agent/store-ready/SKILL.md +56 -184
  26. package/pipeline/commands/multi-agent/sync/SKILL.md +14 -267
  27. package/pipeline/contract/CHANGELOG.md +52 -0
  28. package/pipeline/contract/README.md +41 -1
  29. package/pipeline/contract/build.mjs +49 -7
  30. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  31. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  32. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  33. package/pipeline/contract/fixtures/launch-plan.json +1 -2
  34. package/pipeline/contract/fixtures/runs-awaiting-question.json +10 -3
  35. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  36. package/pipeline/contract/fixtures/runs-failed.json +19 -6
  37. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +25 -8
  38. package/pipeline/contract/fixtures/runs-pr-opened.json +25 -8
  39. package/pipeline/contract/fixtures/runs-running.json +31 -4
  40. package/pipeline/contract/frozen/toolbox.json +13 -0
  41. package/pipeline/contract/manifest.json +112 -10
  42. package/pipeline/contract/types/index.d.ts +186 -17
  43. package/pipeline/lib/claude-sessions.mjs +93 -0
  44. package/pipeline/lib/credential-resolve.mjs +39 -0
  45. package/pipeline/lib/gc-report.sh +64 -0
  46. package/pipeline/lib/unattended-settings-location.mjs +4 -0
  47. package/pipeline/lib/workspace-trust.mjs +73 -0
  48. package/pipeline/multi-agent-refs/analysis/intake.md +5 -3
  49. package/pipeline/multi-agent-refs/analysis/locked.md +8 -7
  50. package/pipeline/multi-agent-refs/analysis/render.md +4 -3
  51. package/pipeline/multi-agent-refs/analysis/resolve.md +1 -1
  52. package/pipeline/multi-agent-refs/analysis/resume.md +37 -0
  53. package/pipeline/multi-agent-refs/analysis/reusable-refs.md +25 -0
  54. package/pipeline/multi-agent-refs/channels/board.md +17 -0
  55. package/pipeline/multi-agent-refs/channels/multi-repo.md +15 -0
  56. package/pipeline/multi-agent-refs/cross-cli-contract.md +4 -4
  57. package/pipeline/multi-agent-refs/design-check/build-launch.md +14 -0
  58. package/pipeline/multi-agent-refs/design-check/compare.md +44 -0
  59. package/pipeline/multi-agent-refs/design-check/drive-capture.md +35 -0
  60. package/pipeline/multi-agent-refs/design-check/export.md +37 -0
  61. package/pipeline/multi-agent-refs/design-check/figma-mapping.md +11 -0
  62. package/pipeline/multi-agent-refs/design-check/init-inventory.md +56 -0
  63. package/pipeline/multi-agent-refs/design-check/mcp-currency-gate.md +41 -0
  64. package/pipeline/multi-agent-refs/features/analysis-outline.md +55 -0
  65. package/pipeline/multi-agent-refs/features/analysis-sources.md +60 -0
  66. package/pipeline/multi-agent-refs/help/en.md +273 -0
  67. package/pipeline/multi-agent-refs/help/tr.md +271 -0
  68. package/pipeline/multi-agent-refs/orchestrator/operations.md +99 -0
  69. package/pipeline/multi-agent-refs/orchestrator/phase-0-projects.md +72 -0
  70. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +40 -0
  71. package/pipeline/multi-agent-refs/orchestrator/phase-4-5-projects.md +68 -0
  72. package/pipeline/multi-agent-refs/orchestrator/skill-loading.md +99 -0
  73. package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -2
  74. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +1 -1
  75. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +1 -1
  76. package/pipeline/multi-agent-refs/picker-contract.md +29 -0
  77. package/pipeline/multi-agent-refs/refactor/drift.md +49 -0
  78. package/pipeline/multi-agent-refs/refactor/run-errors.md +46 -0
  79. package/pipeline/multi-agent-refs/setup/discovery.md +84 -0
  80. package/pipeline/multi-agent-refs/setup/figma.md +27 -0
  81. package/pipeline/multi-agent-refs/setup/identity-routing.md +60 -0
  82. package/pipeline/multi-agent-refs/setup/token-save-flow.md +201 -0
  83. package/pipeline/multi-agent-refs/store-ready/build.md +49 -0
  84. package/pipeline/multi-agent-refs/store-ready/gate-1-static.md +37 -0
  85. package/pipeline/multi-agent-refs/store-ready/gate-3-policy.md +31 -0
  86. package/pipeline/multi-agent-refs/store-ready/preflight.md +50 -0
  87. package/pipeline/multi-agent-refs/store-ready/report.md +40 -0
  88. package/pipeline/multi-agent-refs/sync/codex.md +43 -0
  89. package/pipeline/multi-agent-refs/sync/dev-toolkit.md +174 -0
  90. package/pipeline/multi-agent-refs/sync/stack-plugins.md +51 -0
  91. package/pipeline/multi-agent-refs/tracker-contract.md +29 -4
  92. package/pipeline/schemas/agent-state.schema.json +13 -4
  93. package/pipeline/schemas/analysis-spec.schema.json +56 -4
  94. package/pipeline/schemas/autopilot-off-request.schema.json +20 -0
  95. package/pipeline/schemas/autopilot-off.schema.json +24 -0
  96. package/pipeline/schemas/autopilot-status.schema.json +63 -0
  97. package/pipeline/schemas/contract-error.schema.json +13 -2
  98. package/pipeline/schemas/gc-request.schema.json +31 -0
  99. package/pipeline/schemas/gc.schema.json +116 -0
  100. package/pipeline/schemas/kill-request.schema.json +22 -0
  101. package/pipeline/schemas/kill.schema.json +118 -0
  102. package/pipeline/schemas/launch-plan.schema.json +11 -2
  103. package/pipeline/schemas/launch-request.schema.json +7 -2
  104. package/pipeline/schemas/launch.json +65 -4
  105. package/pipeline/schemas/launch.schema.json +23 -8
  106. package/pipeline/schemas/prefs.schema.json +3 -3
  107. package/pipeline/schemas/repos.schema.json +39 -0
  108. package/pipeline/schemas/resume-request.schema.json +37 -0
  109. package/pipeline/schemas/run-log.schema.json +32 -0
  110. package/pipeline/schemas/run-questions.json +5 -1
  111. package/pipeline/schemas/run-questions.schema.json +1 -1
  112. package/pipeline/schemas/runs-index.schema.json +59 -3
  113. package/pipeline/scripts/_run-paths.mjs +8 -2
  114. package/pipeline/scripts/analysis-conform-coverage.mjs +96 -0
  115. package/pipeline/scripts/analysis-sources.mjs +264 -0
  116. package/pipeline/scripts/autopilot-control.mjs +223 -0
  117. package/pipeline/scripts/autopilot-runner.mjs +14 -39
  118. package/pipeline/scripts/build-references.mjs +5 -1
  119. package/pipeline/scripts/confluence-readback.mjs +4 -23
  120. package/pipeline/scripts/contract-server.mjs +373 -7
  121. package/pipeline/scripts/doctor.mjs +5 -2
  122. package/pipeline/scripts/estimate.mjs +223 -0
  123. package/pipeline/scripts/gate-ledger.mjs +64 -3
  124. package/pipeline/scripts/gc-plan.mjs +288 -0
  125. package/pipeline/scripts/gc-refs.sh +33 -2
  126. package/pipeline/scripts/gc-tmp.sh +33 -2
  127. package/pipeline/scripts/gc-worktrees.sh +42 -3
  128. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -24
  129. package/pipeline/scripts/launch-request.mjs +182 -10
  130. package/pipeline/scripts/phase-tracker.sh +62 -1
  131. package/pipeline/scripts/run-kill.mjs +232 -0
  132. package/pipeline/scripts/run-log.mjs +111 -0
  133. package/pipeline/scripts/runs-index.mjs +177 -11
  134. package/pipeline/scripts/scenario-audit.mjs +245 -0
  135. package/pipeline/scripts/validate-analysis-doc.mjs +84 -6
  136. package/pipeline/skills/.skill-manifest.json +24 -16
  137. package/pipeline/skills/shared/README.md +5 -3
  138. package/pipeline/skills/shared/core/multi-agent/SKILL.md +51 -450
  139. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +7 -1
  140. package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +26 -44
  141. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +31 -127
  142. package/pipeline/skills/shared/core/multi-agent-estimate/SKILL.md +61 -0
  143. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +14 -19
  144. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +7 -76
  145. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
  146. package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +1 -1
  147. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
  148. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
  149. package/pipeline/skills/shared/core/multi-agent-scenario-audit/SKILL.md +77 -0
  150. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +6 -3
  151. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +205 -324
  152. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +5 -0
  153. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +4 -4
@@ -15,8 +15,7 @@ Catch, before you upload, what App Store Connect or the Play Console would send
15
15
  back after you do.
16
16
 
17
17
  **Local-only.** No commits, no push, no PR, no channels unless you ask at the end.
18
- A worktree, when one is needed, exists only to archive without touching your
19
- working tree.
18
+ A worktree, when needed, only archives without touching your working tree.
20
19
 
21
20
  **It never ships.** iOS runs `--validate-app`, never `--upload-app`. Android
22
21
  never commits a Play edit: when Google Play is onboarded, Gate 2 uploads the
@@ -26,12 +25,17 @@ accident.
26
25
 
27
26
  **Input**: $ARGUMENTS
28
27
 
28
+ ## Gotchas
29
+
30
+ - A skipped gate is reported as skipped with its reason, never folded into a pass: a green static audit says nothing about what the store's validator will say.
31
+ - The Play throwaway edit is deleted whether validation passes or fails.
32
+ - Gate 3 reads source, not the binary: a policy finding cites `file:line` in the repo the package was built from.
33
+
29
34
  ## Why three gates, and why the same three on both platforms
30
35
 
31
- Each gate sees something the others structurally cannot, and reporting one of them
32
- as "the check" is how a build passes locally and gets rejected anyway. The shapes
33
- are the same on iOS and Android because the failure modes are: a malformed package,
34
- a package the store itself refuses, and a policy a human enforces.
36
+ Each gate sees what the others cannot, so no single one is "the check". The
37
+ failure modes are the same on both platforms: a malformed package, a package the
38
+ store refuses, a policy a human enforces.
35
39
 
36
40
  | Gate | Sees | Blind to |
37
41
  |---|---|---|
@@ -47,12 +51,10 @@ a package the store itself refuses, and a policy a human enforces.
47
51
  | 2 Authoritative | `ios_testflight_validate({ipa_path, platform: "ios", <credentials>})` → `xcrun altool --validate-app`, plus `store_asc_next_build_number` for whether the build number is already used. Needs an `.ipa` + credentials | With `google_play` onboarded: `store_play_validate_bundle({package_name, bundle_path})` - Google validates the `.aab` in a throwaway Publishing API edit that is then deleted, never committed. Without it, Play's check exists only server-side and nothing local reproduces it, so this gate reports `SKIPPED (no local Play validator)` with the reason `Google Play not onboarded`. Do not substitute `bundletool validate` - that is Gate 1 |
48
52
  | 3 Policy | `ai-ios-toolkit:app-store-review` skill vs repo source | `ai-android-toolkit:play-store-review` skill vs repo source |
49
53
 
50
- Gate 2's asymmetry is real and is reported as an asymmetry, not smoothed over. On
51
- iOS it is the only gate that catches a version+build pair already used - the most
52
- common wasted upload. On Android nothing local reproduces it: Gate 2 runs only when
53
- Google Play is onboarded and the user approves the upload into a throwaway edit.
54
- Without both, an Android run clears at most 2 of 3 gates and must never print
55
- `passed`.
54
+ Gate 2's asymmetry is reported, not smoothed over. On iOS it is the only gate that
55
+ catches a version+build pair already used. On Android it runs only with Google Play
56
+ onboarded and the throwaway-edit upload approved; without both, an Android run
57
+ clears at most 2 of 3 gates and never prints `passed`.
56
58
 
57
59
  The `store_*` tools need `@mmerterden/multi-agent-toolkit-mcp` ≥ v3.17.0. On an
58
60
  older server they are absent, and each branch below that uses one falls back to
@@ -94,22 +96,13 @@ English, per `$HOME/.claude/multi-agent-refs/picker-contract.md`. Print the
94
96
 
95
97
  1. **Repo** - from `prefs.projects` matching the detected platform. A single match
96
98
  auto-resolves (say so in the breadcrumb, do not silently skip the step).
97
- 2. **Branch** - the branch to validate. Resolution order:
98
- - `git fetch --prune` first, capturing **stderr**. **If the fetch fails, do not
99
- silently fall back to a cached ref**, and **classify before naming a cause** -
100
- the same rule as the pipeline's own remote gate:
101
-
102
- | stderr contains | Cause | Remedy |
103
- |---|---|---|
104
- | `could not read Password`, `Authentication failed`, `403` | credential | store the PAT in the credential helper or switch the remote to SSH. **A VPN cannot fix this**, and the base ref being stale is unrelated to what broke - do not offer the cached-ref fallback. |
105
- | `Could not resolve host`, `Operation timed out`, `Connection refused` | network | retry / continue on the cached ref with an explicit warning / switch remote / abort, per `$HOME/.claude/multi-agent-refs/rules.md` |
106
- | `Repository not found`, `404` | wrong remote | show `git remote -v` and ask |
107
-
108
- Always print the observed stderr line next to the classification. Asserting
109
- `unreachable (VPN/DNS)` for a missing-credential error that returns in under a
110
- second sends the user to fix something that was never broken.
111
- - Offer the current branch, the default branch, and any `release/*` /
112
- `tkdevelop/*` heads.
99
+ 2. **Branch** - the branch to validate. Run `git fetch --prune` first, capturing
100
+ **stderr**. **If the fetch fails, do not silently fall back to a cached ref**, and
101
+ **classify before naming a cause** (credential / network / wrong remote), printing
102
+ the observed stderr line next to the classification. A credential failure never
103
+ gets the cached-ref fallback. Then offer the current branch, the default branch,
104
+ and any `release/*` / `tkdevelop/*` heads.
105
+ Full procedure: `$HOME/.claude/multi-agent-refs/store-ready/preflight.md`. Read it for the fetch-failure table.
113
106
  3. **Mode** - how the build is obtained:
114
107
  - `Supply a build` (Mode B, default) - fastest, no signing needed in-run.
115
108
  - `Build from this branch` (Mode A) - iOS needs a distribution certificate and
@@ -120,33 +113,17 @@ English, per `$HOME/.claude/multi-agent-refs/picker-contract.md`. Print the
120
113
 
121
114
  Report every line; a missing prerequisite is a halt, not a warning.
122
115
 
123
- **iOS:**
124
-
125
- ```bash
126
- xcrun --find altool >/dev/null 2>&1 || echo "MISSING: altool (install Xcode)"
127
- xcodebuild -version | head -1
128
- ```
129
-
130
- Then resolve credentials, and **state which tier is active in the report**:
131
-
132
- | Tier | Source | Effect |
133
- |---|---|---|
134
- | 1 | ASC API key - key id, issuer id and `.p8` in the Keychain (`appstore_connect_key_id`, `appstore_connect_issuer_id`, `appstore_connect_private_key`), read by the toolkit through the store reference file. `store_status` reports it as `appStoreConnect.configured` | Gate 2 runs; call `ios_testflight_validate` with neither `api_key_id` nor `apple_id` so it uses that key |
135
- | 2 | Apple ID + app-specific password, referenced as a keychain item | Gate 2 runs |
136
- | 3 | neither | **Gate 2 reports `SKIPPED`, and the run says so in the verdict line** |
137
-
138
- Multi-provider accounts need `--provider-public-id`. When it is not in prefs, run
139
- `ios_testflight_validate({list_providers: true})` once and ask which provider.
116
+ **iOS**: `altool` and `xcodebuild` must resolve. Then resolve credentials and
117
+ **state which tier is active in the report**: tier 1 ASC API key (`store_status`
118
+ reports `appStoreConnect.configured`), tier 2 Apple ID + app-specific password,
119
+ tier 3 neither, where **Gate 2 reports `SKIPPED`, and the run says so in the verdict
120
+ line**. Multi-provider accounts need `--provider-public-id`; ask when it is not in prefs.
140
121
 
141
- **Android:**
122
+ **Android**: `bundletool`, `aapt2` and `apksigner` must resolve.
142
123
 
143
- ```bash
144
- command -v bundletool >/dev/null || echo "MISSING: bundletool"
145
- command -v aapt2 >/dev/null || echo "MISSING: aapt2 (Android SDK build-tools)"
146
- command -v apksigner >/dev/null || echo "MISSING: apksigner (Android SDK build-tools)"
147
- ```
124
+ Full procedure: `$HOME/.claude/multi-agent-refs/store-ready/preflight.md`. Read it for Step 2 (commands, tier table, provider lookup).
148
125
 
149
- Then resolve whether Gate 2 can run. Call `store_status` (no probe) and read
126
+ Then resolve whether Android Gate 2 can run. Call `store_status` (no probe) and read
150
127
  `googlePlay.configured`:
151
128
 
152
129
  | State | Gate 2 |
@@ -155,8 +132,7 @@ Then resolve whether Gate 2 can run. Call `store_status` (no probe) and read
155
132
  | `googlePlay.configured: true` and `MULTI_AGENT_UNATTENDED=1` | `SKIPPED (no local Play validator)`, reason: the toolkit refuses the upload in an unattended run |
156
133
  | not configured, or no `store_status` tool | `SKIPPED (no local Play validator)`, reason: `Google Play not onboarded` (`/multi-agent:setup` Step 3d) |
157
134
 
158
- Say which one it is: a user without the credential will go looking for one, and
159
- one with it needs to know why Gate 2 did not run.
135
+ Say which one it is.
160
136
 
161
137
  Credentials come from `/multi-agent:setup`; never prompt for a secret value in
162
138
  chat.
@@ -178,81 +154,30 @@ findings.
178
154
 
179
155
  ## Step 3 - obtain the build
180
156
 
181
- ### Mode B - a build you supply
182
-
183
- - **iOS `.xcarchive`** → Gate 1 runs on it. To reach Gate 2 the archive must be
184
- exported, so run `ios_export_ipa` (see Mode A for the signing inputs).
185
- - **iOS `.ipa` only** → **Gate 1 is `SKIPPED (needs .xcarchive)`.** The static audit
186
- reads archive structure an `.ipa` does not carry. Do not present a two-gate run as
187
- a full pass; say which gate did not run and why, and offer to re-run with the
188
- archive.
189
- - **Android `.aab`** → Gate 1 runs in full.
190
- - **Android `.apk` only** → Gate 1 runs the rules that do not need a bundle and
191
- **lists the rules it could not apply**. An `.apk` cannot answer bundle-level
192
- questions (per-ABI splits, dynamic features, Play App Signing expectations).
193
-
194
- When no path is given, pick the newest artifact and print which one you picked:
195
-
196
- ```
197
- iOS: newest .xcarchive under ~/Library/Developer/Xcode/Archives/**
198
- Android: newest .aab under **/build/outputs/bundle/**/*.aab
199
- ```
157
+ Mode B (supply a build) and Mode A (build from the branch). Full procedure:
158
+ `$HOME/.claude/multi-agent-refs/store-ready/build.md`. Read it for Step 3. Rules that hold either way:
200
159
 
201
- Never validate an artifact whose provenance you did not state. "The newest archive"
202
- is a guess the user must be able to correct.
203
-
204
- ### Mode A - build from the branch
205
-
206
- 1. Worktree at `{projectRoot}/.worktrees/{taskId}` on the chosen branch (phase-0-init.md Step 6 convention; the `.worktrees` segment is fixed, not a preference).
207
- **Never under `$HOME`**, never a direct checkout of the main working tree.
208
- 2. Resolve the scheme / module and workspace / project from prefs; ask if ambiguous.
209
- 3. Build:
210
- - **iOS**: `ios_xcodebuild({workspace|project, scheme, action: "archive", configuration: "Release", destination: "generic/platform=iOS"})`.
211
- Note the destination: the simulator default would produce an archive that
212
- cannot be exported for distribution.
213
- - **Android**: `./gradlew bundleRelease` (or the release variant the module
214
- declares). A debug-signed bundle fails Gate 1 signing rules for the wrong
215
- reason - if no release signing config resolves, halt and say so rather than
216
- auditing a debug artifact.
217
- 4. **iOS export**:
218
- `ios_export_ipa({archive_path, output_dir, method: "app-store-connect", team_id, provisioning_profiles?, signing_style?})`.
219
- Leave `allow_provisioning_updates` off unless the user asks: it lets xcodebuild
220
- create or modify profiles in the developer account, which a validation run has no
221
- business doing.
222
- 5. A failed build or export halts with the parsed errors. The usual iOS causes are a
223
- missing distribution certificate, a profile that does not match the bundle ID, or
224
- `signing_style: "manual"` with no `provisioning_profiles` map.
160
+ - **iOS `.ipa` only** → **Gate 1 is `SKIPPED (needs .xcarchive)`**; never present a
161
+ two-gate run as a full pass. An Android `.apk` **lists the rules it could not apply**.
162
+ - Never validate an artifact whose provenance you did not state; print which one you picked.
163
+ - Mode A worktree at `{projectRoot}/.worktrees/{taskId}`, **never under `$HOME`**, never
164
+ a direct checkout of the main working tree.
165
+ - iOS archives with `destination: "generic/platform=iOS"`. Android with no release
166
+ signing config halts; never audit a debug artifact.
167
+ - Leave `allow_provisioning_updates` off unless the user asks.
168
+ - A failed build or export halts with the parsed errors.
225
169
 
226
170
  ## Step 4 - Gate 1, static package audit
227
171
 
228
- - **iOS**: `ios_app_store_audit({archive_path, rules: "all"})`. Consult the
229
- `apple-archive-compliance` skill for what each rule means.
230
-
231
- Needs `@mmerterden/multi-agent-toolkit-mcp` ≥ v3.0.0, which provides the tool. When the
232
- MCP server is not registered, the same 18 rules run directly from the package:
233
-
234
- ```bash
235
- node -e "import('@mmerterden/multi-agent-toolkit-mcp/tools/ios-app-store-audit/index.js').then(m => m.runAudit({ archivePath: '<path>', rules: 'all' }).then(r => console.log(JSON.stringify(r))))"
236
- ```
237
-
238
- Use the fallback only when the tool is genuinely absent, and say in the report
239
- which path ran - a rule set that silently differed between two invocations is
240
- worse than a missing gate.
241
-
242
- Then, whichever path ran, count `<archive>/dSYMs/*.dSYM`. Zero is a blocking
243
- finding: `[SYMBOLS] archive carries no dSYM; crash reports will not symbolicate`,
244
- with the hint `DEBUG_INFORMATION_FORMAT = dwarf-with-dsym` for the Release
245
- configuration. This check runs from the package alone and does not need the
246
- MCP tool.
247
- - **Android**: `android_apk_audit` on the artifact, plus the
248
- `google-play-compliance` skill's 21 rules - `bundletool validate` and manifest
249
- dump, `aapt2 dump badging`, `apksigner verify`, ABI / native scan.
172
+ - **iOS**: `ios_app_store_audit({archive_path, rules: "all"})`, per the
173
+ `apple-archive-compliance` skill. The direct-package fallback runs only when the
174
+ tool is genuinely absent, and the report says which path ran. An archive with no
175
+ dSYM (`<archive>/dSYMs/*.dSYM` count zero) is a blocking `[SYMBOLS]` finding.
176
+ - **Android**: `android_apk_audit` plus the `google-play-compliance` skill's 21 rules.
177
+ A `minifyEnabled true` module whose build produced no `mapping.txt` is a blocking
178
+ `[SYMBOLS]` finding.
250
179
 
251
- Then, when the module has `minifyEnabled true` and the bundle build produced no
252
- `mapping.txt`, raise the same class of blocking finding:
253
- `[SYMBOLS] minified bundle carries no mapping.txt; crash reports will not
254
- deobfuscate`. This check reads the module config and the build output alone
255
- and does not need the MCP tool.
180
+ Full procedure: `$HOME/.claude/multi-agent-refs/store-ready/gate-1-static.md`. Read it for Gate 1.
256
181
 
257
182
  `error` findings are blocking; `warning` is advisory. Group by severity and keep
258
183
  each finding's ITMS / Play policy code - Gate 2 may return the same code on iOS,
@@ -304,32 +229,9 @@ check. If the real upload is later refused as "already used", raise `versionCode
304
229
  Load the platform's review skill and review the repo against it. This is the gate
305
230
  that catches what a human reviewer rejects, so it reads source, not the binary.
306
231
 
307
- **iOS** - `ai-ios-toolkit:app-store-review`:
308
-
309
- | Area | Evidence to gather |
310
- |---|---|
311
- | Purpose strings | every `NS*UsageDescription` in Info.plist - present, specific, user-facing, and matching what the code actually does with the data |
312
- | Privacy manifest | `PrivacyInfo.xcprivacy` exists, declares required-reason APIs, and matches the SDKs actually linked |
313
- | Tracking | if any tracking API or SDK is present, an ATT prompt exists and runs before collection |
314
- | Account deletion | if the app creates accounts, an in-app deletion path exists (guideline 5.1.1(v)) |
315
- | Privacy policy | reachable in-app and in the metadata |
316
- | IAP | anything unlocking features goes through StoreKit, with no external purchase path |
317
- | Sign in with Apple | present when a third-party social login is offered |
318
- | Crash symbolication | a dSYM upload step exists: an Xcode run-script calling `upload-symbols`, or a Crashlytics / Sentry / Datadog upload in CI |
319
-
320
- **Android** - `ai-android-toolkit:play-store-review`:
321
-
322
- | Area | Evidence to gather |
323
- |---|---|
324
- | Permissions | every `uses-permission` justified by a feature, no sensitive permission without its declaration form |
325
- | Data safety | the declared data-safety answers match what the code collects and transmits |
326
- | Target API level | meets the current Play requirement for new releases |
327
- | Privacy policy | reachable in-app and in the listing |
328
- | Billing | anything unlocking features goes through Play Billing, with no external purchase path |
329
- | Account deletion | if the app creates accounts, an in-app deletion path exists, plus the web deletion URL Play requires |
330
- | Content rating | the questionnaire answers match the app's actual content |
331
- | Signing | Play App Signing configured, upload key distinct from the app signing key |
332
- | Crash symbolication | a `mapping.txt` upload exists: the Firebase Crashlytics Gradle plugin, or the Play App Bundle deobfuscation file |
232
+ **iOS** - `ai-ios-toolkit:app-store-review`; **Android** - `ai-android-toolkit:play-store-review`.
233
+ Both cover a `Crash symbolication` row (dSYM upload step / `mapping.txt` upload).
234
+ Full procedure: `$HOME/.claude/multi-agent-refs/store-ready/gate-3-policy.md`. Read it for Gate 3 (the per-platform area tables).
333
235
 
334
236
  For each: `pass` / `fail` / `not-applicable` with the evidence path that justifies
335
237
  it. `not-applicable` needs a reason - an unexamined area is not a pass.
@@ -337,40 +239,10 @@ it. `not-applicable` needs a reason - an unexamined area is not a pass.
337
239
  ## Step 7 - report
338
240
 
339
241
  Write to `~/StoreChecks/<platform>-<repo>-<branch>-<timestamp>/report.md` and print
340
- a summary.
341
-
342
- ```
343
- Verdict: <N> of 3 gates cleared[, <M> skipped]
344
- Platform:<ios|android>
345
- Build: <artifact path> · <bundle id / applicationId> <version> (<build>)
346
- Auth: tier <1|2|none> · <method> (iOS only)
347
- Sweep: <n> findings | SKIPPED (<reason>)
348
-
349
- Gate 1 static audit PASS | FAIL (<n> blocking, <n> advisory) | SKIPPED (<reason>)
350
- Gate 2 store validation PASS | FAIL (<n> issues) | SKIPPED (<reason>)
351
- Gate 3 policy review PASS | FAIL (<n> findings) | <n> not-applicable
352
-
353
- Blocking - fix before uploading
354
- [ITMS-90683] Info.plist: NSCameraUsageDescription missing
355
- guideline 5.1.1 Data Collection and Storage
356
- <hint>
357
- <file:line>
358
-
359
- Advisory
360
- ...
361
-
362
- Not run
363
- Gate 2: no local Play validator - Google Play not onboarded; the authoritative check is server-side only
364
-
365
- Open questions
366
- Gate 2 (Android): versionCode <n> went to a discarded edit; Google does not document whether that reserves it
367
-
368
- Before rollout (human inputs, not verified)
369
- Phased rollout: <1% -> 10% -> 50% -> 100% | full>
370
- Halt thresholds: crash-free < 99.5% (iOS, Android) or ANR > 0.47% (Android) => pause the rollout
371
- Rollback / forward-fix owner: <name>
372
- Forward-fix plan: <one line>
373
- ```
242
+ a summary: verdict line, per-gate status, Blocking / Advisory / Not run / Open
243
+ questions, and the `Before rollout` block (phased rollout, `Halt thresholds`,
244
+ rollback / forward-fix owner, forward-fix plan).
245
+ Full procedure: `$HOME/.claude/multi-agent-refs/store-ready/report.md`. Read it for Step 7 (the report layout).
374
246
 
375
247
  Rules for the report:
376
248
 
@@ -24,6 +24,13 @@ When invoked, it synchronizes all targets in order. It detects what changed, upd
24
24
  | `multi-agent-toolkit` | Run Step 3d only: gate, commit and publish the companion MCP server |
25
25
  | `"change description"` | Apply the description to every target at once |
26
26
 
27
+ ## Gotchas
28
+
29
+ - The pre-push gate is timing-sensitive: under heavy load a deadline test fails closed. Re-run it on a quiet machine; never push with `--no-verify`.
30
+ - `npm publish` answering 202 means the registry is still processing. Verify with the registry's dist-tags before moving `required`, which is asked for every release.
31
+ - The installed tree is localized (Turkish descriptions, `model: opus` while fable is off). Normalize before copying into the repo, or the public tree ships the local form.
32
+ - Synced shell runs on BSD userland: BSD grep has no Perl-regex flag, and `sed` has no `\b` or `\|`. A pattern that silently matches nothing reads as "clean".
33
+
27
34
  ## Targets
28
35
 
29
36
  | # | Target | Path | Direction |
@@ -66,7 +73,7 @@ Run every step automatically:
66
73
  ```
67
74
  Step 0: DOCTOR doctor.mjs - exit 2 or 4 stops the sync
68
75
  Step 1.5: DETECT Compare timestamps, find stale targets
69
- Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 61 sub-command skills)
76
+ Step 2: COPILOT Claude Code -> Copilot CLI (instructions + 63 sub-command skills)
70
77
  Step 2b: CODEX Claude Code -> Codex CLI (1 router skill + sub-command specs as refs + agent TOML)
71
78
  Step 3: REPO Claude Code -> pipeline repo (genericized, personal data scrub, bash -n on all sh)
72
79
  Step 3c: PLUGINS pipeline shared/external -> multi-agent-plugins marketplace (rebuild knowledge/,
@@ -99,7 +106,6 @@ Step 0 gate rules and why: `features/doctor.md`.
99
106
  4. **Do not duplicate** - summary in Copilot, full spec in Claude. Keep this distinction.
100
107
  5. **Report** - show a short diff summary after sync
101
108
 
102
-
103
109
  ---
104
110
 
105
111
  ## Pipeline Repo Sync Rules (CRITICAL)
@@ -168,274 +174,15 @@ Step 0 gate rules and why: `features/doctor.md`.
168
174
 
169
175
  ## Codex Sync (Step 2b)
170
176
 
171
- Unlike the Copilot step, this one does **not** hand-copy files. The Codex tree is a
172
- *transform* of the Claude tree, not a mirror of it, and the transform is real work:
173
-
174
- - the sub-command specs become reference files, because Codex silently truncates
175
- its skills block (see `cross-cli-contract.md` 2.6 for the measurement)
176
- - every `$HOME/.claude/...` reference to a CLI-owned tree is retargeted, with
177
- `agents/<persona>.md` becoming `.toml` and the dispatcher becoming the router skill
178
- - the personas under `agents/` are regenerated as TOML with a model + reasoning-effort mapping
179
- - shared state (`logs/`, prefs, `knowledge/`) is deliberately NOT retargeted
180
-
181
- That logic lives in `install/codex.mjs` and is gate-locked by
182
- `smoke-codex-install.sh`. Re-describing it here in prose would give the pipeline two
183
- definitions of the same transform, and the prose copy would be the one that rots. So
184
- the step runs the installer's Codex target:
185
-
186
- ```bash
187
- cd "$HOME/multi-agent-pipeline"
188
- node install.js --codex
189
- ```
190
-
191
- **Verify** (the installer is quiet about correctness, only about counts):
192
-
193
- ```bash
194
- # exactly one pipeline skill: more than one means the skills block will truncate
195
- ls -1 "$HOME/.codex/skills" | grep -c '^multi-agent$' # want 1
196
- # every sub-command reachable as a ref
197
- find "$HOME/.codex/multi-agent-refs/commands" -name SKILL.md | wc -l # want the command count
198
- # no reference left pointing at a tree a Codex-only install does not have
199
- grep -rhoE '(\$HOME|~)/\.claude/(agents|scripts|lib|schemas|commands|multi-agent-refs|rules)' \
200
- "$HOME/.codex/skills" "$HOME/.codex/multi-agent-refs" | sort -u # want empty
201
- ```
202
-
203
- **MCP**: the installer runs `codex mcp add multi-agent-toolkit` itself. It is idempotent, and
204
- it is skipped with a warning when `codex` is not on `PATH` - never hand-edit
205
- `~/.codex/config.toml`, which Codex owns (marketplace and plugin state live there
206
- too).
207
-
208
- **Order matters**: run this AFTER Step 3 (REPO), because the installer reads the repo
209
- tree. Running it before means Codex gets the previous revision.
210
-
211
- ---
177
+ Full procedure: `$HOME/.claude/multi-agent-refs/sync/codex.md`. Read it before Step 2b; it runs after Step 3.
212
178
 
213
179
  ## Stack-Plugin Sync (Step 3c)
214
180
 
215
- Stack skills are distributed as versioned plugins in the `mmerterden/multi-agent-plugins` marketplace. The pipeline's `pipeline/skills/shared/external/` is the **single authoring source**; the marketplace is a derived, versioned publish artifact. This step rebuilds it and publishes only when something changed.
216
-
217
- **Source of truth:** author/vendor knowledge skills in `pipeline/skills/shared/external/` (the pipeline's own phases also consume them). The plugins' authored lifecycle skills (`index` / `reference` / `workflow` / `tools`) live in the plugins repo and are never touched by sync.
218
-
219
- **Flow:**
220
-
221
- ```bash
222
- PLUGINS_REPO="$HOME/multi-agent-plugins"
223
- [ ! -d "$PLUGINS_REPO/.git" ] && gh repo clone mmerterden/multi-agent-plugins "$PLUGINS_REPO"
224
- cd "$PLUGINS_REPO" && git pull origin main
225
-
226
- # 1. Preview what would change (routing + version bumps), no writes:
227
- node "$HOME/multi-agent-pipeline/pipeline/scripts/build-stack-plugins.mjs" --dry-run
228
-
229
- # 2. Apply: rebuild each stack plugin's knowledge/ from shared/external,
230
- # regenerate plugin.json skills[], bump the patch version of any plugin
231
- # whose skill set changed. Cross-stack skills -> ai-common-toolkit;
232
- # Apple/Xcode-only skills -> iOS plugin only.
233
- node "$HOME/multi-agent-pipeline/pipeline/scripts/build-stack-plugins.mjs"
234
- ```
235
-
236
- **Version-based management:** the generator bumps a plugin's `version` (patch) only when its skill set actually changed. Idempotent - a no-op run bumps nothing. Consumers pick up new versions via `/multi-agent:update` (which refreshes the catalog with `claude plugin marketplace update multi-agent-plugins`, then runs `claude plugin update` for each installed plugin).
237
-
238
- **Help + README freshness (mandatory when the generator reported any change):**
239
-
240
- 1. Every plugin ships a `tools/help` skill that renders its catalog LIVE from `plugin.json`, so it needs no per-skill edits - but verify each changed plugin still registers it (`grep -c "./skills/tools/help" plugins/<name>/.claude-plugin/plugin.json` = 1) and that a new plugin gets one before publish.
241
- 2. Plugin README tables sync through `python3 tools/bump.py <plugin> --set <version>`; run `python3 tools/bump.py --check` and treat DRIFT as a blocker.
242
- 3. `python3 tools/validate.py` must be clean (it also enforces the CHANGELOG heading for every bumped version - write the entry, do not backdate).
243
- 4. When the pipeline's command surface changed in the same sync (new/renamed `/multi-agent:*` commands), confirm `commands/multi-agent/help/SKILL.md` and both pipeline READMEs (`README.md`, `README.tr.md`) were updated in Step 3 before pushing here.
244
-
245
- **Publish (only if the generator reported bumps):**
246
-
247
- ```bash
248
- cd "$PLUGINS_REPO"
249
- if ! git diff --quiet; then
250
- # Identity: routed for {owner} (platformIdentityRouting). Never a literal: this file
251
- # installs everywhere and would misattribute a downstream user's commits.
252
- git config user.name "{identity.name}"
253
- git config user.email "{identity.email}"
254
- git add -A
255
- git commit -m "chore: rebuild stack plugins from pipeline shared/external"
256
- gh auth switch --user {owner} 2>/dev/null || true
257
- git push origin main
258
- fi
259
- ```
260
-
261
- Never author skills directly in the plugins repo's `knowledge/` - they will be overwritten on the next rebuild. Author in `shared/external`, then run this step.
262
-
263
- ---
181
+ Full procedure: `$HOME/.claude/multi-agent-refs/sync/stack-plugins.md`. Read it before Step 3c.
264
182
 
265
183
  ## Dev-Toolkit Sync (Step 3d)
266
184
 
267
- The companion MCP server (`multi-agent-toolkit-mcp`) is its own repo with its own registry. Pipeline skills call its tools and several declare a minimum version, so when it moves it has to ship - otherwise the pipeline documents a tool no consumer has.
268
-
269
- **Resolution**: identical to `/multi-agent:refactor` Step 0c - `prefs.global.devToolkit` first, then auto-detect from the `mcpServers` registration (`~/.claude.json`, `~/.claude/settings.json`), then skip. `enabled: false` skips.
270
-
271
- **Detect movement**:
272
-
273
- ```bash
274
- DT="<resolved localPath>"; cd "$DT"
275
- git fetch origin --quiet 2>/dev/null || true
276
- DIRTY=$(git status --porcelain)
277
- AHEAD=$(git log --oneline @{u}..HEAD 2>/dev/null | wc -l | tr -d ' ')
278
- VER=$(node -p "require('./package.json').version")
279
- TAGGED=$(git tag --list "v$VER")
280
- ```
281
-
282
- Moved = `DIRTY` non-empty, or `AHEAD` > 0, or no tag for `VER`. Nothing moved -> report `multi-agent-toolkit: up to date (v$VER)` and continue with the sync.
283
-
284
- **Ship gates** - all must pass before commit or publish. A gate failure aborts THIS step only, reported with file + line; the rest of the sync continues.
285
-
286
- **Prefer the repo's own gate script.** When the toolkit ships one (`npm run gates`, or `scripts/gates.sh`), run THAT and skip the inline list below - the repo owns the definition, this skill only owns the requirement. The inline gates are the fallback for a repo that has none, and the checklist the gate script itself must cover.
287
-
288
- ```bash
289
- cd "$DT"
290
- if node -e "process.exit(require('./package.json').scripts?.gates ? 0 : 1)" 2>/dev/null; then
291
- npm run gates || echo "ABORT: multi-agent-toolkit gates failed"
292
- elif [ -f scripts/gates.sh ]; then
293
- bash scripts/gates.sh || echo "ABORT: multi-agent-toolkit gates failed"
294
- else
295
- : # run the inline gates below
296
- fi
297
- ```
298
-
299
- 1. **Syntax**: `node --check index.js` plus every `tools/**/*.js`.
300
- 2. **Boot + inventory**: handshake the server over stdio and count the registered tools.
301
-
302
- ```bash
303
- TOOLS=$(printf '%s\n' \
304
- '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"sync","version":"1"}}}' \
305
- '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
306
- '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
307
- | node index.js 2>/dev/null \
308
- | node -e 'let b="";process.stdin.on("data",d=>b+=d).on("end",()=>{const m=b.split("\n").filter(Boolean).map(l=>{try{return JSON.parse(l)}catch{return null}}).find(x=>x&&x.id===2&&x.result&&x.result.tools);console.log(m?m.result.tools.length:0)})')
309
- [ "${TOOLS:-0}" -gt 0 ] || echo "ABORT: the toolkit served 0 tools"
310
- ```
311
-
312
- 3. **Advertised-count match**: `$TOOLS` must equal every advertised count (`package.json` `description`, the `README.md` header and its per-family rows). Fix the docs, never the gate - a stale count has shipped before.
313
- 4. **Packaging**: every directory the server loads at runtime must be inside `files[]`. A missing entry publishes a broken package (this has already caused one patch release).
314
-
315
- ```bash
316
- PACK=$(npm pack --dry-run 2>&1)
317
- for d in tools/*/; do printf '%s' "$PACK" | grep -q "$d" || echo "ABORT: $d missing from files[]"; done
318
- ```
319
-
320
- 5. **stdout hygiene**: `grep -rn "console\.log(" index.js tools/` must be empty - stdout carries the JSON-RPC frames, diagnostics belong on `console.error`.
321
- 6. **Personal-data scan**: no absolute `/Users/<name>` paths, no tokens, no corporate hostnames in the shipped files.
322
- 7. **Version contract**: every pipeline-side minimum (the `cross-cli-contract.md` tool table, `design-check`'s MCP requirement, `apple-archive-compliance`) must be satisfied by the version about to ship. A newly added tool that a pipeline skill now needs -> bump that declared minimum in the pipeline during this same sync.
323
-
324
- **Version bump**: patch for fixes and docs, minor for a new tool, major for a removed or renamed tool (pipeline minimums depend on the surface).
325
-
326
- **Ship**:
327
-
328
- ```bash
329
- gh auth switch --user {owner}
330
- git add -A
331
- git commit -F "/tmp/release-msg-$NEW.txt" # "{type}(v$NEW): {what changed}", written with the file tool
332
- git tag "v$NEW" && git push origin main --tags
333
- ```
334
-
335
- Publish to the registry declared in `publishConfig` through a throwaway userconfig. Never edit `~/.npmrc`, and never a bare `npm publish` - it lands on whichever registry the ambient config happens to name.
336
-
337
- **The token depends on the registry AND on the package scope.** The registry picks
338
- the credential *type*; the scope picks the *account*. Resolving on host alone
339
- misroutes on any machine with more than one GitHub identity, which is the common
340
- case for anyone with a work and a personal account.
341
-
342
- | Registry | Credential type | Account chosen by |
343
- |---|---|---|
344
- | `npm.pkg.github.com` | GitHub PAT with `write:packages` (Classic; fine-grained PATs are not fully supported for Packages) | the package scope, e.g. `@{owner}` → the `{owner}` account's PAT |
345
- | `registry.npmjs.org` | npm token (logical key `npm`) | the npm account that owns the scope |
346
-
347
- Resolve the scope first, then the key:
348
-
349
- ```bash
350
- SCOPE=$(node -p "(require('./package.json').name.match(/^@([^/]+)/)||[])[1] || ''")
351
- # Prefer a scope-specific mapping; fall back to the generic key only when the
352
- # machine has exactly one GitHub identity.
353
- KEY=$(node -e '
354
- const fs=require("fs"),os=require("os"),p=os.homedir()+"/.claude/multi-agent-preferences.json";
355
- const km=(JSON.parse(fs.readFileSync(p,"utf8")).global||{}).keychainMapping||{};
356
- const scope=process.argv[1];
357
- process.stdout.write(km[`github_${scope}`] ? `github_${scope}` : "github");
358
- ' "$SCOPE")
359
- ```
360
-
361
- **Pre-flight the scope, do not learn it from a 403.** GitHub tells you a token's
362
- scopes on any authenticated request, so check before uploading rather than after:
363
-
364
- ```bash
365
- scope_ok() { # $1 = token; prints the login, non-zero when write:packages is absent
366
- local hdrs; hdrs=$(curl -sI -H "Authorization: token $1" https://api.github.com/user)
367
- printf '%s' "$hdrs" | grep -i '^x-oauth-scopes:' | grep -q 'write:packages'
368
- }
369
- ```
370
-
371
- **Candidate order for a `npm.pkg.github.com` publish.** The scope matters more than
372
- where the token is stored, and the two are not correlated: on a machine with a work
373
- and a personal identity, the hand-made PAT in the credential store may be the wrong
374
- account or the right account without `write:packages`, while the `gh` CLI's own
375
- OAuth token for that account often has it.
376
-
377
- 1. `github_<scope>` from `keychainMapping` (a PAT deliberately onboarded for this scope)
378
- 2. `gh auth token -u <scope>` - gh's stored OAuth token for that account
379
- 3. the generic `github` key - only when the machine has one GitHub identity
380
-
381
- Take the first candidate that passes `scope_ok` AND whose `login` matches the
382
- package scope. If none qualifies, stop before `npm publish` and report which
383
- candidates were tried, what login each resolved to, and which scope was missing.
384
- That report is the actionable output; a 403 body is not.
385
-
386
- Measured on this machine, which is why the order is what it is:
387
-
388
- | Candidate | login | scopes |
389
- |---|---|---|
390
- | `keychainMapping.github` | corporate EMU account | cannot publish to a personal scope under any grant |
391
- | the personal PAT in the store | personal | `admin:public_key, gist, read:org, repo` - no `write:packages` |
392
- | `gh auth token -u {owner}` | personal | `gist, read:org, repo, workflow, write:packages` ✓ |
393
-
394
- **Two 403s mean two different things, and neither says "wrong token" plainly:**
395
-
396
- - `Unauthorized: As an Enterprise Managed User, you cannot access this content` -
397
- the resolved token belongs to a corporate EMU account, which cannot publish to a
398
- personal scope at all. The mapping points at the wrong identity. Map the personal
399
- account's PAT under `github_<scope>` and re-run; do not "fix" this by granting
400
- the EMU token more scopes, because no scope makes an EMU account able to write
401
- to a personal namespace.
402
- - `The token provided does not match expected scopes` - right account, missing
403
- permission. The PAT needs **Classic** with `write:packages` (plus `repo` for a
404
- private package). Regenerate it at
405
- `https://github.com/settings/tokens/new?scopes=write:packages,read:packages,repo`
406
- and re-onboard via `/multi-agent:setup`.
407
-
408
- Report which of the two it was. "Permission denied" alone sends the user to
409
- regenerate a token that was never the problem.
410
-
411
- ```bash
412
- NPMRC=$(mktemp); trap 'rm -f "$NPMRC"' EXIT
413
- REG=$(node -p "require('./package.json').publishConfig?.registry || 'https://registry.npmjs.org'")
414
- HOST=${REG#https://}; HOST=${HOST%/}
415
- case "$HOST" in npm.pkg.github.com*) KEY=github ;; *) KEY=npm ;; esac
416
- TOKEN=$(bash "$HOME/.claude/lib/credential-store.sh" get "$KEY")
417
- [ -n "$TOKEN" ] || echo "ABORT: no '$KEY' token - onboard it via /multi-agent:setup before publishing"
418
- printf '%s\n' "registry=$REG" "//$HOST/:_authToken=$TOKEN" > "$NPMRC"
419
- npm publish --userconfig "$NPMRC"
420
- ```
421
-
422
- Verify the publish landed: on GitHub Packages `npm view <package> version --userconfig "$NPMRC"`; on npmjs read the registry directly (`curl -s https://registry.npmjs.org/<package>/latest`) rather than `npm view`, which can answer from a stale cache.
423
-
424
- **Required release** (optional; ask first even in `release` mode, it halts every older install): `npm dist-tag add "$(node -p "require('./package.json').name")@$VER" required --userconfig "$NPMRC"`. Out of band, so promote or demote any time. Contract: `multi-agent-refs/rules.md` "Supported Version Gate".
425
-
426
- **Approval**: outside autopilot and outside `release`, ask before shipping.
427
-
428
- > "multi-agent-toolkit moved (N changed files, M unpushed commits, v$VER). What should I do?"
429
-
430
- - Commit + push (no publish)
431
- - Commit + push + publish v$NEW
432
- - Skip this step
433
-
434
- With `release`, or in autopilot, run the full ship path without asking. If the working copy holds band-E work from `/multi-agent:refactor` that was never approved, do not ship it silently - report it and ask.
435
-
436
- **Consumer note**: a path-based stdio registration (`node <localPath>/index.js`) picks the change up on the next MCP restart with no reinstall; a packaged registration (`npx <package>`) needs the published version. State which one the resolved config uses in the Step 6 report.
437
-
438
- ---
185
+ Full procedure: `$HOME/.claude/multi-agent-refs/sync/dev-toolkit.md`. Read it before Step 3d, and for `/multi-agent:sync multi-agent-toolkit`.
439
186
 
440
187
  ## Website Sync (Step 4)
441
188
 
@@ -493,15 +240,15 @@ same specs as reference files rather than as peer skills, via Step 2b - see
493
240
  |-------------|-------------|
494
241
  | `~/.claude/commands/multi-agent/{cmd}/SKILL.md` | `~/.copilot/skills/multi-agent-{cmd}/SKILL.md` |
495
242
 
496
- **61 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
243
+ **63 commands are synced** (canonical inventory - must match `cross-cli-contract.md` section 1; drift = contract violation):
497
244
 
498
245
  ```
499
246
  analysis, analysis-jira, analysis-resolve, autopilot, autopilot-off, autopilot-on,
500
247
  autopilot-status, build-optimize, channels, complaint-analysis, create-jira,
501
- design-check, diff-explain, doctor, feedback, forget, garbage-collect, graph, help,
248
+ design-check, diff-explain, doctor, estimate, feedback, forget, garbage-collect, graph, help,
502
249
  ios-coding-standard, issue, jira, kill, language, log,
503
250
  manual-test, model, prune-logs, prune-prompts, purge, refactor, research, resume, review, review-analysis, review-issue, review-jira, route-off, route-on, route-status,
504
- routines, save, scaffold, scan, search, security-review, serve, setup, stack, status, steer, store-ready, sync, test,
251
+ routines, save, scaffold, scan, scenario-audit, search, security-review, serve, setup, stack, status, steer, store-ready, sync, test,
505
252
  test-accessibility, test-dark-mode, test-dynamic-type, test-screenshots,
506
253
  testflight-validation, uninstall, update
507
254
  ```