@mmerterden/multi-agent-pipeline 18.0.0 → 19.0.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 (209) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +34 -18
  3. package/README.tr.md +14 -16
  4. package/docs/adr/0002-instruction-driven-flag.md +1 -0
  5. package/docs/adr/0005-lazy-phase-docs.md +11 -1
  6. package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +1 -0
  7. package/docs/adr/0010-own-code-graph.md +1 -0
  8. package/docs/adr/0014-six-phase-consolidation.md +134 -0
  9. package/docs/adr/README.md +2 -1
  10. package/docs/architecture.md +37 -38
  11. package/docs/best-practices.md +1 -1
  12. package/docs/ecosystem.md +37 -26
  13. package/docs/engineering.md +1 -1
  14. package/docs/facts.json +45 -0
  15. package/docs/features.md +54 -53
  16. package/docs/performance.md +5 -5
  17. package/docs/recovery-guide.md +9 -9
  18. package/docs/token-budget-history.md +3 -1
  19. package/index.js +2 -2
  20. package/install/_codex-agents.mjs +1 -1
  21. package/install/templates/claude-hooks.json +1 -1
  22. package/install/templates/codex-instructions.md +1 -1
  23. package/install/templates/copilot-instructions.md +28 -28
  24. package/manifest.json +209 -193
  25. package/package.json +2 -2
  26. package/pipeline/agents/dev-critic.md +3 -3
  27. package/pipeline/commands/figma-to-swiftui.md +1 -1
  28. package/pipeline/commands/multi-agent/SKILL.md +8 -8
  29. package/pipeline/commands/multi-agent/analysis/SKILL.md +9 -9
  30. package/pipeline/commands/multi-agent/autopilot/SKILL.md +7 -7
  31. package/pipeline/commands/multi-agent/channels/SKILL.md +15 -15
  32. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +6 -6
  33. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
  34. package/pipeline/commands/multi-agent/graph/SKILL.md +1 -1
  35. package/pipeline/commands/multi-agent/help/SKILL.md +62 -62
  36. package/pipeline/commands/multi-agent/language/SKILL.md +2 -2
  37. package/pipeline/commands/multi-agent/local/SKILL.md +11 -11
  38. package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +13 -13
  39. package/pipeline/commands/multi-agent/log/SKILL.md +2 -2
  40. package/pipeline/commands/multi-agent/manual-test/SKILL.md +9 -9
  41. package/pipeline/commands/multi-agent/model/SKILL.md +69 -0
  42. package/pipeline/commands/multi-agent/refactor/SKILL.md +3 -3
  43. package/pipeline/commands/multi-agent/resume/SKILL.md +4 -4
  44. package/pipeline/commands/multi-agent/resume-local/SKILL.md +19 -17
  45. package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
  46. package/pipeline/commands/multi-agent/route-off/SKILL.md +36 -0
  47. package/pipeline/commands/multi-agent/route-on/SKILL.md +74 -0
  48. package/pipeline/commands/multi-agent/route-status/SKILL.md +56 -0
  49. package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
  50. package/pipeline/commands/multi-agent/status/SKILL.md +5 -5
  51. package/pipeline/commands/multi-agent/steer/SKILL.md +2 -2
  52. package/pipeline/commands/multi-agent/sync/SKILL.md +12 -13
  53. package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
  54. package/pipeline/lib/credential-inventory.sh +1 -1
  55. package/pipeline/lib/fetch-fortify.sh +1 -1
  56. package/pipeline/lib/model-rung.sh +142 -0
  57. package/pipeline/lib/phase-schema.mjs +88 -0
  58. package/pipeline/lib/plan-todos.sh +5 -5
  59. package/pipeline/lib/route-state.sh +161 -0
  60. package/pipeline/lib/run-paths.sh +2 -2
  61. package/pipeline/multi-agent-refs/_account-picker.md +1 -1
  62. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  63. package/pipeline/multi-agent-refs/_input-parser.md +1 -1
  64. package/pipeline/multi-agent-refs/analysis/evidence.md +0 -9
  65. package/pipeline/multi-agent-refs/analysis/intake.md +1 -1
  66. package/pipeline/multi-agent-refs/analysis/locked.md +21 -22
  67. package/pipeline/multi-agent-refs/analysis/render.md +1 -1
  68. package/pipeline/multi-agent-refs/analysis/synthesis.md +12 -6
  69. package/pipeline/multi-agent-refs/android-guide.md +1 -1
  70. package/pipeline/multi-agent-refs/audit-guide.md +13 -13
  71. package/pipeline/multi-agent-refs/channels/issue-comment.md +2 -2
  72. package/pipeline/multi-agent-refs/channels/jira.md +3 -3
  73. package/pipeline/multi-agent-refs/channels/pr.md +4 -4
  74. package/pipeline/multi-agent-refs/channels/wiki.md +1 -1
  75. package/pipeline/multi-agent-refs/component-dispatch.md +3 -3
  76. package/pipeline/multi-agent-refs/cross-cli-contract.md +31 -6
  77. package/pipeline/multi-agent-refs/features/autopilot-circuit-breaker.md +4 -4
  78. package/pipeline/multi-agent-refs/features/code-graph.md +5 -5
  79. package/pipeline/multi-agent-refs/features/design-conformance.md +1 -1
  80. package/pipeline/multi-agent-refs/features/dev-critic.md +3 -3
  81. package/pipeline/multi-agent-refs/features/doctor.md +2 -2
  82. package/pipeline/multi-agent-refs/features/external-context-injection.md +3 -3
  83. package/pipeline/multi-agent-refs/features/maturity-followup.md +3 -3
  84. package/pipeline/multi-agent-refs/features/model-fallback.md +5 -5
  85. package/pipeline/multi-agent-refs/features/plan-todos.md +1 -1
  86. package/pipeline/multi-agent-refs/features/repo-map.md +1 -1
  87. package/pipeline/multi-agent-refs/features/review-delta.md +3 -3
  88. package/pipeline/multi-agent-refs/features/review-multi-repo.md +1 -1
  89. package/pipeline/multi-agent-refs/features/scope-check.md +4 -4
  90. package/pipeline/multi-agent-refs/features/skill-conformance.md +2 -2
  91. package/pipeline/multi-agent-refs/features/stack-skill-routing.md +1 -1
  92. package/pipeline/multi-agent-refs/features/verify-by-test.md +4 -4
  93. package/pipeline/multi-agent-refs/features/visual-evidence.md +19 -19
  94. package/pipeline/multi-agent-refs/features/worktree-finalize.md +6 -6
  95. package/pipeline/multi-agent-refs/issue-jira-triad.md +10 -10
  96. package/pipeline/multi-agent-refs/knowledge.md +11 -11
  97. package/pipeline/multi-agent-refs/multi-repo-integration-build.md +13 -13
  98. package/pipeline/multi-agent-refs/payload-contracts.md +8 -8
  99. package/pipeline/multi-agent-refs/phases/log-format.md +10 -10
  100. package/pipeline/multi-agent-refs/phases/modes.md +30 -30
  101. package/pipeline/multi-agent-refs/phases/operations.md +8 -8
  102. package/pipeline/multi-agent-refs/phases/phase-0-init.md +24 -24
  103. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +599 -0
  104. package/pipeline/multi-agent-refs/phases/{phase-3-dev.md → phase-2-dev.md} +129 -49
  105. package/pipeline/multi-agent-refs/phases/{phase-4-review.md → phase-3-review.md} +225 -107
  106. package/pipeline/multi-agent-refs/phases/{phase-6-commit.md → phase-4-commit.md} +23 -23
  107. package/pipeline/multi-agent-refs/phases/{phase-7-report.md → phase-5-report.md} +29 -29
  108. package/pipeline/multi-agent-refs/phases.md +44 -48
  109. package/pipeline/multi-agent-refs/picker-contract.md +1 -1
  110. package/pipeline/multi-agent-refs/progress-contract.md +6 -6
  111. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  112. package/pipeline/multi-agent-refs/rules.md +7 -7
  113. package/pipeline/multi-agent-refs/swiftui-guide.md +2 -2
  114. package/pipeline/multi-agent-refs/tracker-contract.md +31 -32
  115. package/pipeline/multi-agent-refs/wiki-capture.md +14 -14
  116. package/pipeline/preferences-template.json +9 -1
  117. package/pipeline/rules/outside-the-pipeline.md +1 -1
  118. package/pipeline/schemas/agent-state.schema.json +50 -50
  119. package/pipeline/schemas/analysis-output.schema.json +2 -2
  120. package/pipeline/schemas/autopilot-config.schema.json +1 -1
  121. package/pipeline/schemas/code-graph.schema.json +1 -1
  122. package/pipeline/schemas/criteria-manifest.schema.json +1 -1
  123. package/pipeline/schemas/dev-critic-output.schema.json +1 -1
  124. package/pipeline/schemas/diff-risk.schema.json +1 -1
  125. package/pipeline/schemas/migrations/prefs-2.4.0-to-2.5.0.mjs +2 -2
  126. package/pipeline/schemas/migrations/prefs-2.6.0-to-2.7.0.mjs +31 -0
  127. package/pipeline/schemas/migrations/state-2.1.0-to-2.2.0.mjs +129 -0
  128. package/pipeline/schemas/phases.json +105 -0
  129. package/pipeline/schemas/plan-todos.schema.json +5 -5
  130. package/pipeline/schemas/planning-output.schema.json +1 -1
  131. package/pipeline/schemas/prefs.schema.json +100 -56
  132. package/pipeline/schemas/reviewer-output.schema.json +3 -3
  133. package/pipeline/schemas/route-config.schema.json +74 -0
  134. package/pipeline/schemas/scope-check.schema.json +1 -1
  135. package/pipeline/schemas/test-gap.schema.json +1 -1
  136. package/pipeline/schemas/token-budget.json +12 -18
  137. package/pipeline/schemas/triage-output.schema.json +6 -6
  138. package/pipeline/scripts/README.md +3 -3
  139. package/pipeline/scripts/_code-graph.mjs +2 -2
  140. package/pipeline/scripts/_run-paths.mjs +2 -2
  141. package/pipeline/scripts/_smoke-root.sh +1 -1
  142. package/pipeline/scripts/aggregate-metrics.mjs +1 -1
  143. package/pipeline/scripts/capture-flush.sh +8 -8
  144. package/pipeline/scripts/capture-resume.sh +3 -3
  145. package/pipeline/scripts/classify-plan-safety.mjs +1 -1
  146. package/pipeline/scripts/diff-explain.mjs +1 -1
  147. package/pipeline/scripts/doctor.mjs +2 -2
  148. package/pipeline/scripts/gc-abandoned.sh +3 -3
  149. package/pipeline/scripts/gc-tmp.sh +1 -1
  150. package/pipeline/scripts/gc-worktrees.sh +1 -1
  151. package/pipeline/scripts/gen-facts.mjs +175 -0
  152. package/pipeline/scripts/gen-mode-dispatch.mjs +32 -37
  153. package/pipeline/scripts/gen-ref-toc.mjs +1 -1
  154. package/pipeline/scripts/graph-report.mjs +1 -1
  155. package/pipeline/scripts/jira-attach.sh +1 -1
  156. package/pipeline/scripts/learn-from-transcripts.mjs +1 -1
  157. package/pipeline/scripts/learning-curve.mjs +2 -2
  158. package/pipeline/scripts/log-metric.sh +17 -4
  159. package/pipeline/scripts/memory-save.sh +1 -1
  160. package/pipeline/scripts/migrate-prefs.mjs +22 -5
  161. package/pipeline/scripts/phase-banner.sh +20 -20
  162. package/pipeline/scripts/phase-tracker.sh +7 -7
  163. package/pipeline/scripts/plan-coverage-gate.mjs +2 -2
  164. package/pipeline/scripts/render-agent-log-cost.sh +1 -1
  165. package/pipeline/scripts/render-work-summary.sh +3 -3
  166. package/pipeline/scripts/review-file-filter.mjs +1 -1
  167. package/pipeline/scripts/run-aggregator.mjs +13 -6
  168. package/pipeline/scripts/run-metrics.mjs +1 -1
  169. package/pipeline/scripts/runs-index.mjs +11 -1
  170. package/pipeline/scripts/smoke-cross-cli-behavior.sh +6 -6
  171. package/pipeline/scripts/smoke-schema-validation.sh +26 -7
  172. package/pipeline/scripts/token-budget-report.mjs +13 -2
  173. package/pipeline/scripts/triage-memory.mjs +2 -2
  174. package/pipeline/scripts/validate-analysis-doc.mjs +73 -17
  175. package/pipeline/scripts/validate-planning.mjs +1 -1
  176. package/pipeline/scripts/validate-reviewer.mjs +1 -1
  177. package/pipeline/scripts/validate-state.mjs +45 -5
  178. package/pipeline/scripts/validate-triage.mjs +3 -3
  179. package/pipeline/scripts/worktree-finalize.sh +5 -5
  180. package/pipeline/skills/.skill-manifest.json +37 -21
  181. package/pipeline/skills/.skills-index.json +49 -5
  182. package/pipeline/skills/shared/README.md +10 -6
  183. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +2 -2
  184. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +2 -2
  185. package/pipeline/skills/shared/core/multi-agent/SKILL.md +69 -71
  186. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +3 -3
  187. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +14 -14
  188. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +5 -5
  189. package/pipeline/skills/shared/core/multi-agent-graph/SKILL.md +1 -1
  190. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +25 -23
  191. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -2
  192. package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +2 -2
  193. package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +8 -8
  194. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +6 -6
  195. package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +71 -0
  196. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +3 -3
  197. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +1 -1
  198. package/pipeline/skills/shared/core/multi-agent-resume-local/SKILL.md +7 -7
  199. package/pipeline/skills/shared/core/multi-agent-route-off/SKILL.md +39 -0
  200. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +76 -0
  201. package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +59 -0
  202. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
  203. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +5 -5
  204. package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +2 -2
  205. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +6 -5
  206. package/pipeline/skills/skills-index.md +8 -4
  207. package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +0 -263
  208. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +0 -344
  209. package/pipeline/multi-agent-refs/phases/phase-5-test.md +0 -182
@@ -11,7 +11,7 @@
11
11
  //
12
12
  // Checks (ERROR = blocking exit 1; WARN = advisory, still exit 0 unless --strict):
13
13
  // - Front-matter block with required keys (feature, platform, language, mode,
14
- // template_version); mode in {full, lite}; platform in the known set.
14
+ // template_version); mode must be full (lite removed in v19.0.0); platform in the known set.
15
15
  // - Never-omitted sections present by title keyword (Locked 2): Summary,
16
16
  // Goals, User Stories, API Contracts, Architecture, Files to Add, Risks,
17
17
  // References.
@@ -245,16 +245,31 @@ function main() {
245
245
  for (const k of REQUIRED_FM) {
246
246
  if (!parsed.fm[k]) errors.push(`front-matter missing required key: ${k}`);
247
247
  }
248
+ // `mode` is accepted only as "full" now. Lite was removed in v19.0.0: it
249
+ // picked sections from a fixed list chosen by a three-signal score, which
250
+ // fought Locked 2 in both directions - a small feature with rich business
251
+ // rules lost Section 15 because it was not on the list, and a feature with
252
+ // no API contract kept Section 9 because it was. An older document carrying
253
+ // `mode: lite` is still readable; it is reported as a legacy value rather
254
+ // than rejected, because the document was valid when it was written.
248
255
  const mode = parsed.fm.mode;
249
- if (mode && mode !== "full" && mode !== "lite") {
250
- errors.push(`front-matter mode must be full|lite, got: ${mode}`);
256
+ if (mode === "lite") {
257
+ warns.push(
258
+ "front-matter says mode: lite - Lite was removed in v19.0.0 and this is a pre-v19 document. Sections are chosen by evidence now (Locked 2).",
259
+ );
260
+ } else if (mode && mode !== "full") {
261
+ errors.push(`front-matter mode must be full, got: ${mode}`);
251
262
  }
252
263
  const plat = parsed.fm.platform;
253
264
  if (plat && !KNOWN_PLATFORMS.has(plat)) {
254
265
  errors.push(`front-matter platform not in known set: ${plat}`);
255
266
  }
256
267
  }
257
- const mode = parsed?.fm?.mode || "full";
268
+ // A pre-v19 `lite` document is validated as Full: the checks it skipped were
269
+ // skipped because of a mode that no longer exists, and re-skipping them here
270
+ // would carry that exemption forward forever.
271
+ const mode = "full";
272
+ void parsed?.fm?.mode;
258
273
  const profile = (parsed?.fm?.profile || "global").toLowerCase();
259
274
  if (profile !== "global" && profile !== "corporate") {
260
275
  errors.push(`front-matter profile must be global|corporate, got: ${profile}`);
@@ -385,7 +400,7 @@ function main() {
385
400
  } else if (rows.some((l) => /\bAS-\d{2,3}\b/.test(l))) {
386
401
  // Only when there is something to own. A Section 20 with no stamped row
387
402
  // has no owner to check, and warning there would fire on every document
388
- // that never needed the column - noise that Phase 4 runs under --strict.
403
+ // that never needed the column - noise that Phase 3 runs under --strict.
389
404
  warns.push(
390
405
  "Risks and Open Questions carries AS-NN rows but no owner column; ownership cannot be checked",
391
406
  );
@@ -505,7 +520,7 @@ function main() {
505
520
  }
506
521
  mark("traceability-matrix");
507
522
  } else {
508
- mark("traceability-matrix", "lite mode");
523
+ mark("traceability-matrix");
509
524
  }
510
525
  } else {
511
526
  mark("payload-in-table-cell", "global profile");
@@ -580,7 +595,7 @@ function main() {
580
595
 
581
596
  mark("optin-coverage-sections");
582
597
 
583
- // 2c. The Test Plan is Phase 3's RED input (phase-3-dev.md step 5b): the tests
598
+ // 2c. The Test Plan is Phase 3's RED input (phase-2-dev.md step 5b): the tests
584
599
  // written first come from it. Full mode without it hands dev an empty matrix.
585
600
  // It is Section 15 in the global profile and Section 19 in the corporate one;
586
601
  // the check matches on the title, so only the stack-optional case needs an
@@ -594,7 +609,7 @@ function main() {
594
609
  // The omission table allows exactly one case: a backend-only run with no
595
610
  // contract testing planned. The validator knows the platform, so that case
596
611
  // warns instead of blocking; every other platform hands dev an empty matrix.
597
- const msg = "no Section 15 Test Plan; Full mode dev reads it as the RED input (Locked 31)";
612
+ const msg = "no Section 15 Test Plan; dev reads it as the RED input (Locked 30)";
598
613
  if (parsed?.fm?.platform === "backend") {
599
614
  warns.push(`${msg} - allowed for backend only when no contract testing is planned`);
600
615
  } else {
@@ -615,8 +630,7 @@ function main() {
615
630
  }
616
631
  }
617
632
 
618
- if (mode !== "full") mark("test-plan", "lite mode");
619
- else if (noPlatform) mark("test-plan", "no target platform");
633
+ if (noPlatform) mark("test-plan", "no target platform");
620
634
  else mark("test-plan");
621
635
 
622
636
  // 2d. Section 3 carries the diagrams. Omission is legitimate under the
@@ -726,7 +740,7 @@ function main() {
726
740
 
727
741
  mark("concept-table-evidence", conceptBody ? undefined : "no concept table");
728
742
 
729
- // 2g. Locked 31 main clause: a rule with no test scenario fails the gate.
743
+ // 2g. Locked 30 main clause: a rule with no test scenario fails the gate.
730
744
  // The pre-existing occurrence-count heuristic below stays as the looser net.
731
745
  if (mode === "full") {
732
746
  const idRx = /BR-[a-z0-9]+(?:-[a-z0-9]+)*-\d+/gi;
@@ -747,7 +761,7 @@ function main() {
747
761
  }
748
762
  }
749
763
 
750
- mark("rule-to-test", mode === "full" ? undefined : "lite mode");
764
+ mark("rule-to-test");
751
765
 
752
766
  // 2h. Redesign mode (Locked 37). Eight checks, live only when the front-matter
753
767
  // opts in. The contract they enforce is analysis/redesign.md, which loads only
@@ -794,7 +808,7 @@ function main() {
794
808
  );
795
809
  }
796
810
  // 3. A rule that lives only in a shared module legitimately reads this way,
797
- // so it warns rather than blocks - and Phase 4 runs --strict, so it blocks
811
+ // so it warns rather than blocks - and Phase 3 runs --strict, so it blocks
798
812
  // there, which is where a human is already looking.
799
813
  if (/cross-cutting/i.test(evidence) && certainty.includes("confirmed")) {
800
814
  warns.push(
@@ -871,7 +885,7 @@ function main() {
871
885
  // keyword as a raw substring of the heading line - deliberately, since Locked
872
886
  // 2 re-flows section numbers and the corporate profile numbers them
873
887
  // differently - so an unrelated `### 4.9 Notes on the old Current Behaviour
874
- // audit process` matched, and Phase 4 runs --strict, which turns this warning
888
+ // audit process` matched, and Phase 3 runs --strict, which turns this warning
875
889
  // into a blocked document. The artefact itself is the honest signal: a
876
890
  // rendered current-behaviour table always carries `CB-<slug>-NN` ids, and a
877
891
  // paragraph that merely uses the words never does.
@@ -921,7 +935,49 @@ function main() {
921
935
 
922
936
  mark("placeholder-bodies", profile === "global" ? undefined : "corporate profile");
923
937
 
924
- // 5. Traceability (Full mode only, Locked 31)
938
+ // 4b. Locked 2's numbering half, which was ungated until v19.0.0.
939
+ //
940
+ // It is NOT "numbering re-flows 1..N". That is what the rule used to say and
941
+ // it could not hold: Locked 30 threads ids across the document by section
942
+ // NUMBER ("Section 15.1 scenario", "Section 4.4", "Section 3/5 layout cells"),
943
+ // so a re-flowed document sends every one of those references to the wrong
944
+ // section. No emitted document ever re-flowed. The rule was the wrong half.
945
+ //
946
+ // What holds instead: a rendered section keeps its canonical template number,
947
+ // so gaps are correct and `1, 2, 4, 9, 13, 14, 21` is a valid document. Two
948
+ // things are still defects and both are checked here - a number outside the
949
+ // template's range, and numbers that repeat or go backwards. Either one means
950
+ // a cross-reference lands somewhere its author did not intend.
951
+ {
952
+ const MAX_SECTION = 23;
953
+ const nums = [];
954
+ for (const l of text.split("\n")) {
955
+ const m = /^##\s+(\d+)\.\s/.exec(l);
956
+ if (m) nums.push(Number(m[1]));
957
+ }
958
+ if (nums.length === 0) {
959
+ mark("section-numbering", "no numbered top-level sections");
960
+ } else {
961
+ const outOfRange = nums.filter((n) => n < 1 || n > MAX_SECTION);
962
+ const notAscending = [];
963
+ for (let i = 1; i < nums.length; i++) {
964
+ if (nums[i] <= nums[i - 1]) notAscending.push(`${nums[i - 1]} then ${nums[i]}`);
965
+ }
966
+ if (outOfRange.length > 0) {
967
+ errors.push(
968
+ `section number outside the 1..${MAX_SECTION} template range (Locked 2): ${outOfRange.join(", ")}`,
969
+ );
970
+ }
971
+ if (notAscending.length > 0) {
972
+ errors.push(
973
+ `section numbers repeat or go backwards (Locked 2): ${notAscending.slice(0, 4).join("; ")}`,
974
+ );
975
+ }
976
+ mark("section-numbering");
977
+ }
978
+ }
979
+
980
+ // 5. Traceability (Locked 30)
925
981
  if (mode === "full") {
926
982
  const idRe = /BR-[a-z0-9]+(?:-[a-z0-9]+)*-\d+/gi;
927
983
  const all = text.match(idRe) || [];
@@ -931,7 +987,7 @@ function main() {
931
987
  counts.set(key, (counts.get(key) || 0) + 1);
932
988
  }
933
989
  if (counts.size === 0 && profile === "global") {
934
- warns.push("Full mode but no BR-<slug>-NN business-rule ids found (Section 4.4 / Locked 31)");
990
+ warns.push("no BR-<slug>-NN business-rule ids found (Section 4.4 / Locked 30)");
935
991
  }
936
992
  for (const [id, n] of counts) {
937
993
  if (n < 2) {
@@ -942,7 +998,7 @@ function main() {
942
998
  }
943
999
  }
944
1000
 
945
- mark("br-reference-count", mode === "full" ? undefined : "lite mode");
1001
+ mark("br-reference-count");
946
1002
 
947
1003
  // 6. Manual test scenarios (Section 15.7): every MT row carries a BR id.
948
1004
  // A manual scenario nobody can trace back to a rule is a scenario nobody can
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // validate-planning.mjs - runtime validator for Phase 2 planning output.
2
+ // validate-planning.mjs - runtime validator for Phase 1 planning output.
3
3
  //
4
4
  // Phase 2 returns a task decomposition conforming to
5
5
  // pipeline/schemas/planning-output.schema.json. Phase 3 iterates over `tasks`
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // validate-reviewer.mjs - runtime validator for Phase 4 reviewer subagent output.
2
+ // validate-reviewer.mjs - runtime validator for Phase 3 reviewer subagent output.
3
3
  //
4
4
  // Each of the 3 parallel reviewers (Opus, GPT-5.4, Sonnet) must return an
5
5
  // object matching pipeline/schemas/reviewer-output.schema.json. This validator
@@ -14,7 +14,7 @@
14
14
  // actually make a resume unsafe:
15
15
  // - the file does not parse (truncated / corrupt)
16
16
  // - root is not an object
17
- // - currentPhase is missing or out of the 0..7 range (resume keys on it)
17
+ // - currentPhase is missing or out of the 0..5 range (resume keys on it)
18
18
  // - phases is present but not an object, or an entry is not an object
19
19
  // Phase status strings are NOT enum-checked: real writers use "completed"
20
20
  // alongside the schema's "done", and an odd status does not make a resume
@@ -66,9 +66,33 @@ async function main() {
66
66
  process.exit(1);
67
67
  }
68
68
 
69
+ // Which numbering this file was written under. v19.0.0 renumbered eight
70
+ // phases into six, and a run that finished at `currentPhase: 7` in October
71
+ // was correct when it was written - calling it invalid now would mark most
72
+ // of the log directory broken and teach the reader to ignore this validator.
73
+ // Same decision the metrics file got: label the generation, do not rewrite
74
+ // history. A file stamped 2.2.0 or later is generation 2 and bounded 0..5;
75
+ // anything older, including the unstamped files that predate stamping
76
+ // entirely, is generation 1 and bounded 0..7.
77
+ const GEN2_FROM = "2.2.0";
78
+ const cmpVersion = (a, b) => {
79
+ const pa = String(a).split(".").map(Number);
80
+ const pb = String(b).split(".").map(Number);
81
+ for (let i = 0; i < 3; i++) {
82
+ if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) - (pb[i] || 0);
83
+ }
84
+ return 0;
85
+ };
86
+ const gen1 = !s.schemaVersion || cmpVersion(s.schemaVersion, GEN2_FROM) < 0;
87
+ const maxPhase = gen1 ? 7 : 5;
88
+ const phaseKey = gen1 ? /^[0-7]$/ : /^[0-5]$/;
89
+
69
90
  // currentPhase is the field resume keys on - it must be present and in range.
70
- if (!Number.isInteger(s.currentPhase) || s.currentPhase < 0 || s.currentPhase > 7) {
71
- errors.push(`currentPhase must be integer 0..7, got ${JSON.stringify(s.currentPhase)}`);
91
+ if (!Number.isInteger(s.currentPhase) || s.currentPhase < 0 || s.currentPhase > maxPhase) {
92
+ errors.push(
93
+ `currentPhase must be integer 0..${maxPhase}, got ${JSON.stringify(s.currentPhase)}` +
94
+ (gen1 ? " (generation 1 file: unstamped or schemaVersion < 2.2.0)" : ""),
95
+ );
72
96
  }
73
97
 
74
98
  // phases is optional (some early/aborted states omit it), but if present it
@@ -78,12 +102,28 @@ async function main() {
78
102
  errors.push("phases, when present, must be an object keyed by phase number");
79
103
  } else {
80
104
  for (const [k, v] of Object.entries(s.phases)) {
81
- if (!/^[0-7]$/.test(k)) {
82
- errors.push(`phases key invalid: "${k}" (expected "0".."7")`);
105
+ if (!phaseKey.test(k)) {
106
+ errors.push(`phases key invalid: "${k}" (expected "0".."${maxPhase}")`);
83
107
  continue;
84
108
  }
85
109
  if (typeof v !== "object" || v === null) {
86
110
  errors.push(`phases["${k}"] must be an object`);
111
+ continue;
112
+ }
113
+ // The rework cap. Every phase doc says "hard-kill at retryCount === 3"
114
+ // and the schema writes `maximum: 3`, but nothing read either: a fourth
115
+ // round produced a state that violates the schema and passed this
116
+ // validator, which is the one place that could have said so.
117
+ //
118
+ // What this does NOT do is stop the loop - that is the orchestrator's
119
+ // job and it stays prose. What it does is make an over-cap state fail
120
+ // instead of being carried forward as if it were fine.
121
+ if (v.retryCount !== undefined) {
122
+ if (!Number.isInteger(v.retryCount) || v.retryCount < 0 || v.retryCount > 3) {
123
+ errors.push(
124
+ `phases["${k}"].retryCount must be integer 0..3 (the rework cap), got ${JSON.stringify(v.retryCount)}`,
125
+ );
126
+ }
87
127
  }
88
128
  }
89
129
  }
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- // validate-triage.mjs - behavioral validator for Phase 4 triage output.
2
+ // validate-triage.mjs - behavioral validator for Phase 3 triage output.
3
3
  //
4
4
  // Zero dependencies. Reads a triage JSON from a path arg or STDIN, enforces
5
5
  // the contract documented in pipeline/schemas/triage-output.schema.json AND
6
- // the edge-case rules from phase-4-review.md section3.3.
6
+ // the edge-case rules from phase-3-review.md section3.3.
7
7
  //
8
8
  // Unlike validate-schemas.mjs (which only checks schema files are well-formed),
9
9
  // this validates an ACTUAL triage run's output.
@@ -81,7 +81,7 @@ function validateRawFinding(f, label, errors) {
81
81
  }
82
82
  }
83
83
 
84
- // v3.2.0 verify-by-test outcome (Phase 4 Step 3.7). Optional; when present:
84
+ // v3.2.0 verify-by-test outcome (Phase 3 Step 3.7). Optional; when present:
85
85
  // result is required, and confirmed/not-reproduced additionally require
86
86
  // testRef + evidencePath (the empirical claims must be traceable).
87
87
  function validateVerification(v, label, errors) {
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
3
  # worktree-finalize.sh - salvage a finished task's artefacts, then remove its
4
- # worktree. Called by Phase 6 once the PR is open.
4
+ # worktree. Called by Phase 4 once the PR is open.
5
5
  #
6
6
  # The problem it solves: a task's worktree is dead weight the moment its PR
7
7
  # exists, but people forget to remove it, so `.worktrees/` accumulates full
8
- # checkouts. Removing it at PR-open is safe ONLY if the files Phase 7 and
8
+ # checkouts. Removing it at PR-open is safe ONLY if the files Phase 5 and
9
9
  # `:resume` read are moved somewhere that outlives it - hence salvage first.
10
10
  #
11
11
  # What it deliberately does NOT do:
@@ -125,7 +125,7 @@ rp_pr="$(cd "$PROJECT_ROOT" 2>/dev/null && pwd -P || echo "")"
125
125
  [ "$rp_wt" != "$rp_pr" ] || skip "worktree equals project root (--local mode) - nothing to remove"
126
126
 
127
127
  # Refuse if the caller is standing inside the tree being removed. A shell left on
128
- # a deleted inode is worse than a leftover directory, and Phase 6 legitimately
128
+ # a deleted inode is worse than a leftover directory, and Phase 4 legitimately
129
129
  # cd's into the worktree earlier, so this is a real case rather than a theoretical
130
130
  # one. The caller must cd out first.
131
131
  cwd_rp="$(pwd -P)"
@@ -213,7 +213,7 @@ fi
213
213
  [ "$head_sha" = "$upstream_sha" ] || skip "HEAD ($(echo "$head_sha" | cut -c1-8)) differs from remote ($(echo "$upstream_sha" | cut -c1-8)) - push before finalizing"
214
214
 
215
215
  # --- salvage ---------------------------------------------------------------
216
- # Everything Phase 7, :resume, :status and :log read out of the worktree. Each is
216
+ # Everything Phase 5, :resume, :status and :log read out of the worktree. Each is
217
217
  # copied only if present; a task that never reached Phase 4 has no triage output
218
218
  # and that is not an error.
219
219
  DEST="$LOGS_ROOT/${PROJECT:+$PROJECT/}$TASK_ID/artifacts"
@@ -309,7 +309,7 @@ if git -C "$rp_pr" worktree remove "$rp_wt" 2>/dev/null; then
309
309
  # Stamp the outcome into the SALVAGED agent-state.json here, rather than leaving
310
310
  # the caller to write it. In single-repo worktree mode the caller's $STATE_FILE
311
311
  # is the copy that just went away with the worktree, so a write there fails and
312
- # `worktreeRemovedAt` / `artifactsPath` land nowhere - which then makes Phase 7
312
+ # `worktreeRemovedAt` / `artifactsPath` land nowhere - which then makes Phase 5
313
313
  # read a dead path, fall back to the removed worktree, and silently skip the
314
314
  # triage-memory ingest. Exactly the [ -f ]-guarded degradation this step exists
315
315
  # to prevent.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-09-17T11:16:58Z",
4
- "skillCount": 212,
3
+ "generatedAt": "2026-09-18T07:17:50Z",
4
+ "skillCount": 216,
5
5
  "entries": [
6
6
  {
7
7
  "path": "shared/core/apple-archive-compliance/SKILL.md",
8
- "sha256": "0d2f81825bf1610c765a4a7a223247703812e86a642e78f4f367cfc35cea76af"
8
+ "sha256": "e5c38c240a674903acf3f32e5b492a4a6c5dc438a323bb3ca9adc361b41a6884"
9
9
  },
10
10
  {
11
11
  "path": "shared/core/google-play-compliance/SKILL.md",
12
- "sha256": "356ff2b30f414e582bb215c4728696af8e249dfe924e16a550294e48fd9bdcf9"
12
+ "sha256": "49412b53af57ba31fe7d19983144043a2333249d075ff90a9fde9a9d3482ce83"
13
13
  },
14
14
  {
15
15
  "path": "shared/core/multi-agent-analysis-jira/SKILL.md",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "path": "shared/core/multi-agent-autopilot/SKILL.md",
40
- "sha256": "c02525ad003c34d53834ecd04eb150764b36779f4e08941c9016926418e74333"
40
+ "sha256": "7446424d3dd480751358a0e3de917f3d22bb4f1ce6dec1b99217877c6b217e76"
41
41
  },
42
42
  {
43
43
  "path": "shared/core/multi-agent-build-optimize/SKILL.md",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  {
47
47
  "path": "shared/core/multi-agent-channels/SKILL.md",
48
- "sha256": "fa128726aa0009699e7ac2de566812e7192681db98c90dfc5da501ad50a05583"
48
+ "sha256": "414eead38b461c8aa95f6af3175366be905338233e6872313f5d4f59a02351af"
49
49
  },
50
50
  {
51
51
  "path": "shared/core/multi-agent-complaint-analysis/SKILL.md",
@@ -61,7 +61,7 @@
61
61
  },
62
62
  {
63
63
  "path": "shared/core/multi-agent-diff-explain/SKILL.md",
64
- "sha256": "7cb37a224e61d66e350202ecfc5fbc6c33da3fe0718504a093602f5cde5b648f"
64
+ "sha256": "ec3827e0457c693812d11b3a96f88f0e2d186af369c353e1b5c40795d96933dd"
65
65
  },
66
66
  {
67
67
  "path": "shared/core/multi-agent-doctor/SKILL.md",
@@ -81,11 +81,11 @@
81
81
  },
82
82
  {
83
83
  "path": "shared/core/multi-agent-graph/SKILL.md",
84
- "sha256": "918feff1a0a691535901c20a0625340a0f88cd5294cff1a1da20f799f6746f2a"
84
+ "sha256": "d6781a34d98a542aac3df4ce9c7c52d83902851de2d239bed022ac382716a26e"
85
85
  },
86
86
  {
87
87
  "path": "shared/core/multi-agent-help/SKILL.md",
88
- "sha256": "87d45a04c782b03569b0ab9ee54da8414cbadd5a2a82a7701f38dc8a3ee94627"
88
+ "sha256": "6ebe7d4de1a1ff815f572abb5d5db5d5af9ea507b3047ec60597a54455176da5"
89
89
  },
90
90
  {
91
91
  "path": "shared/core/multi-agent-ios-coding-standard/SKILL.md",
@@ -105,15 +105,15 @@
105
105
  },
106
106
  {
107
107
  "path": "shared/core/multi-agent-language/SKILL.md",
108
- "sha256": "c44d951996a208d962d969b0ac309ce88a38c048a2d8b332546c532045c189fc"
108
+ "sha256": "63e746bc63ec9963c54e852e6ca5cdb30afd9309a02ee3fdb35965eb931d0300"
109
109
  },
110
110
  {
111
111
  "path": "shared/core/multi-agent-local-autopilot/SKILL.md",
112
- "sha256": "b0fac3509c2fa513b3fea9bfde4f2554642cb60373a5b570ef29ba8bf760e2a1"
112
+ "sha256": "5e367258e57fa710d16a1ad6363d5974b89aa99fb0ac791d1ce0070c81191f6b"
113
113
  },
114
114
  {
115
115
  "path": "shared/core/multi-agent-local/SKILL.md",
116
- "sha256": "90dd95a0dc569f1451bf095a77cffccae607e4dedd271a3362cce32b53b5d819"
116
+ "sha256": "0a5f20782de81ac3376088579ff6fbc3a6f3781cb285860aae796408aa57e6aa"
117
117
  },
118
118
  {
119
119
  "path": "shared/core/multi-agent-log/SKILL.md",
@@ -121,7 +121,11 @@
121
121
  },
122
122
  {
123
123
  "path": "shared/core/multi-agent-manual-test/SKILL.md",
124
- "sha256": "e7f7f8004d286c5b5b596f8659bcf57b2350eb9c67a55470bb2e9b714513a3a4"
124
+ "sha256": "53e1d58848673690aa0b146908eae98a2de9861dae8b613f63f63672adf6d69b"
125
+ },
126
+ {
127
+ "path": "shared/core/multi-agent-model/SKILL.md",
128
+ "sha256": "eb66f48b4772f41b395b0aff0c3d0303e29da0a470abae8b61a602b93ba7335c"
125
129
  },
126
130
  {
127
131
  "path": "shared/core/multi-agent-prune-logs/SKILL.md",
@@ -137,15 +141,15 @@
137
141
  },
138
142
  {
139
143
  "path": "shared/core/multi-agent-refactor/SKILL.md",
140
- "sha256": "56b49a8216086961bc407a60b559942252a1aae3005b73811b1d40668758cc84"
144
+ "sha256": "56eb2be076a6840ddfbf57b8e82c8b4bcf76209553d41a06cc71e56dc894364e"
141
145
  },
142
146
  {
143
147
  "path": "shared/core/multi-agent-resume-local/SKILL.md",
144
- "sha256": "a4bedf949ab648d977dd1409339d08af204341f555d69f71f58c1a54dffaff6d"
148
+ "sha256": "9f5089c748a8f0ae5983a3f392879a86017a33c883a87607169e32705c68c5e9"
145
149
  },
146
150
  {
147
151
  "path": "shared/core/multi-agent-resume/SKILL.md",
148
- "sha256": "5e80eb098996fdea36f013acc8ddec44d462cace031c78341f11f0b59592a6ba"
152
+ "sha256": "6701424edde0a19b55a7de62bb5ba5f9dbaef7d9fb9ea2bce632374863145774"
149
153
  },
150
154
  {
151
155
  "path": "shared/core/multi-agent-review-analysis/SKILL.md",
@@ -163,6 +167,18 @@
163
167
  "path": "shared/core/multi-agent-review/SKILL.md",
164
168
  "sha256": "f3903b07fa7176ff9430f46cc1e981a0f0d06ab028df5ef1d45ad9271bada1e5"
165
169
  },
170
+ {
171
+ "path": "shared/core/multi-agent-route-off/SKILL.md",
172
+ "sha256": "c569e9ba1fbbebc879b69229cf2154edc89998fcdcfe74fb4220f5af70daafa0"
173
+ },
174
+ {
175
+ "path": "shared/core/multi-agent-route-on/SKILL.md",
176
+ "sha256": "40fab187a6054b90c9b8f1e8ad198a08ab94fdfd9cd89eef9b439e59b570d821"
177
+ },
178
+ {
179
+ "path": "shared/core/multi-agent-route-status/SKILL.md",
180
+ "sha256": "f104d3de6974837b8ebbcc6242269c06ea78a0d97a3e216c1b62cf6d91a72fd8"
181
+ },
166
182
  {
167
183
  "path": "shared/core/multi-agent-routines/SKILL.md",
168
184
  "sha256": "a8cc83140b5d84365348a2b0858f06a9e92808f608544eea61ab5760c82f9f97"
@@ -181,7 +197,7 @@
181
197
  },
182
198
  {
183
199
  "path": "shared/core/multi-agent-setup/SKILL.md",
184
- "sha256": "d475f14de5db9ffe0c8ae5b3b83374d5f82a41c29da5271c7399d151e6bd4c1d"
200
+ "sha256": "d2c167082f40af3c2a7cbb0be55a8cdf8076a4f06a3df54c89b1318759421a29"
185
201
  },
186
202
  {
187
203
  "path": "shared/core/multi-agent-stack/SKILL.md",
@@ -189,11 +205,11 @@
189
205
  },
190
206
  {
191
207
  "path": "shared/core/multi-agent-status/SKILL.md",
192
- "sha256": "3305fcce80bdad9ea0032e382276c5692a197749d9c012910daaea7a332bce0e"
208
+ "sha256": "ae9a7507e0a0291d8e786820b1a0394363f416fd7715f2deb162c9f542ae5351"
193
209
  },
194
210
  {
195
211
  "path": "shared/core/multi-agent-steer/SKILL.md",
196
- "sha256": "a5988d6945dabea45d9827c76e270bb3d12fb2b7689e8893ea09f650ae97baa9"
212
+ "sha256": "d2a3602c1acbd1a01b30fcba65fbbe669ac825ec4ac9b0d6679bba07e0d1207c"
197
213
  },
198
214
  {
199
215
  "path": "shared/core/multi-agent-store-ready/SKILL.md",
@@ -201,7 +217,7 @@
201
217
  },
202
218
  {
203
219
  "path": "shared/core/multi-agent-sync/SKILL.md",
204
- "sha256": "51e9a8a9053ce9d0450bcaf66555075f83c340203bb753946938f4b29cf93b79"
220
+ "sha256": "3d3331d34f9610ea02b96ee27c8029734f3a3447d2857fc0dca92d5b43d0f8e2"
205
221
  },
206
222
  {
207
223
  "path": "shared/core/multi-agent-test-accessibility/SKILL.md",
@@ -237,7 +253,7 @@
237
253
  },
238
254
  {
239
255
  "path": "shared/core/multi-agent/SKILL.md",
240
- "sha256": "faac7ceb535d18778efe0ea91c19534c8e076bc709e7b1dbc567f5e71692bbbd"
256
+ "sha256": "849a2c7db9fb779d9919c7ed6cf3e0c3c6fd105ff961c45af31055ad21fd181c"
241
257
  },
242
258
  {
243
259
  "path": "shared/external/accessibility-compliance-accessibility-audit/SKILL.md",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "skillCount": 212,
3
+ "skillCount": 216,
4
4
  "entries": [
5
5
  {
6
6
  "name": "accessibility-compliance-accessibility-audit",
@@ -1038,7 +1038,7 @@
1038
1038
  },
1039
1039
  {
1040
1040
  "name": "multi-agent-channels",
1041
- "description": "Multi-channel reporter - Jira/Confluence/Wiki/PR description. Multi-select channels + content, humanizer pass, reviewer-preserving Bitbucket PR PUT. Phase 7 delegates to this skill; users can invoke post-hoc by Jira ID / PR URL / branch.",
1041
+ "description": "Multi-channel reporter - Jira/Confluence/Wiki/PR description. Multi-select channels + content, humanizer pass, reviewer-preserving Bitbucket PR PUT. Phase 5 delegates to this skill; users can invoke post-hoc by Jira ID / PR URL / branch.",
1042
1042
  "platform": null,
1043
1043
  "group": "core",
1044
1044
  "plugin": null,
@@ -1082,7 +1082,7 @@
1082
1082
  },
1083
1083
  {
1084
1084
  "name": "multi-agent-diff-explain",
1085
- "description": "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 code change'. Use when a review finding has to be traced to the exact lines that caused it.",
1085
+ "description": "Map Phase 3 triage findings to branch diff lines. Read-only post-hoc command, used after review to answer 'which finding lines up with which code change'. Use when a review finding has to be traced to the exact lines that caused it.",
1086
1086
  "platform": null,
1087
1087
  "group": "core",
1088
1088
  "plugin": null,
@@ -1225,7 +1225,7 @@
1225
1225
  },
1226
1226
  {
1227
1227
  "name": "multi-agent-local-autopilot",
1228
- "description": "Full pipeline + local + autopilot - no worktree, no confirmations, all 8 phases run end-to-end on the current branch. Use when the full pipeline should run on the current branch with no worktree and no prompts.",
1228
+ "description": "Full pipeline + local + autopilot - no worktree, no confirmations, all 6 phases run end-to-end on the current branch. Use when the full pipeline should run on the current branch with no worktree and no prompts.",
1229
1229
  "platform": null,
1230
1230
  "group": "core",
1231
1231
  "plugin": null,
@@ -1256,6 +1256,17 @@
1256
1256
  "triggerPaths": [],
1257
1257
  "relativePath": "shared/core/multi-agent-manual-test/SKILL.md"
1258
1258
  },
1259
+ {
1260
+ "name": "multi-agent-model",
1261
+ "description": "Turn the top model rung on or off and keep the cost ledger's pricing in step with it. Use when asked to enable or disable Fable, or which model the pipeline dispatches.",
1262
+ "platform": null,
1263
+ "group": "core",
1264
+ "plugin": null,
1265
+ "invokeAs": "multi-agent-model",
1266
+ "triggerKeywords": [],
1267
+ "triggerPaths": [],
1268
+ "relativePath": "shared/core/multi-agent-model/SKILL.md"
1269
+ },
1259
1270
  {
1260
1271
  "name": "multi-agent-prune-logs",
1261
1272
  "description": "Delete per-task project logs under ~/.claude/logs/multi-agent (filter by age/project/task). Audit trail + metrics are preserved. Dry-run first; confirms before deleting. Use when task logs have built up and need trimming by age, project or task.",
@@ -1313,7 +1324,7 @@
1313
1324
  },
1314
1325
  {
1315
1326
  "name": "multi-agent-resume-local",
1316
- "description": "Continue already-done LOCAL work through the pipeline tail: Review → Build+Test → Commit/PR → Report (technical analysis + Jira test-scenario comment). No dev phase. Use when local work is already done and only review, build, commit and reporting remain.",
1327
+ "description": "Continue already-done LOCAL work through the pipeline tail: Review (with its build gate) → Commit/PR → Report (technical analysis + Jira test-scenario comment). No dev phase. Use when local work is already done and only review, build, commit and reporting remain.",
1317
1328
  "platform": null,
1318
1329
  "group": "core",
1319
1330
  "plugin": null,
@@ -1366,6 +1377,39 @@
1366
1377
  "triggerPaths": [],
1367
1378
  "relativePath": "shared/core/multi-agent-review-jira/SKILL.md"
1368
1379
  },
1380
+ {
1381
+ "name": "multi-agent-route-off",
1382
+ "description": "Disable model routing and keep its rules, so turning it back on does not re-ask for the same configuration. Use when asked to turn model routing off.",
1383
+ "platform": null,
1384
+ "group": "core",
1385
+ "plugin": null,
1386
+ "invokeAs": "multi-agent-route-off",
1387
+ "triggerKeywords": [],
1388
+ "triggerPaths": [],
1389
+ "relativePath": "shared/core/multi-agent-route-off/SKILL.md"
1390
+ },
1391
+ {
1392
+ "name": "multi-agent-route-on",
1393
+ "description": "Enable policy-driven model routing: pick a strategy, a scope, and the rules that say which rung a call lands on. Use when asked to turn model routing on.",
1394
+ "platform": null,
1395
+ "group": "core",
1396
+ "plugin": null,
1397
+ "invokeAs": "multi-agent-route-on",
1398
+ "triggerKeywords": [],
1399
+ "triggerPaths": [],
1400
+ "relativePath": "shared/core/multi-agent-route-on/SKILL.md"
1401
+ },
1402
+ {
1403
+ "name": "multi-agent-route-status",
1404
+ "description": "Report model routing: whether it is armed, which rule applies where, which rung the last dispatches took, and what this run has cost. Use when asked which model is being used or why.",
1405
+ "platform": null,
1406
+ "group": "core",
1407
+ "plugin": null,
1408
+ "invokeAs": "multi-agent-route-status",
1409
+ "triggerKeywords": [],
1410
+ "triggerPaths": [],
1411
+ "relativePath": "shared/core/multi-agent-route-status/SKILL.md"
1412
+ },
1369
1413
  {
1370
1414
  "name": "multi-agent-routines",
1371
1415
  "description": "List your saved /multi-agent routines (from /multi-agent:save) with what each one does, rendered in outputLanguage. Use when asked which saved routines exist or what one of them does.",