@opengsd/gsd-core 1.8.0 → 1.9.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 (174) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +31 -1
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-codebase-mapper.md +1 -1
  6. package/agents/gsd-debug-session-manager.md +36 -0
  7. package/agents/gsd-executor.md +20 -7
  8. package/agents/gsd-intel-updater.md +3 -3
  9. package/agents/gsd-phase-researcher.md +4 -2
  10. package/agents/gsd-plan-checker.md +20 -0
  11. package/agents/gsd-planner.md +15 -23
  12. package/agents/gsd-project-researcher.md +2 -2
  13. package/agents/gsd-ui-auditor.md +0 -40
  14. package/bin/install.js +186 -55
  15. package/commands/gsd/plan-review-convergence.md +5 -1
  16. package/gsd-core/bin/gsd-tools.cjs +849 -2
  17. package/gsd-core/bin/lib/api-coverage.cjs +22 -8
  18. package/gsd-core/bin/lib/audit.cjs +8 -8
  19. package/gsd-core/bin/lib/capability-consent.cjs +40 -1
  20. package/gsd-core/bin/lib/capability-lifecycle.cjs +58 -0
  21. package/gsd-core/bin/lib/capability-loader.cjs +23 -1
  22. package/gsd-core/bin/lib/capability-registry.cjs +1353 -132
  23. package/gsd-core/bin/lib/capability-trust.cjs +468 -33
  24. package/gsd-core/bin/lib/capability-validator.cjs +882 -6
  25. package/gsd-core/bin/lib/check-command-router.cjs +12 -2
  26. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +15 -0
  27. package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +102 -12
  28. package/gsd-core/bin/lib/claude-orchestration.cjs +125 -22
  29. package/gsd-core/bin/lib/commands.cjs +246 -18
  30. package/gsd-core/bin/lib/config-loader.cjs +200 -28
  31. package/gsd-core/bin/lib/config.cjs +90 -5
  32. package/gsd-core/bin/lib/estimate-cli.cjs +336 -0
  33. package/gsd-core/bin/lib/frontmatter.cjs +125 -15
  34. package/gsd-core/bin/lib/host-integration.cjs +215 -8
  35. package/gsd-core/bin/lib/init.cjs +44 -19
  36. package/gsd-core/bin/lib/install-engine.cjs +1 -0
  37. package/gsd-core/bin/lib/milestone.cjs +5 -5
  38. package/gsd-core/bin/lib/model-catalog.cjs +51 -1
  39. package/gsd-core/bin/lib/observability/logger.cjs +7 -2
  40. package/gsd-core/bin/lib/phase-command-router.cjs +10 -1
  41. package/gsd-core/bin/lib/phase-estimation.cjs +398 -0
  42. package/gsd-core/bin/lib/phase-id.cjs +278 -5
  43. package/gsd-core/bin/lib/phase.cjs +57 -5
  44. package/gsd-core/bin/lib/plan-drift-guard.cjs +1 -1
  45. package/gsd-core/bin/lib/plan-scan.cjs +1 -1
  46. package/gsd-core/bin/lib/planning-workspace.cjs +9 -2
  47. package/gsd-core/bin/lib/profile-output.cjs +34 -8
  48. package/gsd-core/bin/lib/review-lane-descriptor.cjs +927 -0
  49. package/gsd-core/bin/lib/review-lane-invocation.cjs +348 -0
  50. package/gsd-core/bin/lib/review-lane-runner.cjs +594 -0
  51. package/gsd-core/bin/lib/review-reviewer-selection.cjs +114 -32
  52. package/gsd-core/bin/lib/roadmap-parser.cjs +54 -6
  53. package/gsd-core/bin/lib/roadmap.cjs +10 -4
  54. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +31 -4
  55. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +1 -1
  56. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +140 -0
  57. package/gsd-core/bin/lib/runtime-name-policy.cjs +15 -2
  58. package/gsd-core/bin/lib/smart-entry.cjs +1 -1
  59. package/gsd-core/bin/lib/state-document.cjs +164 -20
  60. package/gsd-core/bin/lib/state-transition.cjs +28 -10
  61. package/gsd-core/bin/lib/state.cjs +141 -21
  62. package/gsd-core/bin/lib/uat-predicate.cjs +6 -4
  63. package/gsd-core/bin/lib/uat.cjs +9 -7
  64. package/gsd-core/bin/lib/ui-consideration-probe.cjs +2 -2
  65. package/gsd-core/bin/lib/unusable-input.cjs +216 -0
  66. package/gsd-core/bin/lib/validate.cjs +32 -0
  67. package/gsd-core/bin/lib/verification.cjs +51 -14
  68. package/gsd-core/bin/lib/verify.cjs +128 -20
  69. package/gsd-core/bin/lib/worktree-safety.cjs +360 -15
  70. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  71. package/gsd-core/bin/shared/config-schema.manifest.json +1 -13
  72. package/gsd-core/bin/shared/model-catalog.json +5 -0
  73. package/gsd-core/bin/shared/runtime-aliases.manifest.json +5 -0
  74. package/gsd-core/references/context-budget.md +40 -0
  75. package/gsd-core/references/gate-prompts.md +6 -3
  76. package/gsd-core/references/model-profile-resolution.md +64 -13
  77. package/gsd-core/references/offer-next.md +88 -0
  78. package/gsd-core/references/planning-config.md +2 -1
  79. package/gsd-core/references/reviewer-instances.md +28 -21
  80. package/gsd-core/references/runtime-aware-dispatch.md +42 -0
  81. package/gsd-core/references/ui-consideration-probe.md +2 -2
  82. package/gsd-core/references/worktree-branch-check.md +4 -4
  83. package/gsd-core/templates/summary-minimal.md +4 -0
  84. package/gsd-core/templates/summary-standard.md +4 -0
  85. package/gsd-core/templates/summary.md +7 -0
  86. package/gsd-core/workflows/ai-integration-phase.md +4 -4
  87. package/gsd-core/workflows/audit-fix.md +4 -0
  88. package/gsd-core/workflows/audit-milestone.md +8 -0
  89. package/gsd-core/workflows/autonomous.md +19 -15
  90. package/gsd-core/workflows/check-todos.md +2 -2
  91. package/gsd-core/workflows/code-review-fix.md +14 -6
  92. package/gsd-core/workflows/code-review.md +76 -19
  93. package/gsd-core/workflows/debug.md +10 -2
  94. package/gsd-core/workflows/diagnose-issues.md +4 -0
  95. package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -4
  96. package/gsd-core/workflows/discuss-phase/modes/auto.md +0 -6
  97. package/gsd-core/workflows/discuss-phase-assumptions.md +15 -9
  98. package/gsd-core/workflows/discuss-phase.md +2 -2
  99. package/gsd-core/workflows/docs-update.md +8 -0
  100. package/gsd-core/workflows/eval-review.md +1 -1
  101. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +4 -0
  102. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +160 -0
  103. package/gsd-core/workflows/execute-phase.md +85 -115
  104. package/gsd-core/workflows/execute-plan.md +5 -4
  105. package/gsd-core/workflows/explore.md +4 -0
  106. package/gsd-core/workflows/extract-learnings.md +21 -0
  107. package/gsd-core/workflows/help/modes/full.md +3 -3
  108. package/gsd-core/workflows/import.md +4 -1
  109. package/gsd-core/workflows/ingest-docs.md +4 -0
  110. package/gsd-core/workflows/map-codebase.md +13 -6
  111. package/gsd-core/workflows/new-milestone.md +10 -2
  112. package/gsd-core/workflows/new-project.md +11 -4
  113. package/gsd-core/workflows/next.md +5 -2
  114. package/gsd-core/workflows/plan-phase.md +42 -46
  115. package/gsd-core/workflows/plan-review-convergence.md +18 -14
  116. package/gsd-core/workflows/progress.md +1 -1
  117. package/gsd-core/workflows/quick.md +14 -3
  118. package/gsd-core/workflows/review.md +146 -575
  119. package/gsd-core/workflows/scan.md +9 -1
  120. package/gsd-core/workflows/secure-phase.md +10 -2
  121. package/gsd-core/workflows/ship.md +41 -11
  122. package/gsd-core/workflows/smart-entry.md +1 -1
  123. package/gsd-core/workflows/ui-phase.md +8 -1
  124. package/gsd-core/workflows/ui-review.md +8 -1
  125. package/gsd-core/workflows/update.md +104 -5
  126. package/gsd-core/workflows/validate-phase.md +10 -2
  127. package/gsd-core/workflows/verify-work.md +8 -1
  128. package/hooks/dist/gsd-cursor-session-start.js +6 -2
  129. package/hooks/dist/gsd-cursor-stop.js +6 -2
  130. package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
  131. package/hooks/dist/gsd-graphify-update.sh +9 -0
  132. package/hooks/dist/gsd-phase-boundary.sh +14 -2
  133. package/hooks/dist/gsd-prompt-guard.js +101 -2
  134. package/hooks/dist/gsd-read-guard.js +100 -2
  135. package/hooks/dist/gsd-read-injection-scanner.js +109 -2
  136. package/hooks/dist/gsd-statusline.js +9 -6
  137. package/hooks/dist/gsd-workflow-guard.js +110 -6
  138. package/hooks/dist/gsd-worktree-path-guard.js +132 -8
  139. package/hooks/dist/lib/cursor-workspace.js +74 -0
  140. package/hooks/gsd-cursor-session-start.js +6 -2
  141. package/hooks/gsd-cursor-stop.js +6 -2
  142. package/hooks/gsd-cursor-subagent-start.js +6 -2
  143. package/hooks/gsd-graphify-update.sh +9 -0
  144. package/hooks/gsd-phase-boundary.sh +14 -2
  145. package/hooks/gsd-prompt-guard.js +101 -2
  146. package/hooks/gsd-read-guard.js +100 -2
  147. package/hooks/gsd-read-injection-scanner.js +109 -2
  148. package/hooks/gsd-statusline.js +9 -6
  149. package/hooks/gsd-workflow-guard.js +110 -6
  150. package/hooks/gsd-worktree-path-guard.js +132 -8
  151. package/hooks/lib/cursor-workspace.js +74 -0
  152. package/package.json +7 -7
  153. package/pi/gsd.cjs +26 -1
  154. package/scripts/check-coverage-gate.cjs +51 -0
  155. package/scripts/check-glossary-refs.cjs +24 -0
  156. package/scripts/ci-test-scope.cjs +67 -17
  157. package/scripts/gen-adr-index.cjs +6 -4
  158. package/scripts/gen-capability-matrix.cjs +26 -2
  159. package/scripts/gen-capability-registry.cjs +132 -34
  160. package/scripts/gen-emitted-baseline.cjs +145 -0
  161. package/scripts/lint-compiled-artifact-sync.cjs +146 -0
  162. package/scripts/lint-emitted-drift-ack.cjs +149 -0
  163. package/scripts/lint-fix-has-regression-test.cjs +131 -0
  164. package/scripts/lint-resolution-provenance.cjs +9 -0
  165. package/scripts/mutation-matrix.cjs +4 -0
  166. package/scripts/prompt-injection-scan.sh +6 -0
  167. package/scripts/registry-schema.cjs +57 -8
  168. package/scripts/release-notes/conventional-title.cjs +19 -1
  169. package/scripts/release-notes/format-github-release-notes.cjs +7 -3
  170. package/scripts/workflow-size.cjs +16 -8
  171. package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
  172. package/vscode/package.json +1 -1
  173. package/scripts/gen-golden-install-parity-zcode.cjs +0 -77
  174. package/scripts/update-size-baseline.cjs +0 -68
@@ -10,7 +10,7 @@ const capabilities = {
10
10
  "ai-integration": {
11
11
  "id": "ai-integration",
12
12
  "role": "feature",
13
- "version": "1.8.0",
13
+ "version": "1.9.0",
14
14
  "title": "AI design contract",
15
15
  "description": "AI-SPEC design contract workflow for phases that build AI systems; owns the AI integration command, agents, and workflow.ai_integration_phase activation key.",
16
16
  "tier": "full",
@@ -95,7 +95,7 @@ const capabilities = {
95
95
  "antigravity": {
96
96
  "id": "antigravity",
97
97
  "role": "runtime",
98
- "version": "1.8.0",
98
+ "version": "1.9.0",
99
99
  "title": "Antigravity",
100
100
  "description": "Google Antigravity IDE — nested under ~/.gemini/antigravity; probed across 1.x and 2.x layouts; Gemini hook event dialect; flat skill layout; tier-1 support.",
101
101
  "tier": "core",
@@ -176,13 +176,15 @@ const capabilities = {
176
176
  "maxDepth": "undocumented",
177
177
  "background": true,
178
178
  "subagentToolkit": "full",
179
- "backgroundDispatch": "undocumented"
179
+ "backgroundDispatch": "undocumented",
180
+ "isolation": "undocumented"
180
181
  },
181
182
  "modelMode": "passive",
182
183
  "hookBus": "host",
183
184
  "stateIO": "filesystem",
184
185
  "transport": "mcp",
185
- "runtime": "go"
186
+ "runtime": "go",
187
+ "effortSurface": "undocumented"
186
188
  },
187
189
  "hostBehaviors": {
188
190
  "reviewerCli": true,
@@ -191,12 +193,53 @@ const capabilities = {
191
193
  "hookPathStyle": "raw",
192
194
  "globalDirResolver": "antigravity"
193
195
  }
196
+ },
197
+ "reviewer": {
198
+ "slug": "antigravity",
199
+ "flags": [
200
+ "--antigravity",
201
+ "--agy"
202
+ ],
203
+ "transport": "spawn",
204
+ "probe": {
205
+ "kind": "command-exists",
206
+ "binary": "agy"
207
+ },
208
+ "invoke": {
209
+ "binary": "agy",
210
+ "args": [
211
+ "--print-timeout",
212
+ "540s",
213
+ "{{model}}",
214
+ "-p",
215
+ "{{prompt}}"
216
+ ],
217
+ "promptChannel": "argv-file-ref",
218
+ "outputChannel": "stdout",
219
+ "modelArg": "--model",
220
+ "effortChannel": "none"
221
+ },
222
+ "timeoutFloorMs": 600000,
223
+ "emptyOutput": "handler-owned",
224
+ "reviewsSection": "Antigravity",
225
+ "evidenceClass": "source-grounded",
226
+ "requiresBinaries": [],
227
+ "promptBudgetKey": null,
228
+ "modelConfigKey": "review.models.agy",
229
+ "handler": "antigravity"
230
+ },
231
+ "config": {
232
+ "review.models.agy": {
233
+ "type": "string",
234
+ "default": "",
235
+ "description": "Model passed to the Antigravity reviewer lane. The key suffix is the lane binary/flag alias `agy`, not the slug `antigravity` — preserved verbatim so existing .planning/config.json files keep working."
236
+ }
194
237
  }
195
238
  },
196
239
  "assumption-delta": {
197
240
  "id": "assumption-delta",
198
241
  "role": "feature",
199
- "version": "1.8.0",
242
+ "version": "1.9.0",
200
243
  "title": "Assumption-delta architecture checkpoint",
201
244
  "description": "Rarely-firing advisory checkpoint that triggers when a phase makes something plural, optional, or chosen that used to be singular, required, or derived. Surfaces one identity-model question (promote the new general representation to primary, or add it alongside?) so a silent primary-key drift does not accumulate into a later user-facing bug. Non-blocking; fires only on a detected signal.",
202
245
  "tier": "full",
@@ -242,7 +285,7 @@ const capabilities = {
242
285
  "audit": {
243
286
  "id": "audit",
244
287
  "role": "feature",
245
- "version": "1.8.0",
288
+ "version": "1.9.0",
246
289
  "title": "Audit",
247
290
  "description": "Open-artifact audit and UAT-gap audit for milestone close gates; exposes `gsd-tools audit-uat` (cross-phase UAT outstanding items) and `gsd-tools audit-open` (structured open-artifact scan across debug, tasks, threads, todos, seeds, UAT, verification, context-questions).",
248
291
  "tier": "full",
@@ -279,7 +322,7 @@ const capabilities = {
279
322
  "augment": {
280
323
  "id": "augment",
281
324
  "role": "runtime",
282
- "version": "1.8.0",
325
+ "version": "1.9.0",
283
326
  "title": "Augment Code",
284
327
  "description": "Augment Code CLI — commands + nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
285
328
  "tier": "core",
@@ -373,20 +416,22 @@ const capabilities = {
373
416
  "maxDepth": "undocumented",
374
417
  "background": true,
375
418
  "subagentToolkit": "full",
376
- "backgroundDispatch": "undocumented"
419
+ "backgroundDispatch": "undocumented",
420
+ "isolation": "undocumented"
377
421
  },
378
422
  "modelMode": "passive",
379
423
  "hookBus": "host",
380
424
  "stateIO": "filesystem",
381
425
  "transport": "mcp",
382
- "runtime": "node"
426
+ "runtime": "node",
427
+ "effortSurface": "undocumented"
383
428
  }
384
429
  }
385
430
  },
386
431
  "broken-windows": {
387
432
  "id": "broken-windows",
388
433
  "role": "feature",
389
- "version": "1.8.0",
434
+ "version": "1.9.0",
390
435
  "title": "Broken-windows ledger",
391
436
  "description": "Cross-phase defect register accumulating stubs, TODOs, skipped tests, unrun verifies, and unmet truths into .planning/WINDOWS.md. Blocks /gsd-ship while any window is open unless explicitly waived with a recorded reason. Operationalizes GSD's no-defer discipline as a tracked, enforced artifact (issue #1950).",
392
437
  "tier": "full",
@@ -432,7 +477,7 @@ const capabilities = {
432
477
  "claude": {
433
478
  "id": "claude",
434
479
  "role": "runtime",
435
- "version": "1.8.0",
480
+ "version": "1.9.0",
436
481
  "title": "Claude Code",
437
482
  "description": "Anthropic Claude Code — primary development runtime; tier-1 support with full hook surface and skills-based global install.",
438
483
  "tier": "core",
@@ -503,14 +548,17 @@ const capabilities = {
503
548
  "maxDepth": 5,
504
549
  "background": true,
505
550
  "subagentToolkit": "full",
506
- "backgroundDispatch": false
551
+ "backgroundDispatch": false,
552
+ "isolation": "harness-worktree"
507
553
  },
508
554
  "modelMode": "passive",
509
555
  "hookBus": "host",
510
556
  "stateIO": "filesystem",
511
557
  "transport": "mcp",
512
- "runtime": "node"
558
+ "runtime": "node",
559
+ "effortSurface": "argv"
513
560
  },
561
+ "harnessIsolationFlag": "isolation=\"worktree\"",
514
562
  "hostBehaviors": {
515
563
  "attributionSource": "settings-json-commit",
516
564
  "authorsCanonicalWorkflow": true,
@@ -532,12 +580,51 @@ const capabilities = {
532
580
  "hyphenNameAgentBody": true,
533
581
  "reviewerCli": true
534
582
  }
583
+ },
584
+ "reviewer": {
585
+ "slug": "claude",
586
+ "flags": [
587
+ "--claude"
588
+ ],
589
+ "transport": "spawn",
590
+ "probe": {
591
+ "kind": "command-exists",
592
+ "binary": "claude"
593
+ },
594
+ "invoke": {
595
+ "binary": "claude",
596
+ "args": [
597
+ "{{model}}",
598
+ "{{effort}}",
599
+ "-p",
600
+ "-"
601
+ ],
602
+ "promptChannel": "stdin",
603
+ "outputChannel": "stdout",
604
+ "modelArg": "--model",
605
+ "effortChannel": "argv"
606
+ },
607
+ "timeoutFloorMs": 1200000,
608
+ "emptyOutput": "stub-with-stderr",
609
+ "reviewsSection": "Claude",
610
+ "evidenceClass": "source-grounded",
611
+ "requiresBinaries": [],
612
+ "promptBudgetKey": null,
613
+ "modelConfigKey": "review.models.claude",
614
+ "handler": null
615
+ },
616
+ "config": {
617
+ "review.models.claude": {
618
+ "type": "string",
619
+ "default": "",
620
+ "description": "Model passed to the Claude reviewer lane."
621
+ }
535
622
  }
536
623
  },
537
624
  "claude-orchestration": {
538
625
  "id": "claude-orchestration",
539
626
  "role": "feature",
540
- "version": "1.8.0",
627
+ "version": "1.9.0",
541
628
  "title": "Claude orchestration (Workflow backend)",
542
629
  "description": "Default-off, BETA, claude-only capability that adopts Claude Code's Workflow tool (the engine behind /effort ultracode) as an optional parallel-execution backend for the GSD loop. When the runtime exposes the Workflow tool and claude_orchestration.execution_backend resolves to 'workflow', execute-phase emits a generated Workflow script (waves -> parallel() barriers, plans -> agent({ agentType: 'gsd-executor', isolation: 'worktree' }), files_modified overlap -> separate sequential stages, resumeFromRunId wired to the phase run id, shared token budget) that composes the SAME gsd-executor agent and worktree isolation the inline path uses, restoring the wave parallelism the #853 backgrounded-agent nesting limitation forces inline on Claude Code. (The plan-checker and verifier remain inline until separately wired — this capability delivers the parallel-execution backend, not those gates.) Also folds the ultraplan plan-offload under one runtime gate (plan:* surface). On any runtime lacking the Workflow tool, or when the capability is disabled, behaviour is byte-identical to today (inline/manual dispatch). Detection + emission live in gsd-core/bin/lib/claude-orchestration.cjs (pure, fail-closed). Mirrors the existing gsd-ultraplan-phase BETA-isolation posture.",
543
630
  "tier": "full",
@@ -596,7 +683,7 @@ const capabilities = {
596
683
  "into": "executor",
597
684
  "fragment": {
598
685
  "path": "fragments/execute-wave-pre.md",
599
- "inline": "# Claude orchestration — Workflow execution backend (BETA)\n\n> Injected at `execute:wave:pre` `into: executor` only when\n> `claude_orchestration.enabled` is true. Default-off; `onError: skip`.\n\n## When this contribution is active\n\nThe Claude orchestration capability is **default-off and BETA**. It activates only\nwhen ALL of the following hold:\n\n1. `claude_orchestration.enabled` is `true` in `.planning/config.json`, AND\n2. the active runtime is **Claude Code** (the Workflow tool is Claude / Agent\n SDK-specific), AND\n3. `claude_orchestration.execution_backend` resolves to `workflow` — either\n explicitly, or via `auto` — **and** the Agent SDK version is\n `>= claude_orchestration.min_agent_sdk_version` (default `0.3.149`). The SDK\n floor applies in both `auto` and `workflow` modes (fail-closed: a pre-release\n or older SDK never activates the preview backend).\n\nDetection is fail-closed: any miss degrades to **inline, manual, one-agent-per-\nmessage dispatch** — exactly today's behaviour. On a non-Claude runtime this\ncontribution is a no-op.\n\n## Why `execute:wave:pre` (not `execute:wave:post`)\n\nThis is a **dispatch-backend selector** — it decides HOW a wave's executor agents\nare spawned. That decision has to be made BEFORE the wave's `Agent()` calls in\n`execute-phase.md` step 3, not after the wave has already finished (#2285). The\ncapability previously registered at `execute:wave:post`, which fires only after\nworktree merge/post-merge tests/tracking updates — by then the wave was already\ndispatched inline, so the contribution was structurally unable to change how\ndispatch happened. This fragment is injected at the point that actually precedes\ndispatch.\n\n## What the orchestrator does when the Workflow backend is active\n\nBefore spawning executor agents for the current wave (execute-phase.md step 3),\nresolve the dispatch backend through the single composed CLI seam:\n\n```bash\ngsd-tools claude-orchestration resolve-wave-dispatch \\\n --waves \"$WAVE_MANIFEST_PATH\" --run-id \"$PHASE_RUN_ID\" \\\n --runtime \"$RUNTIME\" \\\n ${AGENT_SDK_VERSION:+--agent-sdk-version \"$AGENT_SDK_VERSION\"} \\\n --phase-dir \"$PHASE_DIR\" --raw\n```\n\nThis composes `detectWorkflowBackend` (the gate ladder above) with\n`emitWorkflowScript` (the wave→plan mapping below) in ONE call — the pure\nfunction backing it is `resolveWaveDispatch` in\n`gsd-core/bin/lib/claude-orchestration.cjs`. Response shape:\n`{ backend: 'inline'|'workflow', reason, script?, summary? }`.\n\n### Manifest construction (`$WAVE_MANIFEST_PATH`, `$PHASE_RUN_ID`, `$PHASE_DIR`, `$AGENT_SDK_VERSION`)\n\nThese are NOT pre-existing execute-phase.md variables — the orchestrator builds\nthem at this step, from data it already has in-context from `discover_and_group_plans`\n(the `PLAN_INDEX` JSON) and step 2.5 (the per-plan `USE_WORKTREES_FOR_PLAN` decision):\n\n1. **`$PHASE_DIR`** — reuse `{phase_dir}` from the `INIT` bundle (already loaded\n in the `initialize` step). No new value needed.\n\n2. **`$PHASE_RUN_ID`** — a stable identifier for THIS phase-execution attempt, so\n `resumeFromRunId` can resume an interrupted run without re-dispatching plans\n the Workflow tool already completed. Construct it deterministically —\n `execute-{phase_number}-{phase_slug}` — from `INIT`'s `phase_number`/`phase_slug`\n (both are already validated identifiers used elsewhere in this workflow, so\n they satisfy `emitWorkflowScript`'s `isScriptableIdentifier` check). Do NOT\n mint a new random id per wave — the SAME `$PHASE_RUN_ID` is reused for every\n wave in the phase so the Workflow tool can correctly track cross-wave resume\n state.\n\n3. **`$WAVE_MANIFEST_PATH`** — a fresh temp file for THIS wave's manifest (one\n wave = one `waves` array with a single entry, matching the wave-by-wave\n dispatch loop; do not batch multiple waves into one manifest — waves are\n dispatched in wave order, not all at once):\n\n ```bash\n WAVE_MANIFEST_PATH=$(mktemp \"${TMPDIR:-/tmp}/gsd-wave-dispatch-XXXXXX\") && mv \"$WAVE_MANIFEST_PATH\" \"$WAVE_MANIFEST_PATH.json\" && WAVE_MANIFEST_PATH=\"$WAVE_MANIFEST_PATH.json\"\n ```\n\n Then **use the Write tool** (not a bash/jq pipeline — the orchestrator already\n has every field parsed in-context) to write the manifest JSON to\n `$WAVE_MANIFEST_PATH`:\n\n ```json\n {\n \"waves\": [\n {\n \"id\": \"wave-{N}\",\n \"plans\": [\n {\n \"id\": \"{plan_id}\",\n \"brief\": \"{the SAME <objective>...<success_criteria> prompt block step 3 builds for this plan's inline Agent() call}\",\n \"files_modified\": [\"{from PLAN_INDEX.plans[].files_modified for this plan}\"],\n \"use_worktree\": {true unless step 2.5 set USE_WORKTREES_FOR_PLAN=false for this plan}\n }\n ]\n }\n ]\n }\n ```\n\n - **`id`** — the plan id from `PLAN_INDEX`, e.g. `\"01-01\"`.\n - **`brief`** — MUST carry the same task content as step 3's inline `Agent()`\n prompt (the `<objective>`/`<execution_context>`/`<files_to_read>`/\n `<success_criteria>` block, with `{plan_number}`/`{phase_number}`/\n `{phase_name}` substituted) — a short summary here would NOT reproduce\n step 3's behavior and would violate the \"identical artifacts\" contract.\n - **`files_modified`** — copy verbatim from the plan's `PLAN_INDEX` entry.\n - **`use_worktree`** — `true` for every plan UNLESS step 2.5's per-plan\n worktree gate (`execute-phase/steps/per-plan-worktree-gate.md`) set\n `USE_WORKTREES_FOR_PLAN=false` for that plan (submodule-touching plan, or\n project-level `USE_WORKTREES=false`) — in which case pass `false` here so\n `emitWorkflowScript` omits `isolation: \"worktree\"` for that plan (#2772 /\n #2285 finding 1). **Never** hardcode `true` — that would force worktree\n isolation on a plan the inline path explicitly keeps out of worktrees.\n\n4. **`$AGENT_SDK_VERSION`** — see below; OMIT when unknown (fails closed).\n\n**Agent SDK version:** the orchestrator has no scriptable (bash-computable) way\nto introspect the live Agent SDK version. When it can determine the version\n(e.g. from a host-exposed value it can read directly), pass\n`--agent-sdk-version`. When it cannot, OMIT the flag — `resolveWaveDispatch`'s\ngate 5 (`agent_sdk_version_unknown`) then fails closed to `inline` by design;\nthis is not a bug, it is the same fail-closed posture documented above applied\nto a real absence of information.\n\n**If `backend == \"workflow\"`:** run the emitted `script` via the Workflow tool\nfor THIS wave instead of the per-message `Agent()` loop in step 3. The script\ncomposes the SAME `gsd-executor` agent type the inline path uses, with\nworktree isolation applied PER PLAN from the manifest's `use_worktree` field\n(see `emitWorkflowScript`):\n\n- **waves → one or more sequential `parallel()` barriers** — each wave is a\n barrier group; when plans within a wave share `files_modified`, they are split\n into separate sequential stages within that wave's barrier.\n- **plans → `agent(brief, { agentType: 'gsd-executor', isolation: 'worktree' })`**\n when `use_worktree` is not `false`, or `agent(brief, { agentType: 'gsd-executor' })`\n (no isolation) when it is — so the produced `SUMMARY.md` and commits are\n identical to inline dispatch, INCLUDING the inline path's submodule safety\n gate (#2772 / #2285 finding 1).\n- **`files_modified` overlap → separate sequential stages** — the same overlap\n rule execute-phase already applies inline (step 1 of the wave loop).\n- **`resumeFromRunId`** — wired to the phase run id, so an interrupted phase\n resumes without re-running completed plans.\n\nThe orchestrator still runs steps 4–5.8 (wait for completion, worktree cleanup,\npost-merge gate, tracking update) exactly as it does for inline dispatch — the\nWorkflow backend only replaces HOW agents are spawned for this wave, not what\nhappens after they return.\n\n**If `backend == \"inline\"`** (any gate miss, or `resolve-wave-dispatch` itself\nunavailable/erroring): proceed to step 3's standard per-message `Agent()`\ndispatch — the default, byte-identical-to-today path. `onError: skip` on this\ncontribution means a `resolve-wave-dispatch` command failure is treated exactly\nlike an `inline` result, never as a fatal wave error.\n\n## Fallback contract\n\nDetection is fail-closed end-to-end: capability disabled, non-Claude runtime,\n`execution_backend:\"inline\"`, missing/incapable host descriptor, unknown or\nbelow-floor Agent SDK version, or an `emitWorkflowScript` failure on a malformed\nwave manifest — ANY of these degrades to `backend:\"inline\"` and execute-phase's\nstandard inline dispatch (step 3) runs unmodified. The Workflow backend never\npartially activates; the executor MUST NOT assume parallelism, a shared budget,\nor resume-from-run-id semantics when `backend == \"inline\"`.\n"
686
+ "inline": "# Claude orchestration — Workflow execution backend (BETA)\n\n> Injected at `execute:wave:pre` `into: executor` only when\n> `claude_orchestration.enabled` is true. Default-off; `onError: skip`.\n\n## When this contribution is active\n\nThe Claude orchestration capability is **default-off and BETA**. It activates only\nwhen ALL of the following hold:\n\n1. `claude_orchestration.enabled` is `true` in `.planning/config.json`, AND\n2. the active runtime is **Claude Code** (the Workflow tool is Claude / Agent\n SDK-specific), AND\n3. `claude_orchestration.execution_backend` resolves to `workflow` — either\n explicitly, or via `auto` — **and** the Agent SDK version is\n `>= claude_orchestration.min_agent_sdk_version` (default `0.3.149`). The SDK\n floor applies in both `auto` and `workflow` modes (fail-closed: a pre-release\n or older SDK never activates the preview backend).\n\nDetection is fail-closed: any miss degrades to **inline, manual, one-agent-per-\nmessage dispatch** — exactly today's behaviour. On a non-Claude runtime this\ncontribution is a no-op.\n\n## Why `execute:wave:pre` (not `execute:wave:post`)\n\nThis is a **dispatch-backend selector** — it decides HOW a wave's executor agents\nare spawned. That decision has to be made BEFORE the wave's `Agent()` calls in\n`execute-phase.md` step 3, not after the wave has already finished (#2285). The\ncapability previously registered at `execute:wave:post`, which fires only after\nworktree merge/post-merge tests/tracking updates — by then the wave was already\ndispatched inline, so the contribution was structurally unable to change how\ndispatch happened. This fragment is injected at the point that actually precedes\ndispatch.\n\n## What the orchestrator does when the Workflow backend is active\n\nBefore spawning executor agents for the current wave (execute-phase.md step 3),\nresolve the dispatch backend through the single composed CLI seam:\n\n```bash\ngsd-tools claude-orchestration resolve-wave-dispatch \\\n --waves \"$WAVE_MANIFEST_PATH\" --run-id \"$PHASE_RUN_ID\" \\\n --runtime \"$RUNTIME\" \\\n --phase-dir \"$PHASE_DIR\" --raw\n```\n\n`--agent-sdk-version` is no longer passed here (#2590). The router resolves the\ninstalled Agent SDK version itself; see **Agent SDK version** below. The former\n`${AGENT_SDK_VERSION:+--agent-sdk-version \"$AGENT_SDK_VERSION\"}` line was also\n**shell-dependent**: zsh does not word-split unquoted parameter expansions, so it\ncollapsed to a SINGLE argv element there, `argValue()` never matched, and the run\nfailed into `agent_sdk_version_unknown` — indistinguishable from genuinely\nunknown. Pass `--agent-sdk-version <ver>` explicitly only to pin a version.\n\nThis composes `detectWorkflowBackend` (the gate ladder above) with\n`emitWorkflowScript` (the wave→plan mapping below) in ONE call — the pure\nfunction backing it is `resolveWaveDispatch` in\n`gsd-core/bin/lib/claude-orchestration.cjs`. Response shape:\n`{ backend: 'inline'|'workflow', reason, script?, summary? }`.\n\n### Manifest construction (`$WAVE_MANIFEST_PATH`, `$PHASE_RUN_ID`, `$PHASE_DIR`)\n\nThese are NOT pre-existing execute-phase.md variables — the orchestrator builds\nthem at this step, from data it already has in-context from `discover_and_group_plans`\n(the `PLAN_INDEX` JSON) and step 2.5 (the per-plan `USE_WORKTREES_FOR_PLAN` decision):\n\n1. **`$PHASE_DIR`** — reuse `{phase_dir}` from the `INIT` bundle (already loaded\n in the `initialize` step). No new value needed.\n\n2. **`$PHASE_RUN_ID`** — a stable identifier for THIS phase-execution attempt, so\n `resumeFromRunId` can resume an interrupted run without re-dispatching plans\n the Workflow tool already completed. Construct it deterministically —\n `execute-{phase_number}-{phase_slug}` — from `INIT`'s `phase_number`/`phase_slug`\n (both are already validated identifiers used elsewhere in this workflow, so\n they satisfy `emitWorkflowScript`'s `isScriptableIdentifier` check). Do NOT\n mint a new random id per wave — the SAME `$PHASE_RUN_ID` is reused for every\n wave in the phase so the Workflow tool can correctly track cross-wave resume\n state.\n\n3. **`$WAVE_MANIFEST_PATH`** — a fresh temp file for THIS wave's manifest (one\n wave = one `waves` array with a single entry, matching the wave-by-wave\n dispatch loop; do not batch multiple waves into one manifest — waves are\n dispatched in wave order, not all at once):\n\n ```bash\n WAVE_MANIFEST_PATH=$(mktemp \"${TMPDIR:-/tmp}/gsd-wave-dispatch-XXXXXX\") && mv \"$WAVE_MANIFEST_PATH\" \"$WAVE_MANIFEST_PATH.json\" && WAVE_MANIFEST_PATH=\"$WAVE_MANIFEST_PATH.json\"\n ```\n\n Then **use the Write tool** (not a bash/jq pipeline — the orchestrator already\n has every field parsed in-context) to write the manifest JSON to\n `$WAVE_MANIFEST_PATH`:\n\n ```json\n {\n \"waves\": [\n {\n \"id\": \"wave-{N}\",\n \"plans\": [\n {\n \"id\": \"{plan_id}\",\n \"brief\": \"{the SAME <objective>...<success_criteria> prompt block step 3 builds for this plan's inline Agent() call}\",\n \"files_modified\": [\"{from PLAN_INDEX.plans[].files_modified for this plan}\"],\n \"use_worktree\": {true unless step 2.5 set USE_WORKTREES_FOR_PLAN=false for this plan}\n }\n ]\n }\n ]\n }\n ```\n\n - **`id`** — the plan id from `PLAN_INDEX`, e.g. `\"01-01\"`.\n - **`brief`** — MUST carry the same task content as step 3's inline `Agent()`\n prompt (the `<objective>`/`<execution_context>`/`<files_to_read>`/\n `<success_criteria>` block, with `{plan_number}`/`{phase_number}`/\n `{phase_name}` substituted) — a short summary here would NOT reproduce\n step 3's behavior and would violate the \"identical artifacts\" contract.\n - **`files_modified`** — copy verbatim from the plan's `PLAN_INDEX` entry.\n - **`use_worktree`** — `true` for every plan UNLESS step 2.5's per-plan\n worktree gate (`execute-phase/steps/per-plan-worktree-gate.md`) set\n `USE_WORKTREES_FOR_PLAN=false` for that plan (submodule-touching plan, or\n project-level `USE_WORKTREES=false`) — in which case pass `false` here so\n `emitWorkflowScript` omits `isolation: \"worktree\"` for that plan (#2772 /\n #2285 finding 1). **Never** hardcode `true` — that would force worktree\n isolation on a plan the inline path explicitly keeps out of worktrees.\n\n4. **`$AGENT_SDK_VERSION`** — no longer built here; the router resolves it.\n\n**Agent SDK version:** the orchestrator has no *bash-computable* way to\nintrospect the live Agent SDK version — but the router runs in Node, so it\nresolves the version itself (#2590), in this order:\n\n1. an explicit `--agent-sdk-version <ver>` (pin a version),\n2. `GSD_AGENT_SDK_VERSION`,\n3. the **installed** `@anthropic-ai/claude-agent-sdk` package version, read from\n its `package.json` on disk by walking `node_modules` up the tree. (Read\n directly rather than via `require.resolve`: the SDK's `exports` map does not\n expose `./package.json`, so `require.resolve` throws\n `ERR_PACKAGE_PATH_NOT_EXPORTED`.)\n\nPreviously nothing computed this at all, so gate 5 returned\n`agent_sdk_version_unknown` on **every** automated run and the Workflow backend\ncould never activate — while `gsd-tools capability state` still reported the\ncapability `active: true`. Fail-closed is preserved: when no version can be\nresolved, gate 5 still declines to `inline`. What changed is that a resolvable\nversion is now actually found, so a genuinely-too-old SDK reports\n`agent_sdk_version_below_floor` — the truthful reason — instead of `unknown`.\n\n**If `backend == \"workflow\"`:** run the emitted `script` via the Workflow tool\nfor THIS wave instead of the per-message `Agent()` loop in step 3. The script\ncomposes the SAME `gsd-executor` agent type the inline path uses, with\nworktree isolation applied PER PLAN from the manifest's `use_worktree` field\n(see `emitWorkflowScript`):\n\n- **waves → one or more sequential `parallel()` barriers** — each wave is a\n barrier group; when plans within a wave share `files_modified`, they are split\n into separate sequential stages within that wave's barrier.\n- **plans → `agent(brief, { agentType: 'gsd-executor', isolation: 'worktree' })`**\n when `use_worktree` is not `false`, or `agent(brief, { agentType: 'gsd-executor' })`\n (no isolation) when it is — so the produced `SUMMARY.md` and commits are\n identical to inline dispatch, INCLUDING the inline path's submodule safety\n gate (#2772 / #2285 finding 1).\n- **`files_modified` overlap → separate sequential stages** — the same overlap\n rule execute-phase already applies inline (step 1 of the wave loop).\n- **`resumeFromRunId`** — **pass `summary.resumeRunId` as the Workflow tool's\n `resumeFromRunId` INPUT when you invoke the tool.** It is a tool parameter,\n not a script function; the script deliberately does not call it (#2590 — doing\n so threw \"resumeFromRunId is not defined\" and rejected the entire script).\n Omitting it from the tool invocation silently regresses phase-resume to a\n no-op: an interrupted phase re-runs completed plans.\n\nThe orchestrator still runs steps 4–5.8 (wait for completion, worktree cleanup,\npost-merge gate, tracking update) exactly as it does for inline dispatch — the\nWorkflow backend only replaces HOW agents are spawned for this wave, not what\nhappens after they return.\n\n**If `backend == \"inline\"`** (any gate miss, or `resolve-wave-dispatch` itself\nunavailable/erroring): proceed to step 3's standard per-message `Agent()`\ndispatch — the default, byte-identical-to-today path. `onError: skip` on this\ncontribution means a `resolve-wave-dispatch` command failure is treated exactly\nlike an `inline` result, never as a fatal wave error.\n\n## Fallback contract\n\nDetection is fail-closed end-to-end: capability disabled, non-Claude runtime,\n`execution_backend:\"inline\"`, missing/incapable host descriptor, unknown or\nbelow-floor Agent SDK version, or an `emitWorkflowScript` failure on a malformed\nwave manifest — ANY of these degrades to `backend:\"inline\"` and execute-phase's\nstandard inline dispatch (step 3) runs unmodified. The Workflow backend never\npartially activates; the executor MUST NOT assume parallelism, a shared budget,\nor resume-from-run-id semantics when `backend == \"inline\"`.\n"
600
687
  },
601
688
  "produces": [],
602
689
  "consumes": [
@@ -625,7 +712,7 @@ const capabilities = {
625
712
  "cline": {
626
713
  "id": "cline",
627
714
  "role": "runtime",
628
- "version": "1.8.0",
715
+ "version": "1.9.0",
629
716
  "title": "Cline",
630
717
  "description": "Cline (VS Code extension) — global-only nested-skill layout; cline-rules hook surface (.clinerules); no hook events emitted; tier-2 support.",
631
718
  "tier": "core",
@@ -673,13 +760,15 @@ const capabilities = {
673
760
  "maxDepth": 1,
674
761
  "background": true,
675
762
  "subagentToolkit": "read-only",
676
- "backgroundDispatch": false
763
+ "backgroundDispatch": false,
764
+ "isolation": "undocumented"
677
765
  },
678
766
  "modelMode": "active",
679
767
  "hookBus": "host",
680
768
  "stateIO": "filesystem",
681
769
  "transport": "mcp",
682
- "runtime": "node"
770
+ "runtime": "node",
771
+ "effortSurface": "undocumented"
683
772
  },
684
773
  "hostBehaviors": {
685
774
  "reapplyCommand": "/gsd-update --reapply",
@@ -694,7 +783,7 @@ const capabilities = {
694
783
  "code-review": {
695
784
  "id": "code-review",
696
785
  "role": "feature",
697
- "version": "1.8.0",
786
+ "version": "1.9.0",
698
787
  "title": "Code review",
699
788
  "description": "Source-file code review and review-fix workflow support for completed execution work.",
700
789
  "tier": "full",
@@ -755,7 +844,7 @@ const capabilities = {
755
844
  "codebuddy": {
756
845
  "id": "codebuddy",
757
846
  "role": "runtime",
758
- "version": "1.8.0",
847
+ "version": "1.9.0",
759
848
  "title": "CodeBuddy",
760
849
  "description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
761
850
  "tier": "core",
@@ -850,23 +939,67 @@ const capabilities = {
850
939
  "maxDepth": 1,
851
940
  "background": true,
852
941
  "subagentToolkit": "full",
853
- "backgroundDispatch": false
942
+ "backgroundDispatch": false,
943
+ "isolation": "undocumented"
854
944
  },
855
945
  "modelMode": "passive",
856
946
  "hookBus": "host",
857
947
  "stateIO": "filesystem",
858
948
  "transport": "mcp",
859
- "runtime": "node"
949
+ "runtime": "node",
950
+ "effortSurface": "undocumented"
860
951
  },
861
952
  "hostBehaviors": {
862
953
  "reportCommandsDir": true
863
954
  }
864
955
  }
865
956
  },
957
+ "coderabbit": {
958
+ "id": "coderabbit",
959
+ "role": "reviewer",
960
+ "version": "1.9.0",
961
+ "title": "CodeRabbit",
962
+ "description": "CodeRabbit CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Reviews the working-tree diff (`coderabbit review --prompt-only`), not the source tree, and accepts neither a prompt nor a model flag; findings are down-weighted in consensus (evidenceClass: diff-only).",
963
+ "tier": "full",
964
+ "requires": [],
965
+ "engines": {
966
+ "gsd": ">=1.8.0"
967
+ },
968
+ "reviewer": {
969
+ "slug": "coderabbit",
970
+ "flags": [
971
+ "--coderabbit"
972
+ ],
973
+ "transport": "spawn",
974
+ "probe": {
975
+ "kind": "command-exists",
976
+ "binary": "coderabbit"
977
+ },
978
+ "invoke": {
979
+ "binary": "coderabbit",
980
+ "args": [
981
+ "review",
982
+ "--prompt-only"
983
+ ],
984
+ "promptChannel": "none",
985
+ "outputChannel": "stdout",
986
+ "modelArg": null,
987
+ "effortChannel": "none"
988
+ },
989
+ "timeoutFloorMs": 360000,
990
+ "emptyOutput": "stub-with-stderr",
991
+ "reviewsSection": "CodeRabbit",
992
+ "evidenceClass": "diff-only",
993
+ "requiresBinaries": [],
994
+ "promptBudgetKey": null,
995
+ "modelConfigKey": null,
996
+ "handler": null
997
+ }
998
+ },
866
999
  "codex": {
867
1000
  "id": "codex",
868
1001
  "role": "runtime",
869
- "version": "1.8.0",
1002
+ "version": "1.9.0",
870
1003
  "title": "OpenAI Codex CLI",
871
1004
  "description": "OpenAI Codex CLI — shell-var command style; per-agent sandbox tiers; config.toml + hooks.json hook surface; tier-1 support.",
872
1005
  "tier": "core",
@@ -930,13 +1063,23 @@ const capabilities = {
930
1063
  "maxDepth": 1,
931
1064
  "background": true,
932
1065
  "subagentToolkit": "full",
933
- "backgroundDispatch": true
1066
+ "backgroundDispatch": true,
1067
+ "isolation": "orchestrator-worktree"
934
1068
  },
935
1069
  "modelMode": "passive",
936
1070
  "hookBus": "host",
937
1071
  "stateIO": "filesystem",
938
1072
  "transport": "mcp",
939
- "runtime": "node"
1073
+ "runtime": "node",
1074
+ "effortSurface": "argv"
1075
+ },
1076
+ "orchestratorExec": {
1077
+ "command": "codex",
1078
+ "args": [
1079
+ "exec"
1080
+ ],
1081
+ "cwdFlag": "--cd",
1082
+ "promptFlag": null
940
1083
  },
941
1084
  "hostBehaviors": {
942
1085
  "reapplyCommand": "$gsd-update --reapply",
@@ -946,12 +1089,55 @@ const capabilities = {
946
1089
  "frontmatterDialect": "codex",
947
1090
  "reviewerCli": true
948
1091
  }
1092
+ },
1093
+ "reviewer": {
1094
+ "slug": "codex",
1095
+ "flags": [
1096
+ "--codex"
1097
+ ],
1098
+ "transport": "spawn",
1099
+ "probe": {
1100
+ "kind": "command-exists",
1101
+ "binary": "codex"
1102
+ },
1103
+ "invoke": {
1104
+ "binary": "codex",
1105
+ "args": [
1106
+ "exec",
1107
+ "--ephemeral",
1108
+ "{{model}}",
1109
+ "{{effort}}",
1110
+ "--skip-git-repo-check",
1111
+ "{{output}}",
1112
+ "-"
1113
+ ],
1114
+ "promptChannel": "stdin",
1115
+ "outputChannel": "file-arg",
1116
+ "outputArg": "-o",
1117
+ "modelArg": "--model",
1118
+ "effortChannel": "argv"
1119
+ },
1120
+ "timeoutFloorMs": 1200000,
1121
+ "emptyOutput": "stub-with-stderr",
1122
+ "reviewsSection": "Codex",
1123
+ "evidenceClass": "source-grounded",
1124
+ "requiresBinaries": [],
1125
+ "promptBudgetKey": null,
1126
+ "modelConfigKey": "review.models.codex",
1127
+ "handler": null
1128
+ },
1129
+ "config": {
1130
+ "review.models.codex": {
1131
+ "type": "string",
1132
+ "default": "",
1133
+ "description": "Model passed to the Codex reviewer lane."
1134
+ }
949
1135
  }
950
1136
  },
951
1137
  "copilot": {
952
1138
  "id": "copilot",
953
1139
  "role": "runtime",
954
- "version": "1.8.0",
1140
+ "version": "1.9.0",
955
1141
  "title": "GitHub Copilot",
956
1142
  "description": "GitHub Copilot (VS Code) — markdown config format; copilot-inline hook surface; no hook events emitted; flat skill nesting (unconfirmed recursive loader); tier-2 support.",
957
1143
  "tier": "core",
@@ -1025,13 +1211,15 @@ const capabilities = {
1025
1211
  "maxDepth": 1,
1026
1212
  "background": true,
1027
1213
  "subagentToolkit": "full",
1028
- "backgroundDispatch": false
1214
+ "backgroundDispatch": false,
1215
+ "isolation": "undocumented"
1029
1216
  },
1030
1217
  "modelMode": "passive",
1031
1218
  "hookBus": "host",
1032
1219
  "stateIO": "filesystem",
1033
1220
  "transport": "mcp",
1034
- "runtime": "undocumented"
1221
+ "runtime": "undocumented",
1222
+ "effortSurface": "undocumented"
1035
1223
  },
1036
1224
  "hostBehaviors": {
1037
1225
  "reapplyCommand": "/gsd-update --reapply",
@@ -1044,7 +1232,7 @@ const capabilities = {
1044
1232
  "cursor": {
1045
1233
  "id": "cursor",
1046
1234
  "role": "runtime",
1047
- "version": "1.8.0",
1235
+ "version": "1.9.0",
1048
1236
  "title": "Cursor",
1049
1237
  "description": "Cursor IDE — skills + converted commands artifact layout; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.",
1050
1238
  "tier": "core",
@@ -1134,14 +1322,17 @@ const capabilities = {
1134
1322
  "maxDepth": 2,
1135
1323
  "background": true,
1136
1324
  "subagentToolkit": "full",
1137
- "backgroundDispatch": true
1325
+ "backgroundDispatch": true,
1326
+ "isolation": "harness-worktree"
1138
1327
  },
1139
1328
  "modelMode": "passive",
1140
1329
  "hookBus": "host",
1141
1330
  "stateIO": "filesystem",
1142
1331
  "transport": "mcp",
1143
- "runtime": "node"
1332
+ "runtime": "node",
1333
+ "effortSurface": "undocumented"
1144
1334
  },
1335
+ "harnessIsolationFlag": "--worktree",
1145
1336
  "hostBehaviors": {
1146
1337
  "reapplyCommand": "gsd-update --reapply (mention the skill name)",
1147
1338
  "frontmatterDialect": "cursor",
@@ -1160,12 +1351,47 @@ const capabilities = {
1160
1351
  ],
1161
1352
  "reviewerCli": true
1162
1353
  }
1354
+ },
1355
+ "reviewer": {
1356
+ "slug": "cursor",
1357
+ "flags": [
1358
+ "--cursor"
1359
+ ],
1360
+ "transport": "spawn",
1361
+ "probe": {
1362
+ "kind": "command-exists",
1363
+ "binary": "cursor-agent"
1364
+ },
1365
+ "invoke": {
1366
+ "binary": "cursor-agent",
1367
+ "args": [
1368
+ "-p",
1369
+ "--mode",
1370
+ "ask",
1371
+ "--trust",
1372
+ "--output-format",
1373
+ "text",
1374
+ "{{prompt}}"
1375
+ ],
1376
+ "promptChannel": "argv-file-ref",
1377
+ "outputChannel": "stdout",
1378
+ "modelArg": null,
1379
+ "effortChannel": "none"
1380
+ },
1381
+ "timeoutFloorMs": 900000,
1382
+ "emptyOutput": "stub-with-stderr",
1383
+ "reviewsSection": "Cursor",
1384
+ "evidenceClass": "source-grounded",
1385
+ "requiresBinaries": [],
1386
+ "promptBudgetKey": null,
1387
+ "modelConfigKey": null,
1388
+ "handler": null
1163
1389
  }
1164
1390
  },
1165
1391
  "drift": {
1166
1392
  "id": "drift",
1167
1393
  "role": "feature",
1168
- "version": "1.8.0",
1394
+ "version": "1.9.0",
1169
1395
  "title": "Drift detection gates",
1170
1396
  "description": "Drift detection gates for the planning loop. At execute:wave:post: a blocking schema drift gate (detects schema files changed without a database push) and a non-blocking codebase drift gate (detects structural additions not reflected in STRUCTURE.md). At plan:pre: a non-blocking, warn-only codebase drift gate (gated on workflow.plan_drift_precheck) that flags a stale codebase map before planning, so plans are authored against a fresh STRUCTURE.md instead of discovering drift mid-execution.",
1171
1397
  "tier": "full",
@@ -1243,7 +1469,7 @@ const capabilities = {
1243
1469
  "external-job": {
1244
1470
  "id": "external-job",
1245
1471
  "role": "feature",
1246
- "version": "1.8.0",
1472
+ "version": "1.9.0",
1247
1473
  "title": "Async external-job scheduler adapter",
1248
1474
  "description": "Default-off producer of the async external-job manifest (#1164). At execute:wave:post an executor can externalize long-running compute (SLURM first, scheduler-pluggable), commit a .planning/async-jobs/<job>.json manifest, defer SUMMARY.md, and return external_job_waiting. The core loop (#1165) consumes the manifest; this capability is the only thing that writes it. NOTE on contribution point: #1164 specifies execute:wave:pre, but execute-phase.md only dispatches execute:wave:post today (wave:pre is declared in the loop host contract but not rendered); wiring wave:pre dispatch is a core-loop change #1164 explicitly puts out of scope, so this capability registers at wave:post and the executor honors the runtime_budget classification guidance before running any tagged task. The adapter (scripts/slurm-adapter.cjs) reads external_job.submit_timeout_ms / poll_timeout_ms / artifact_dir through the canonical capability-config seam (env override > config > registry default).",
1249
1475
  "tier": "full",
@@ -1326,7 +1552,7 @@ const capabilities = {
1326
1552
  "gap-analysis": {
1327
1553
  "id": "gap-analysis",
1328
1554
  "role": "feature",
1329
- "version": "1.8.0",
1555
+ "version": "1.9.0",
1330
1556
  "title": "Post-planning gap analysis",
1331
1557
  "description": "Proactive, non-blocking post-planning coverage report. After all PLAN.md files are generated, cross-references every REQ-ID and D-ID from REQUIREMENTS.md and CONTEXT.md against plan bodies. Emits a Source | Item | Status table. Does not block phase advancement.",
1332
1558
  "tier": "standard",
@@ -1364,10 +1590,60 @@ const capabilities = {
1364
1590
  }
1365
1591
  ]
1366
1592
  },
1593
+ "gemini": {
1594
+ "id": "gemini",
1595
+ "role": "reviewer",
1596
+ "version": "1.9.0",
1597
+ "title": "Gemini CLI",
1598
+ "description": "Google Gemini CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Spawned as `gemini -p - -m <model>` with the plan piped on stdin.",
1599
+ "tier": "full",
1600
+ "requires": [],
1601
+ "engines": {
1602
+ "gsd": ">=1.8.0"
1603
+ },
1604
+ "reviewer": {
1605
+ "slug": "gemini",
1606
+ "flags": [
1607
+ "--gemini"
1608
+ ],
1609
+ "transport": "spawn",
1610
+ "probe": {
1611
+ "kind": "command-exists",
1612
+ "binary": "gemini"
1613
+ },
1614
+ "invoke": {
1615
+ "binary": "gemini",
1616
+ "args": [
1617
+ "{{model}}",
1618
+ "-p",
1619
+ "-"
1620
+ ],
1621
+ "promptChannel": "stdin",
1622
+ "outputChannel": "stdout",
1623
+ "modelArg": "-m",
1624
+ "effortChannel": "none"
1625
+ },
1626
+ "timeoutFloorMs": 900000,
1627
+ "emptyOutput": "stub-with-stderr",
1628
+ "reviewsSection": "Gemini",
1629
+ "evidenceClass": "source-grounded",
1630
+ "requiresBinaries": [],
1631
+ "promptBudgetKey": null,
1632
+ "modelConfigKey": "review.models.gemini",
1633
+ "handler": null
1634
+ },
1635
+ "config": {
1636
+ "review.models.gemini": {
1637
+ "type": "string",
1638
+ "default": "",
1639
+ "description": "Model passed to the Gemini reviewer lane."
1640
+ }
1641
+ }
1642
+ },
1367
1643
  "graphify": {
1368
1644
  "id": "graphify",
1369
1645
  "role": "feature",
1370
- "version": "1.8.0",
1646
+ "version": "1.9.0",
1371
1647
  "title": "Knowledge graph",
1372
1648
  "description": "Build, query, and inspect the project knowledge graph in `.planning/graphs/`; exposes graphify CLI subcommands (build, query, status, diff) and the /gsd-graphify skill.",
1373
1649
  "tier": "full",
@@ -1408,7 +1684,7 @@ const capabilities = {
1408
1684
  "hermes": {
1409
1685
  "id": "hermes",
1410
1686
  "role": "runtime",
1411
- "version": "1.8.0",
1687
+ "version": "1.9.0",
1412
1688
  "title": "Hermes Agent",
1413
1689
  "description": "Hermes Agent (NousResearch) — skills nest under skills/gsd/ category bucket; nested skill layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
1414
1690
  "tier": "core",
@@ -1484,20 +1760,22 @@ const capabilities = {
1484
1760
  "maxDepth": 1,
1485
1761
  "background": true,
1486
1762
  "subagentToolkit": "read-only",
1487
- "backgroundDispatch": false
1763
+ "backgroundDispatch": false,
1764
+ "isolation": "undocumented"
1488
1765
  },
1489
1766
  "modelMode": "active",
1490
1767
  "hookBus": "host",
1491
1768
  "stateIO": "filesystem",
1492
1769
  "transport": "mcp",
1493
- "runtime": "python"
1770
+ "runtime": "python",
1771
+ "effortSurface": "undocumented"
1494
1772
  }
1495
1773
  }
1496
1774
  },
1497
1775
  "intel": {
1498
1776
  "id": "intel",
1499
1777
  "role": "feature",
1500
- "version": "1.8.0",
1778
+ "version": "1.9.0",
1501
1779
  "title": "Codebase intelligence",
1502
1780
  "description": "Code-intelligence store for codebase querying, diff, snapshot, and API-surface extraction; exposes `gsd-tools intel` subcommands (query, status, update, diff, snapshot, patch-meta, validate, extract-exports, api-surface) and backs `/gsd-map-codebase` and `gsd-intel-updater`.",
1503
1781
  "tier": "full",
@@ -1549,7 +1827,7 @@ const capabilities = {
1549
1827
  "kilo": {
1550
1828
  "id": "kilo",
1551
1829
  "role": "runtime",
1552
- "version": "1.8.0",
1830
+ "version": "1.9.0",
1553
1831
  "title": "Kilo Code",
1554
1832
  "description": "Kilo Code — XDG-based config dir; global skills at ~/.kilo/skills (separate from XDG config); flat command/ + skills artifact layout; no lifecycle hook registration; tier-2 support.",
1555
1833
  "tier": "core",
@@ -1630,13 +1908,15 @@ const capabilities = {
1630
1908
  "maxDepth": -1,
1631
1909
  "background": true,
1632
1910
  "subagentToolkit": "undocumented",
1633
- "backgroundDispatch": false
1911
+ "backgroundDispatch": false,
1912
+ "isolation": "undocumented"
1634
1913
  },
1635
1914
  "modelMode": "active",
1636
1915
  "hookBus": "host",
1637
1916
  "stateIO": "filesystem",
1638
1917
  "transport": "mcp",
1639
- "runtime": "bun"
1918
+ "runtime": "bun",
1919
+ "effortSurface": "undocumented"
1640
1920
  },
1641
1921
  "hostBehaviors": {
1642
1922
  "reapplyCommand": "/gsd-update --reapply",
@@ -1656,7 +1936,7 @@ const capabilities = {
1656
1936
  "kimi": {
1657
1937
  "id": "kimi",
1658
1938
  "role": "runtime",
1659
- "version": "1.8.0",
1939
+ "version": "1.9.0",
1660
1940
  "title": "Kimi CLI",
1661
1941
  "description": "Kimi CLI (Moonshot AI) — generic agents root at ~/.config/agents; skills + kimi-agents artifact layout; native config.toml [[hooks]] bus at ~/.kimi/config.toml; background dispatch; tier-2 support.",
1662
1942
  "tier": "core",
@@ -1723,13 +2003,23 @@ const capabilities = {
1723
2003
  "maxDepth": 1,
1724
2004
  "background": true,
1725
2005
  "subagentToolkit": "undocumented",
1726
- "backgroundDispatch": true
2006
+ "backgroundDispatch": true,
2007
+ "isolation": "orchestrator-worktree"
1727
2008
  },
1728
2009
  "modelMode": "passive",
1729
2010
  "hookBus": "host",
1730
2011
  "stateIO": "filesystem",
1731
2012
  "transport": "mcp",
1732
- "runtime": "python"
2013
+ "runtime": "python",
2014
+ "effortSurface": "undocumented"
2015
+ },
2016
+ "orchestratorExec": {
2017
+ "command": "kimi",
2018
+ "args": [
2019
+ "--print"
2020
+ ],
2021
+ "cwdFlag": "--work-dir",
2022
+ "promptFlag": "--prompt"
1733
2023
  },
1734
2024
  "hostBehaviors": {
1735
2025
  "reapplyCommand": "/skill:gsd-update --reapply",
@@ -1741,10 +2031,258 @@ const capabilities = {
1741
2031
  }
1742
2032
  }
1743
2033
  },
2034
+ "kimi-code": {
2035
+ "id": "kimi-code",
2036
+ "role": "runtime",
2037
+ "version": "1.9.0",
2038
+ "title": "Kimi Code CLI",
2039
+ "description": "Kimi Code CLI (Moonshot AI, Node) — Agent Skills auto-discovered at ~/.kimi-code/skills; global AGENTS.md at ~/.kimi-code/AGENTS.md; native config.toml + [[hooks]] bus; three built-in subagents (coder/explore/plan), NO custom named subagents; background dispatch; tier-2 support. Distinct from Python kimi-cli (the 'kimi' capability) per ADR-1239 EoS — Kimi Code cannot dispatch named subagents so the kimi-agents YAML layout does NOT apply; persona injection rides the existing ${AGENT_SKILLS_*} workflow fallback. Install-layout, agent-install-check, and install-time decision (kimi vs kimi-code) land in follow-up PRs; this descriptor is the EoS foundation.",
2040
+ "tier": "core",
2041
+ "requires": [],
2042
+ "engines": {
2043
+ "gsd": ">=1.7.0"
2044
+ },
2045
+ "runtime": {
2046
+ "configHome": {
2047
+ "kind": "dot-home",
2048
+ "name": ".kimi-code",
2049
+ "env": [
2050
+ "KIMI_CODE_HOME"
2051
+ ],
2052
+ "probe": [
2053
+ "~/.kimi-code"
2054
+ ],
2055
+ "probeExists": "config.toml"
2056
+ },
2057
+ "localConfigDir": ".kimi-code",
2058
+ "configFormat": "none",
2059
+ "artifactLayout": {
2060
+ "global": [
2061
+ {
2062
+ "kind": "skills",
2063
+ "destSubpath": "skills",
2064
+ "prefix": "gsd-",
2065
+ "nesting": "flat",
2066
+ "recursive": false,
2067
+ "converter": "convertClaudeCommandToKimiCodeSkill"
2068
+ }
2069
+ ],
2070
+ "local": []
2071
+ },
2072
+ "commandStyle": "slash-hyphen",
2073
+ "hooksSurface": "kimi-hooks-toml",
2074
+ "hookEvents": "claude",
2075
+ "sandboxTier": "none",
2076
+ "supportTier": 2,
2077
+ "installSurface": "profile-marker-only",
2078
+ "writesSharedSettings": false,
2079
+ "permissionWriter": null,
2080
+ "extendedHookEvents": [
2081
+ "SubagentStop",
2082
+ "Stop",
2083
+ "PreCompact",
2084
+ "SubagentStart"
2085
+ ],
2086
+ "hostIntegration": {
2087
+ "embeddingMode": "declarative",
2088
+ "commandSurface": "slash-file",
2089
+ "dispatch": {
2090
+ "namedDispatch": false,
2091
+ "nested": true,
2092
+ "maxDepth": "undocumented",
2093
+ "background": true,
2094
+ "subagentToolkit": "built-in-only",
2095
+ "backgroundDispatch": true,
2096
+ "builtInSubagents": [
2097
+ "coder",
2098
+ "explore",
2099
+ "plan"
2100
+ ],
2101
+ "isolation": "orchestrator-worktree"
2102
+ },
2103
+ "modelMode": "passive",
2104
+ "hookBus": "host",
2105
+ "stateIO": "filesystem",
2106
+ "transport": "mcp",
2107
+ "runtime": "node"
2108
+ },
2109
+ "orchestratorExec": {
2110
+ "command": "kimi",
2111
+ "args": [],
2112
+ "cwdFlag": null,
2113
+ "promptFlag": "--prompt"
2114
+ },
2115
+ "hostBehaviors": {
2116
+ "reapplyCommand": "/skill:gsd-update --reapply",
2117
+ "localInstallDeferred": true,
2118
+ "verificationStyle": "kimi-code",
2119
+ "agentManifestStyle": "none",
2120
+ "doneBannerStyle": "kimi-code",
2121
+ "skipSharedHooksInstall": true,
2122
+ "namedSubagentsSupported": false
2123
+ }
2124
+ },
2125
+ "reviewer": {
2126
+ "slug": "kimi-code",
2127
+ "flags": [
2128
+ "--kimi-code"
2129
+ ],
2130
+ "transport": "spawn",
2131
+ "probe": {
2132
+ "kind": "command-capability",
2133
+ "binary": "kimi",
2134
+ "needle": "--output-format",
2135
+ "timeoutMs": 5000
2136
+ },
2137
+ "invoke": {
2138
+ "binary": "kimi",
2139
+ "args": [
2140
+ "{{model}}",
2141
+ "-p",
2142
+ "{{prompt}}"
2143
+ ],
2144
+ "promptChannel": "argv-file-ref",
2145
+ "outputChannel": "stdout",
2146
+ "modelArg": "-m",
2147
+ "effortChannel": "none"
2148
+ },
2149
+ "timeoutFloorMs": 900000,
2150
+ "emptyOutput": "stub-with-stderr",
2151
+ "reviewsSection": "Kimi Code",
2152
+ "evidenceClass": "source-grounded",
2153
+ "requiresBinaries": [],
2154
+ "promptBudgetKey": null,
2155
+ "modelConfigKey": "review.models.kimi-code",
2156
+ "handler": null
2157
+ },
2158
+ "config": {
2159
+ "review.models.kimi-code": {
2160
+ "type": "string",
2161
+ "default": "",
2162
+ "description": "Model passed to the Kimi Code reviewer lane."
2163
+ }
2164
+ }
2165
+ },
2166
+ "llama-cpp": {
2167
+ "id": "llama-cpp",
2168
+ "role": "reviewer",
2169
+ "version": "1.9.0",
2170
+ "title": "llama.cpp",
2171
+ "description": "llama.cpp server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.llama_cpp_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`llama-cpp`, required by KEBAB_RE); `reviewer.slug` stays snake (`llama_cpp`) to match the shipped roster and the `review.llama_cpp_host` config key (ADR-2782's three-namespace trap).",
2172
+ "tier": "full",
2173
+ "requires": [],
2174
+ "engines": {
2175
+ "gsd": ">=1.8.0"
2176
+ },
2177
+ "reviewer": {
2178
+ "slug": "llama_cpp",
2179
+ "flags": [
2180
+ "--llama-cpp"
2181
+ ],
2182
+ "transport": "openai-http",
2183
+ "probe": {
2184
+ "kind": "http-reachable",
2185
+ "hostConfigKey": "review.llama_cpp_host",
2186
+ "path": "/v1/models",
2187
+ "timeoutMs": 2000
2188
+ },
2189
+ "invoke": {
2190
+ "hostConfigKey": "review.llama_cpp_host",
2191
+ "defaultHost": "http://localhost:8080",
2192
+ "path": "/v1/chat/completions",
2193
+ "modelDiscovery": "first-from-models-endpoint",
2194
+ "fallbackModel": "local-model",
2195
+ "effortChannel": "none"
2196
+ },
2197
+ "timeoutFloorMs": 120000,
2198
+ "emptyOutput": "stub-with-stderr",
2199
+ "reviewsSection": "llama.cpp",
2200
+ "evidenceClass": "source-grounded",
2201
+ "requiresBinaries": [],
2202
+ "promptBudgetKey": "review.max_prompt_tokens_per_reviewer.llama_cpp",
2203
+ "modelConfigKey": "review.models.llama_cpp",
2204
+ "handler": "openai-compatible"
2205
+ },
2206
+ "config": {
2207
+ "review.models.llama_cpp": {
2208
+ "type": "string",
2209
+ "default": "",
2210
+ "description": "Model requested from the llama.cpp reviewer lane; empty discovers the first model from /v1/models."
2211
+ },
2212
+ "review.llama_cpp_host": {
2213
+ "type": "string",
2214
+ "default": "",
2215
+ "description": "Base URL of the llama.cpp OpenAI-compatible server."
2216
+ },
2217
+ "review.max_prompt_tokens_per_reviewer.llama_cpp": {
2218
+ "type": "number",
2219
+ "default": -1,
2220
+ "description": "Prompt-token budget for the llama.cpp reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
2221
+ }
2222
+ }
2223
+ },
2224
+ "lm-studio": {
2225
+ "id": "lm-studio",
2226
+ "role": "reviewer",
2227
+ "version": "1.9.0",
2228
+ "title": "LM Studio",
2229
+ "description": "LM Studio local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.lm_studio_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`lm-studio`, required by KEBAB_RE); `reviewer.slug` stays snake (`lm_studio`) to match the shipped roster and the `review.lm_studio_host` config key (ADR-2782's three-namespace trap).",
2230
+ "tier": "full",
2231
+ "requires": [],
2232
+ "engines": {
2233
+ "gsd": ">=1.8.0"
2234
+ },
2235
+ "reviewer": {
2236
+ "slug": "lm_studio",
2237
+ "flags": [
2238
+ "--lm-studio"
2239
+ ],
2240
+ "transport": "openai-http",
2241
+ "probe": {
2242
+ "kind": "http-reachable",
2243
+ "hostConfigKey": "review.lm_studio_host",
2244
+ "path": "/v1/models",
2245
+ "timeoutMs": 2000
2246
+ },
2247
+ "invoke": {
2248
+ "hostConfigKey": "review.lm_studio_host",
2249
+ "defaultHost": "http://localhost:1234",
2250
+ "path": "/v1/chat/completions",
2251
+ "modelDiscovery": "first-from-models-endpoint",
2252
+ "fallbackModel": "local-model",
2253
+ "effortChannel": "none"
2254
+ },
2255
+ "timeoutFloorMs": 120000,
2256
+ "emptyOutput": "stub-with-stderr",
2257
+ "reviewsSection": "LM Studio",
2258
+ "evidenceClass": "source-grounded",
2259
+ "requiresBinaries": [],
2260
+ "promptBudgetKey": "review.max_prompt_tokens_per_reviewer.lm_studio",
2261
+ "modelConfigKey": "review.models.lm_studio",
2262
+ "handler": "openai-compatible"
2263
+ },
2264
+ "config": {
2265
+ "review.models.lm_studio": {
2266
+ "type": "string",
2267
+ "default": "",
2268
+ "description": "Model requested from the LM Studio reviewer lane; empty discovers the first model from /v1/models."
2269
+ },
2270
+ "review.lm_studio_host": {
2271
+ "type": "string",
2272
+ "default": "",
2273
+ "description": "Base URL of the LM Studio OpenAI-compatible server."
2274
+ },
2275
+ "review.max_prompt_tokens_per_reviewer.lm_studio": {
2276
+ "type": "number",
2277
+ "default": -1,
2278
+ "description": "Prompt-token budget for the LM Studio reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
2279
+ }
2280
+ }
2281
+ },
1744
2282
  "mempalace": {
1745
2283
  "id": "mempalace",
1746
2284
  "role": "feature",
1747
- "version": "1.8.0",
2285
+ "version": "1.9.0",
1748
2286
  "title": "MemPalace memory",
1749
2287
  "description": "Cross-session, cross-project memory: deliberate recall before discuss/plan and verbatim capture + temporal-KG sync at phase boundaries, via the MemPalace MCP server and CLI.",
1750
2288
  "tier": "full",
@@ -1918,7 +2456,7 @@ const capabilities = {
1918
2456
  "nyquist": {
1919
2457
  "id": "nyquist",
1920
2458
  "role": "feature",
1921
- "version": "1.8.0",
2459
+ "version": "1.9.0",
1922
2460
  "title": "Nyquist validation",
1923
2461
  "description": "Validation coverage audit that maps executed work back to tests and manual-only evidence.",
1924
2462
  "tier": "full",
@@ -1965,10 +2503,68 @@ const capabilities = {
1965
2503
  "contributions": [],
1966
2504
  "gates": []
1967
2505
  },
2506
+ "ollama": {
2507
+ "id": "ollama",
2508
+ "role": "reviewer",
2509
+ "version": "1.9.0",
2510
+ "title": "Ollama",
2511
+ "description": "Ollama local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.ollama_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq.",
2512
+ "tier": "full",
2513
+ "requires": [],
2514
+ "engines": {
2515
+ "gsd": ">=1.8.0"
2516
+ },
2517
+ "reviewer": {
2518
+ "slug": "ollama",
2519
+ "flags": [
2520
+ "--ollama"
2521
+ ],
2522
+ "transport": "openai-http",
2523
+ "probe": {
2524
+ "kind": "http-reachable",
2525
+ "hostConfigKey": "review.ollama_host",
2526
+ "path": "/v1/models",
2527
+ "timeoutMs": 2000
2528
+ },
2529
+ "invoke": {
2530
+ "hostConfigKey": "review.ollama_host",
2531
+ "defaultHost": "http://localhost:11434",
2532
+ "path": "/v1/chat/completions",
2533
+ "modelDiscovery": "first-from-models-endpoint",
2534
+ "fallbackModel": "llama3",
2535
+ "effortChannel": "none"
2536
+ },
2537
+ "timeoutFloorMs": 120000,
2538
+ "emptyOutput": "stub-with-stderr",
2539
+ "reviewsSection": "Ollama",
2540
+ "evidenceClass": "source-grounded",
2541
+ "requiresBinaries": [],
2542
+ "promptBudgetKey": "review.max_prompt_tokens_per_reviewer.ollama",
2543
+ "modelConfigKey": "review.models.ollama",
2544
+ "handler": "openai-compatible"
2545
+ },
2546
+ "config": {
2547
+ "review.models.ollama": {
2548
+ "type": "string",
2549
+ "default": "",
2550
+ "description": "Model requested from the Ollama reviewer lane; empty discovers the first model from /v1/models."
2551
+ },
2552
+ "review.ollama_host": {
2553
+ "type": "string",
2554
+ "default": "",
2555
+ "description": "Base URL of the Ollama OpenAI-compatible server."
2556
+ },
2557
+ "review.max_prompt_tokens_per_reviewer.ollama": {
2558
+ "type": "number",
2559
+ "default": -1,
2560
+ "description": "Prompt-token budget for the Ollama reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
2561
+ }
2562
+ }
2563
+ },
1968
2564
  "opencode": {
1969
2565
  "id": "opencode",
1970
2566
  "role": "runtime",
1971
- "version": "1.8.0",
2567
+ "version": "1.9.0",
1972
2568
  "title": "OpenCode",
1973
2569
  "description": "OpenCode — XDG-based config dir; flat commands/ + skills artifact layout; settings-json config format; no lifecycle hook registration; tier-2 support.",
1974
2570
  "tier": "core",
@@ -2042,15 +2638,25 @@ const capabilities = {
2042
2638
  "namedDispatch": true,
2043
2639
  "nested": "undocumented",
2044
2640
  "maxDepth": "undocumented",
2045
- "background": true,
2641
+ "background": false,
2046
2642
  "subagentToolkit": "full",
2047
- "backgroundDispatch": true
2643
+ "backgroundDispatch": false,
2644
+ "isolation": "orchestrator-worktree"
2048
2645
  },
2049
2646
  "modelMode": "active",
2050
2647
  "hookBus": "host",
2051
2648
  "stateIO": "filesystem",
2052
2649
  "transport": "mcp",
2053
- "runtime": "bun"
2650
+ "runtime": "bun",
2651
+ "effortSurface": "argv"
2652
+ },
2653
+ "orchestratorExec": {
2654
+ "command": "opencode",
2655
+ "args": [
2656
+ "run"
2657
+ ],
2658
+ "cwdFlag": "--dir",
2659
+ "promptFlag": null
2054
2660
  },
2055
2661
  "hostBehaviors": {
2056
2662
  "reapplyCommand": "/gsd-update --reapply",
@@ -2069,12 +2675,53 @@ const capabilities = {
2069
2675
  "skipCodexSkillsManifest": true,
2070
2676
  "reviewerCli": true
2071
2677
  }
2678
+ },
2679
+ "reviewer": {
2680
+ "slug": "opencode",
2681
+ "flags": [
2682
+ "--opencode"
2683
+ ],
2684
+ "transport": "spawn",
2685
+ "probe": {
2686
+ "kind": "command-exists",
2687
+ "binary": "opencode"
2688
+ },
2689
+ "invoke": {
2690
+ "binary": "opencode",
2691
+ "args": [
2692
+ "run",
2693
+ "{{model}}",
2694
+ "{{effort}}",
2695
+ "--format",
2696
+ "json",
2697
+ "-"
2698
+ ],
2699
+ "promptChannel": "stdin",
2700
+ "outputChannel": "stdout",
2701
+ "modelArg": "--model",
2702
+ "effortChannel": "argv"
2703
+ },
2704
+ "timeoutFloorMs": 660000,
2705
+ "emptyOutput": "stub-with-stderr",
2706
+ "reviewsSection": "OpenCode",
2707
+ "evidenceClass": "source-grounded",
2708
+ "requiresBinaries": [],
2709
+ "promptBudgetKey": null,
2710
+ "modelConfigKey": "review.models.opencode",
2711
+ "handler": "opencode"
2712
+ },
2713
+ "config": {
2714
+ "review.models.opencode": {
2715
+ "type": "string",
2716
+ "default": "",
2717
+ "description": "Model passed to the OpenCode reviewer lane."
2718
+ }
2072
2719
  }
2073
2720
  },
2074
2721
  "pattern-mapper": {
2075
2722
  "id": "pattern-mapper",
2076
2723
  "role": "feature",
2077
- "version": "1.8.0",
2724
+ "version": "1.9.0",
2078
2725
  "title": "Pattern mapping",
2079
2726
  "description": "Optional codebase-pattern mapping before planning; owns the pattern mapper agent and workflow.pattern_mapper activation key.",
2080
2727
  "tier": "full",
@@ -2128,7 +2775,7 @@ const capabilities = {
2128
2775
  "pi": {
2129
2776
  "id": "pi",
2130
2777
  "role": "runtime",
2131
- "version": "1.8.0",
2778
+ "version": "1.9.0",
2132
2779
  "title": "pi",
2133
2780
  "description": "pi (pi.dev) — bun-runtime programmatic-CLI; TS ExtensionAPI (registerCommand/registerTool/registerProvider/pi.on); single native-extension file at ~/.pi/agent/extensions/gsd.js (.js, not .cjs — pi's extension auto-discovery accepts only .ts/.js, #2470); no shared-settings hook surface; tier-2 support.",
2134
2781
  "tier": "core",
@@ -2167,13 +2814,15 @@ const capabilities = {
2167
2814
  "maxDepth": 0,
2168
2815
  "background": false,
2169
2816
  "backgroundDispatch": false,
2170
- "subagentToolkit": "undocumented"
2817
+ "subagentToolkit": "undocumented",
2818
+ "isolation": "none"
2171
2819
  },
2172
2820
  "modelMode": "active",
2173
2821
  "hookBus": "host",
2174
2822
  "stateIO": "session-log-append",
2175
2823
  "transport": "native-extension",
2176
- "runtime": "bun"
2824
+ "runtime": "bun",
2825
+ "effortSurface": "undocumented"
2177
2826
  },
2178
2827
  "hostBehaviors": {
2179
2828
  "nativePlugin": {
@@ -2188,7 +2837,7 @@ const capabilities = {
2188
2837
  "profile-pipeline": {
2189
2838
  "id": "profile-pipeline",
2190
2839
  "role": "feature",
2191
- "version": "1.8.0",
2840
+ "version": "1.9.0",
2192
2841
  "title": "Developer profiling pipeline",
2193
2842
  "description": "Developer behavioral profiling from Claude Code session history; scans session JSONL files, extracts and samples user messages, and generates profile artifacts (USER-PROFILE.md, dev-preferences.md, CLAUDE.md sections). Exposes eight `gsd-tools` commands: scan-sessions, extract-messages, profile-sample (pipeline phase) and write-profile, profile-questionnaire, generate-dev-preferences, generate-claude-profile, generate-claude-md (output phase). Backs the /gsd-profile-user skill and gsd-user-profiler agent.",
2194
2843
  "tier": "full",
@@ -2265,7 +2914,7 @@ const capabilities = {
2265
2914
  "qwen": {
2266
2915
  "id": "qwen",
2267
2916
  "role": "runtime",
2268
- "version": "1.8.0",
2917
+ "version": "1.9.0",
2269
2918
  "title": "Qwen Code",
2270
2919
  "description": "Qwen Code (Alibaba) — nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
2271
2920
  "tier": "core",
@@ -2344,13 +2993,15 @@ const capabilities = {
2344
2993
  "maxDepth": 1,
2345
2994
  "background": true,
2346
2995
  "subagentToolkit": "full",
2347
- "backgroundDispatch": false
2996
+ "backgroundDispatch": false,
2997
+ "isolation": "undocumented"
2348
2998
  },
2349
2999
  "modelMode": "passive",
2350
3000
  "hookBus": "host",
2351
3001
  "stateIO": "filesystem",
2352
3002
  "transport": "mcp",
2353
- "runtime": "node"
3003
+ "runtime": "node",
3004
+ "effortSurface": "undocumented"
2354
3005
  },
2355
3006
  "hostBehaviors": {
2356
3007
  "skillPriorityFrontmatter": true,
@@ -2365,12 +3016,41 @@ const capabilities = {
2365
3016
  "hyphenNameAgentBody": true,
2366
3017
  "reviewerCli": true
2367
3018
  }
3019
+ },
3020
+ "reviewer": {
3021
+ "slug": "qwen",
3022
+ "flags": [
3023
+ "--qwen"
3024
+ ],
3025
+ "transport": "spawn",
3026
+ "probe": {
3027
+ "kind": "command-exists",
3028
+ "binary": "qwen"
3029
+ },
3030
+ "invoke": {
3031
+ "binary": "qwen",
3032
+ "args": [
3033
+ "-"
3034
+ ],
3035
+ "promptChannel": "stdin",
3036
+ "outputChannel": "stdout",
3037
+ "modelArg": null,
3038
+ "effortChannel": "none"
3039
+ },
3040
+ "timeoutFloorMs": 900000,
3041
+ "emptyOutput": "stub-with-stderr",
3042
+ "reviewsSection": "Qwen",
3043
+ "evidenceClass": "source-grounded",
3044
+ "requiresBinaries": [],
3045
+ "promptBudgetKey": null,
3046
+ "modelConfigKey": null,
3047
+ "handler": null
2368
3048
  }
2369
3049
  },
2370
3050
  "research": {
2371
3051
  "id": "research",
2372
3052
  "role": "feature",
2373
- "version": "1.8.0",
3053
+ "version": "1.9.0",
2374
3054
  "title": "Phase research",
2375
3055
  "description": "Optional phase research before planning; owns the phase researcher agent and workflow.research activation key.",
2376
3056
  "tier": "standard",
@@ -2422,7 +3102,7 @@ const capabilities = {
2422
3102
  "schema-gate": {
2423
3103
  "id": "schema-gate",
2424
3104
  "role": "feature",
2425
- "version": "1.8.0",
3105
+ "version": "1.9.0",
2426
3106
  "title": "Schema push detection gate",
2427
3107
  "description": "Detects ORM schema-relevant files in the phase scope during planning and injects a mandatory [BLOCKING] schema push task into the plan. Prevents false-positive verification where build/types pass because TypeScript types come from config, not the live database.",
2428
3108
  "tier": "full",
@@ -2468,7 +3148,7 @@ const capabilities = {
2468
3148
  "security": {
2469
3149
  "id": "security",
2470
3150
  "role": "feature",
2471
- "version": "1.8.0",
3151
+ "version": "1.9.0",
2472
3152
  "title": "Security enforcement",
2473
3153
  "description": "Threat mitigation verification and ship-time security blocking for phases with security enforcement enabled.",
2474
3154
  "tier": "full",
@@ -2567,7 +3247,7 @@ const capabilities = {
2567
3247
  "tdd": {
2568
3248
  "id": "tdd",
2569
3249
  "role": "feature",
2570
- "version": "1.8.0",
3250
+ "version": "1.9.0",
2571
3251
  "title": "Test-driven development",
2572
3252
  "description": "Injects TDD heuristics into the planner and enforces RED/GREEN gate compliance on type:tdd plans after execution. Owns workflow.tdd_mode; the --tdd CLI flag is the ephemeral override.",
2573
3253
  "tier": "full",
@@ -2620,7 +3300,7 @@ const capabilities = {
2620
3300
  "trae": {
2621
3301
  "id": "trae",
2622
3302
  "role": "runtime",
2623
- "version": "1.8.0",
3303
+ "version": "1.9.0",
2624
3304
  "title": "Trae IDE",
2625
3305
  "description": "Trae IDE — nested-skill artifact layout; no hook surface (profile-marker-only config); tier-2 support.",
2626
3306
  "tier": "core",
@@ -2693,13 +3373,15 @@ const capabilities = {
2693
3373
  "maxDepth": "undocumented",
2694
3374
  "background": true,
2695
3375
  "subagentToolkit": "undocumented",
2696
- "backgroundDispatch": "undocumented"
3376
+ "backgroundDispatch": "undocumented",
3377
+ "isolation": "undocumented"
2697
3378
  },
2698
3379
  "modelMode": "passive",
2699
3380
  "hookBus": "engine",
2700
3381
  "stateIO": "filesystem",
2701
3382
  "transport": "mcp",
2702
- "runtime": "node"
3383
+ "runtime": "node",
3384
+ "effortSurface": "undocumented"
2703
3385
  },
2704
3386
  "hostBehaviors": {
2705
3387
  "skipSharedHooksInstall": true,
@@ -2710,7 +3392,7 @@ const capabilities = {
2710
3392
  "ui": {
2711
3393
  "id": "ui",
2712
3394
  "role": "feature",
2713
- "version": "1.8.0",
3395
+ "version": "1.9.0",
2714
3396
  "title": "UI design contracts",
2715
3397
  "description": "UI-SPEC design contract + retrospective UI audit for frontend phases.",
2716
3398
  "tier": "full",
@@ -2805,7 +3487,7 @@ const capabilities = {
2805
3487
  "vscode": {
2806
3488
  "id": "vscode",
2807
3489
  "role": "runtime",
2808
- "version": "1.8.0",
3490
+ "version": "1.9.0",
2809
3491
  "title": "VS Code",
2810
3492
  "description": "VS Code — Marketplace/VSIX extension; no file-projected config directory; IDE-profile reference host (active vscode.lm model, engine-owned hook bus, sandboxed globalState/workspaceState stateIO).",
2811
3493
  "tier": "core",
@@ -2843,20 +3525,22 @@ const capabilities = {
2843
3525
  "maxDepth": 5,
2844
3526
  "background": true,
2845
3527
  "subagentToolkit": "undocumented",
2846
- "backgroundDispatch": "undocumented"
3528
+ "backgroundDispatch": "undocumented",
3529
+ "isolation": "undocumented"
2847
3530
  },
2848
3531
  "modelMode": "active",
2849
3532
  "hookBus": "engine",
2850
3533
  "stateIO": "sandboxed-storage",
2851
3534
  "transport": "mcp",
2852
- "runtime": "sandboxed-web"
3535
+ "runtime": "sandboxed-web",
3536
+ "effortSurface": "undocumented"
2853
3537
  }
2854
3538
  }
2855
3539
  },
2856
3540
  "windsurf": {
2857
3541
  "id": "windsurf",
2858
3542
  "role": "runtime",
2859
- "version": "1.8.0",
3543
+ "version": "1.9.0",
2860
3544
  "title": "Windsurf",
2861
3545
  "description": "Windsurf (Codeium) — workspace workflow artifact layout for slash commands; Cascade native hooks.json blocking hook bus (pre_write_code, pre_run_command); tier-2 support.",
2862
3546
  "tier": "core",
@@ -2922,13 +3606,15 @@ const capabilities = {
2922
3606
  "maxDepth": "undocumented",
2923
3607
  "background": "undocumented",
2924
3608
  "subagentToolkit": "undocumented",
2925
- "backgroundDispatch": "undocumented"
3609
+ "backgroundDispatch": "undocumented",
3610
+ "isolation": "none"
2926
3611
  },
2927
3612
  "modelMode": "passive",
2928
3613
  "hookBus": "host",
2929
3614
  "stateIO": "filesystem",
2930
3615
  "transport": "mcp",
2931
- "runtime": "undocumented"
3616
+ "runtime": "undocumented",
3617
+ "effortSurface": "undocumented"
2932
3618
  },
2933
3619
  "hostBehaviors": {
2934
3620
  "skipSharedHooksInstall": true,
@@ -2941,7 +3627,7 @@ const capabilities = {
2941
3627
  "zcode": {
2942
3628
  "id": "zcode",
2943
3629
  "role": "runtime",
2944
- "version": "1.8.0",
3630
+ "version": "1.9.0",
2945
3631
  "title": "ZCode",
2946
3632
  "description": "ZCode (Z.ai) — desktop Agentic Development Environment for GLM-5.2; Claude-shaped nested skills at ~/.zcode/skills/<name>/SKILL.md, slash commands, named subagents, native MCP; declarative plugin surface; profile-marker install; tier-2 community support.",
2947
3633
  "tier": "core",
@@ -3030,13 +3716,15 @@ const capabilities = {
3030
3716
  "maxDepth": "undocumented",
3031
3717
  "background": false,
3032
3718
  "subagentToolkit": "full",
3033
- "backgroundDispatch": false
3719
+ "backgroundDispatch": false,
3720
+ "isolation": "none"
3034
3721
  },
3035
3722
  "modelMode": "passive",
3036
3723
  "hookBus": "host",
3037
3724
  "stateIO": "filesystem",
3038
3725
  "transport": "mcp",
3039
- "runtime": "electron"
3726
+ "runtime": "electron",
3727
+ "effortSurface": "undocumented"
3040
3728
  },
3041
3729
  "hostBehaviors": {
3042
3730
  "skipSharedHooksInstall": true
@@ -3387,7 +4075,7 @@ const byLoopPoint = {
3387
4075
  "into": "executor",
3388
4076
  "fragment": {
3389
4077
  "path": "fragments/execute-wave-pre.md",
3390
- "inline": "# Claude orchestration — Workflow execution backend (BETA)\n\n> Injected at `execute:wave:pre` `into: executor` only when\n> `claude_orchestration.enabled` is true. Default-off; `onError: skip`.\n\n## When this contribution is active\n\nThe Claude orchestration capability is **default-off and BETA**. It activates only\nwhen ALL of the following hold:\n\n1. `claude_orchestration.enabled` is `true` in `.planning/config.json`, AND\n2. the active runtime is **Claude Code** (the Workflow tool is Claude / Agent\n SDK-specific), AND\n3. `claude_orchestration.execution_backend` resolves to `workflow` — either\n explicitly, or via `auto` — **and** the Agent SDK version is\n `>= claude_orchestration.min_agent_sdk_version` (default `0.3.149`). The SDK\n floor applies in both `auto` and `workflow` modes (fail-closed: a pre-release\n or older SDK never activates the preview backend).\n\nDetection is fail-closed: any miss degrades to **inline, manual, one-agent-per-\nmessage dispatch** — exactly today's behaviour. On a non-Claude runtime this\ncontribution is a no-op.\n\n## Why `execute:wave:pre` (not `execute:wave:post`)\n\nThis is a **dispatch-backend selector** — it decides HOW a wave's executor agents\nare spawned. That decision has to be made BEFORE the wave's `Agent()` calls in\n`execute-phase.md` step 3, not after the wave has already finished (#2285). The\ncapability previously registered at `execute:wave:post`, which fires only after\nworktree merge/post-merge tests/tracking updates — by then the wave was already\ndispatched inline, so the contribution was structurally unable to change how\ndispatch happened. This fragment is injected at the point that actually precedes\ndispatch.\n\n## What the orchestrator does when the Workflow backend is active\n\nBefore spawning executor agents for the current wave (execute-phase.md step 3),\nresolve the dispatch backend through the single composed CLI seam:\n\n```bash\ngsd-tools claude-orchestration resolve-wave-dispatch \\\n --waves \"$WAVE_MANIFEST_PATH\" --run-id \"$PHASE_RUN_ID\" \\\n --runtime \"$RUNTIME\" \\\n ${AGENT_SDK_VERSION:+--agent-sdk-version \"$AGENT_SDK_VERSION\"} \\\n --phase-dir \"$PHASE_DIR\" --raw\n```\n\nThis composes `detectWorkflowBackend` (the gate ladder above) with\n`emitWorkflowScript` (the wave→plan mapping below) in ONE call — the pure\nfunction backing it is `resolveWaveDispatch` in\n`gsd-core/bin/lib/claude-orchestration.cjs`. Response shape:\n`{ backend: 'inline'|'workflow', reason, script?, summary? }`.\n\n### Manifest construction (`$WAVE_MANIFEST_PATH`, `$PHASE_RUN_ID`, `$PHASE_DIR`, `$AGENT_SDK_VERSION`)\n\nThese are NOT pre-existing execute-phase.md variables — the orchestrator builds\nthem at this step, from data it already has in-context from `discover_and_group_plans`\n(the `PLAN_INDEX` JSON) and step 2.5 (the per-plan `USE_WORKTREES_FOR_PLAN` decision):\n\n1. **`$PHASE_DIR`** — reuse `{phase_dir}` from the `INIT` bundle (already loaded\n in the `initialize` step). No new value needed.\n\n2. **`$PHASE_RUN_ID`** — a stable identifier for THIS phase-execution attempt, so\n `resumeFromRunId` can resume an interrupted run without re-dispatching plans\n the Workflow tool already completed. Construct it deterministically —\n `execute-{phase_number}-{phase_slug}` — from `INIT`'s `phase_number`/`phase_slug`\n (both are already validated identifiers used elsewhere in this workflow, so\n they satisfy `emitWorkflowScript`'s `isScriptableIdentifier` check). Do NOT\n mint a new random id per wave — the SAME `$PHASE_RUN_ID` is reused for every\n wave in the phase so the Workflow tool can correctly track cross-wave resume\n state.\n\n3. **`$WAVE_MANIFEST_PATH`** — a fresh temp file for THIS wave's manifest (one\n wave = one `waves` array with a single entry, matching the wave-by-wave\n dispatch loop; do not batch multiple waves into one manifest — waves are\n dispatched in wave order, not all at once):\n\n ```bash\n WAVE_MANIFEST_PATH=$(mktemp \"${TMPDIR:-/tmp}/gsd-wave-dispatch-XXXXXX\") && mv \"$WAVE_MANIFEST_PATH\" \"$WAVE_MANIFEST_PATH.json\" && WAVE_MANIFEST_PATH=\"$WAVE_MANIFEST_PATH.json\"\n ```\n\n Then **use the Write tool** (not a bash/jq pipeline — the orchestrator already\n has every field parsed in-context) to write the manifest JSON to\n `$WAVE_MANIFEST_PATH`:\n\n ```json\n {\n \"waves\": [\n {\n \"id\": \"wave-{N}\",\n \"plans\": [\n {\n \"id\": \"{plan_id}\",\n \"brief\": \"{the SAME <objective>...<success_criteria> prompt block step 3 builds for this plan's inline Agent() call}\",\n \"files_modified\": [\"{from PLAN_INDEX.plans[].files_modified for this plan}\"],\n \"use_worktree\": {true unless step 2.5 set USE_WORKTREES_FOR_PLAN=false for this plan}\n }\n ]\n }\n ]\n }\n ```\n\n - **`id`** — the plan id from `PLAN_INDEX`, e.g. `\"01-01\"`.\n - **`brief`** — MUST carry the same task content as step 3's inline `Agent()`\n prompt (the `<objective>`/`<execution_context>`/`<files_to_read>`/\n `<success_criteria>` block, with `{plan_number}`/`{phase_number}`/\n `{phase_name}` substituted) — a short summary here would NOT reproduce\n step 3's behavior and would violate the \"identical artifacts\" contract.\n - **`files_modified`** — copy verbatim from the plan's `PLAN_INDEX` entry.\n - **`use_worktree`** — `true` for every plan UNLESS step 2.5's per-plan\n worktree gate (`execute-phase/steps/per-plan-worktree-gate.md`) set\n `USE_WORKTREES_FOR_PLAN=false` for that plan (submodule-touching plan, or\n project-level `USE_WORKTREES=false`) — in which case pass `false` here so\n `emitWorkflowScript` omits `isolation: \"worktree\"` for that plan (#2772 /\n #2285 finding 1). **Never** hardcode `true` — that would force worktree\n isolation on a plan the inline path explicitly keeps out of worktrees.\n\n4. **`$AGENT_SDK_VERSION`** — see below; OMIT when unknown (fails closed).\n\n**Agent SDK version:** the orchestrator has no scriptable (bash-computable) way\nto introspect the live Agent SDK version. When it can determine the version\n(e.g. from a host-exposed value it can read directly), pass\n`--agent-sdk-version`. When it cannot, OMIT the flag — `resolveWaveDispatch`'s\ngate 5 (`agent_sdk_version_unknown`) then fails closed to `inline` by design;\nthis is not a bug, it is the same fail-closed posture documented above applied\nto a real absence of information.\n\n**If `backend == \"workflow\"`:** run the emitted `script` via the Workflow tool\nfor THIS wave instead of the per-message `Agent()` loop in step 3. The script\ncomposes the SAME `gsd-executor` agent type the inline path uses, with\nworktree isolation applied PER PLAN from the manifest's `use_worktree` field\n(see `emitWorkflowScript`):\n\n- **waves → one or more sequential `parallel()` barriers** — each wave is a\n barrier group; when plans within a wave share `files_modified`, they are split\n into separate sequential stages within that wave's barrier.\n- **plans → `agent(brief, { agentType: 'gsd-executor', isolation: 'worktree' })`**\n when `use_worktree` is not `false`, or `agent(brief, { agentType: 'gsd-executor' })`\n (no isolation) when it is — so the produced `SUMMARY.md` and commits are\n identical to inline dispatch, INCLUDING the inline path's submodule safety\n gate (#2772 / #2285 finding 1).\n- **`files_modified` overlap → separate sequential stages** — the same overlap\n rule execute-phase already applies inline (step 1 of the wave loop).\n- **`resumeFromRunId`** — wired to the phase run id, so an interrupted phase\n resumes without re-running completed plans.\n\nThe orchestrator still runs steps 4–5.8 (wait for completion, worktree cleanup,\npost-merge gate, tracking update) exactly as it does for inline dispatch — the\nWorkflow backend only replaces HOW agents are spawned for this wave, not what\nhappens after they return.\n\n**If `backend == \"inline\"`** (any gate miss, or `resolve-wave-dispatch` itself\nunavailable/erroring): proceed to step 3's standard per-message `Agent()`\ndispatch — the default, byte-identical-to-today path. `onError: skip` on this\ncontribution means a `resolve-wave-dispatch` command failure is treated exactly\nlike an `inline` result, never as a fatal wave error.\n\n## Fallback contract\n\nDetection is fail-closed end-to-end: capability disabled, non-Claude runtime,\n`execution_backend:\"inline\"`, missing/incapable host descriptor, unknown or\nbelow-floor Agent SDK version, or an `emitWorkflowScript` failure on a malformed\nwave manifest — ANY of these degrades to `backend:\"inline\"` and execute-phase's\nstandard inline dispatch (step 3) runs unmodified. The Workflow backend never\npartially activates; the executor MUST NOT assume parallelism, a shared budget,\nor resume-from-run-id semantics when `backend == \"inline\"`.\n"
4078
+ "inline": "# Claude orchestration — Workflow execution backend (BETA)\n\n> Injected at `execute:wave:pre` `into: executor` only when\n> `claude_orchestration.enabled` is true. Default-off; `onError: skip`.\n\n## When this contribution is active\n\nThe Claude orchestration capability is **default-off and BETA**. It activates only\nwhen ALL of the following hold:\n\n1. `claude_orchestration.enabled` is `true` in `.planning/config.json`, AND\n2. the active runtime is **Claude Code** (the Workflow tool is Claude / Agent\n SDK-specific), AND\n3. `claude_orchestration.execution_backend` resolves to `workflow` — either\n explicitly, or via `auto` — **and** the Agent SDK version is\n `>= claude_orchestration.min_agent_sdk_version` (default `0.3.149`). The SDK\n floor applies in both `auto` and `workflow` modes (fail-closed: a pre-release\n or older SDK never activates the preview backend).\n\nDetection is fail-closed: any miss degrades to **inline, manual, one-agent-per-\nmessage dispatch** — exactly today's behaviour. On a non-Claude runtime this\ncontribution is a no-op.\n\n## Why `execute:wave:pre` (not `execute:wave:post`)\n\nThis is a **dispatch-backend selector** — it decides HOW a wave's executor agents\nare spawned. That decision has to be made BEFORE the wave's `Agent()` calls in\n`execute-phase.md` step 3, not after the wave has already finished (#2285). The\ncapability previously registered at `execute:wave:post`, which fires only after\nworktree merge/post-merge tests/tracking updates — by then the wave was already\ndispatched inline, so the contribution was structurally unable to change how\ndispatch happened. This fragment is injected at the point that actually precedes\ndispatch.\n\n## What the orchestrator does when the Workflow backend is active\n\nBefore spawning executor agents for the current wave (execute-phase.md step 3),\nresolve the dispatch backend through the single composed CLI seam:\n\n```bash\ngsd-tools claude-orchestration resolve-wave-dispatch \\\n --waves \"$WAVE_MANIFEST_PATH\" --run-id \"$PHASE_RUN_ID\" \\\n --runtime \"$RUNTIME\" \\\n --phase-dir \"$PHASE_DIR\" --raw\n```\n\n`--agent-sdk-version` is no longer passed here (#2590). The router resolves the\ninstalled Agent SDK version itself; see **Agent SDK version** below. The former\n`${AGENT_SDK_VERSION:+--agent-sdk-version \"$AGENT_SDK_VERSION\"}` line was also\n**shell-dependent**: zsh does not word-split unquoted parameter expansions, so it\ncollapsed to a SINGLE argv element there, `argValue()` never matched, and the run\nfailed into `agent_sdk_version_unknown` — indistinguishable from genuinely\nunknown. Pass `--agent-sdk-version <ver>` explicitly only to pin a version.\n\nThis composes `detectWorkflowBackend` (the gate ladder above) with\n`emitWorkflowScript` (the wave→plan mapping below) in ONE call — the pure\nfunction backing it is `resolveWaveDispatch` in\n`gsd-core/bin/lib/claude-orchestration.cjs`. Response shape:\n`{ backend: 'inline'|'workflow', reason, script?, summary? }`.\n\n### Manifest construction (`$WAVE_MANIFEST_PATH`, `$PHASE_RUN_ID`, `$PHASE_DIR`)\n\nThese are NOT pre-existing execute-phase.md variables — the orchestrator builds\nthem at this step, from data it already has in-context from `discover_and_group_plans`\n(the `PLAN_INDEX` JSON) and step 2.5 (the per-plan `USE_WORKTREES_FOR_PLAN` decision):\n\n1. **`$PHASE_DIR`** — reuse `{phase_dir}` from the `INIT` bundle (already loaded\n in the `initialize` step). No new value needed.\n\n2. **`$PHASE_RUN_ID`** — a stable identifier for THIS phase-execution attempt, so\n `resumeFromRunId` can resume an interrupted run without re-dispatching plans\n the Workflow tool already completed. Construct it deterministically —\n `execute-{phase_number}-{phase_slug}` — from `INIT`'s `phase_number`/`phase_slug`\n (both are already validated identifiers used elsewhere in this workflow, so\n they satisfy `emitWorkflowScript`'s `isScriptableIdentifier` check). Do NOT\n mint a new random id per wave — the SAME `$PHASE_RUN_ID` is reused for every\n wave in the phase so the Workflow tool can correctly track cross-wave resume\n state.\n\n3. **`$WAVE_MANIFEST_PATH`** — a fresh temp file for THIS wave's manifest (one\n wave = one `waves` array with a single entry, matching the wave-by-wave\n dispatch loop; do not batch multiple waves into one manifest — waves are\n dispatched in wave order, not all at once):\n\n ```bash\n WAVE_MANIFEST_PATH=$(mktemp \"${TMPDIR:-/tmp}/gsd-wave-dispatch-XXXXXX\") && mv \"$WAVE_MANIFEST_PATH\" \"$WAVE_MANIFEST_PATH.json\" && WAVE_MANIFEST_PATH=\"$WAVE_MANIFEST_PATH.json\"\n ```\n\n Then **use the Write tool** (not a bash/jq pipeline — the orchestrator already\n has every field parsed in-context) to write the manifest JSON to\n `$WAVE_MANIFEST_PATH`:\n\n ```json\n {\n \"waves\": [\n {\n \"id\": \"wave-{N}\",\n \"plans\": [\n {\n \"id\": \"{plan_id}\",\n \"brief\": \"{the SAME <objective>...<success_criteria> prompt block step 3 builds for this plan's inline Agent() call}\",\n \"files_modified\": [\"{from PLAN_INDEX.plans[].files_modified for this plan}\"],\n \"use_worktree\": {true unless step 2.5 set USE_WORKTREES_FOR_PLAN=false for this plan}\n }\n ]\n }\n ]\n }\n ```\n\n - **`id`** — the plan id from `PLAN_INDEX`, e.g. `\"01-01\"`.\n - **`brief`** — MUST carry the same task content as step 3's inline `Agent()`\n prompt (the `<objective>`/`<execution_context>`/`<files_to_read>`/\n `<success_criteria>` block, with `{plan_number}`/`{phase_number}`/\n `{phase_name}` substituted) — a short summary here would NOT reproduce\n step 3's behavior and would violate the \"identical artifacts\" contract.\n - **`files_modified`** — copy verbatim from the plan's `PLAN_INDEX` entry.\n - **`use_worktree`** — `true` for every plan UNLESS step 2.5's per-plan\n worktree gate (`execute-phase/steps/per-plan-worktree-gate.md`) set\n `USE_WORKTREES_FOR_PLAN=false` for that plan (submodule-touching plan, or\n project-level `USE_WORKTREES=false`) — in which case pass `false` here so\n `emitWorkflowScript` omits `isolation: \"worktree\"` for that plan (#2772 /\n #2285 finding 1). **Never** hardcode `true` — that would force worktree\n isolation on a plan the inline path explicitly keeps out of worktrees.\n\n4. **`$AGENT_SDK_VERSION`** — no longer built here; the router resolves it.\n\n**Agent SDK version:** the orchestrator has no *bash-computable* way to\nintrospect the live Agent SDK version — but the router runs in Node, so it\nresolves the version itself (#2590), in this order:\n\n1. an explicit `--agent-sdk-version <ver>` (pin a version),\n2. `GSD_AGENT_SDK_VERSION`,\n3. the **installed** `@anthropic-ai/claude-agent-sdk` package version, read from\n its `package.json` on disk by walking `node_modules` up the tree. (Read\n directly rather than via `require.resolve`: the SDK's `exports` map does not\n expose `./package.json`, so `require.resolve` throws\n `ERR_PACKAGE_PATH_NOT_EXPORTED`.)\n\nPreviously nothing computed this at all, so gate 5 returned\n`agent_sdk_version_unknown` on **every** automated run and the Workflow backend\ncould never activate — while `gsd-tools capability state` still reported the\ncapability `active: true`. Fail-closed is preserved: when no version can be\nresolved, gate 5 still declines to `inline`. What changed is that a resolvable\nversion is now actually found, so a genuinely-too-old SDK reports\n`agent_sdk_version_below_floor` — the truthful reason — instead of `unknown`.\n\n**If `backend == \"workflow\"`:** run the emitted `script` via the Workflow tool\nfor THIS wave instead of the per-message `Agent()` loop in step 3. The script\ncomposes the SAME `gsd-executor` agent type the inline path uses, with\nworktree isolation applied PER PLAN from the manifest's `use_worktree` field\n(see `emitWorkflowScript`):\n\n- **waves → one or more sequential `parallel()` barriers** — each wave is a\n barrier group; when plans within a wave share `files_modified`, they are split\n into separate sequential stages within that wave's barrier.\n- **plans → `agent(brief, { agentType: 'gsd-executor', isolation: 'worktree' })`**\n when `use_worktree` is not `false`, or `agent(brief, { agentType: 'gsd-executor' })`\n (no isolation) when it is — so the produced `SUMMARY.md` and commits are\n identical to inline dispatch, INCLUDING the inline path's submodule safety\n gate (#2772 / #2285 finding 1).\n- **`files_modified` overlap → separate sequential stages** — the same overlap\n rule execute-phase already applies inline (step 1 of the wave loop).\n- **`resumeFromRunId`** — **pass `summary.resumeRunId` as the Workflow tool's\n `resumeFromRunId` INPUT when you invoke the tool.** It is a tool parameter,\n not a script function; the script deliberately does not call it (#2590 — doing\n so threw \"resumeFromRunId is not defined\" and rejected the entire script).\n Omitting it from the tool invocation silently regresses phase-resume to a\n no-op: an interrupted phase re-runs completed plans.\n\nThe orchestrator still runs steps 4–5.8 (wait for completion, worktree cleanup,\npost-merge gate, tracking update) exactly as it does for inline dispatch — the\nWorkflow backend only replaces HOW agents are spawned for this wave, not what\nhappens after they return.\n\n**If `backend == \"inline\"`** (any gate miss, or `resolve-wave-dispatch` itself\nunavailable/erroring): proceed to step 3's standard per-message `Agent()`\ndispatch — the default, byte-identical-to-today path. `onError: skip` on this\ncontribution means a `resolve-wave-dispatch` command failure is treated exactly\nlike an `inline` result, never as a fatal wave error.\n\n## Fallback contract\n\nDetection is fail-closed end-to-end: capability disabled, non-Claude runtime,\n`execution_backend:\"inline\"`, missing/incapable host descriptor, unknown or\nbelow-floor Agent SDK version, or an `emitWorkflowScript` failure on a malformed\nwave manifest — ANY of these degrades to `backend:\"inline\"` and execute-phase's\nstandard inline dispatch (step 3) runs unmodified. The Workflow backend never\npartially activates; the executor MUST NOT assume parallelism, a shared budget,\nor resume-from-run-id semantics when `backend == \"inline\"`.\n"
3391
4079
  },
3392
4080
  "produces": [],
3393
4081
  "consumes": [
@@ -3638,13 +4326,16 @@ const byLoopPoint = {
3638
4326
  const configKeys = {
3639
4327
  "workflow.ai_integration_phase": "ai-integration",
3640
4328
  "workflow.api_coverage_gate": "ai-integration",
4329
+ "review.models.agy": "antigravity",
3641
4330
  "workflow.assumption_delta": "assumption-delta",
3642
4331
  "workflow.windows_enforce": "broken-windows",
4332
+ "review.models.claude": "claude",
3643
4333
  "claude_orchestration.enabled": "claude-orchestration",
3644
4334
  "claude_orchestration.execution_backend": "claude-orchestration",
3645
4335
  "claude_orchestration.min_agent_sdk_version": "claude-orchestration",
3646
4336
  "workflow.code_review": "code-review",
3647
4337
  "workflow.code_review_depth": "code-review",
4338
+ "review.models.codex": "codex",
3648
4339
  "workflow.drift_threshold": "drift",
3649
4340
  "workflow.drift_action": "drift",
3650
4341
  "workflow.schema_drift_gate": "drift",
@@ -3655,8 +4346,16 @@ const configKeys = {
3655
4346
  "external_job.submit_timeout_ms": "external-job",
3656
4347
  "external_job.poll_timeout_ms": "external-job",
3657
4348
  "workflow.post_planning_gaps": "gap-analysis",
4349
+ "review.models.gemini": "gemini",
3658
4350
  "graphify.enabled": "graphify",
3659
4351
  "intel.enabled": "intel",
4352
+ "review.models.kimi-code": "kimi-code",
4353
+ "review.models.llama_cpp": "llama-cpp",
4354
+ "review.llama_cpp_host": "llama-cpp",
4355
+ "review.max_prompt_tokens_per_reviewer.llama_cpp": "llama-cpp",
4356
+ "review.models.lm_studio": "lm-studio",
4357
+ "review.lm_studio_host": "lm-studio",
4358
+ "review.max_prompt_tokens_per_reviewer.lm_studio": "lm-studio",
3660
4359
  "mempalace.enabled": "mempalace",
3661
4360
  "mempalace.memory_mode": "mempalace",
3662
4361
  "mempalace.wing": "mempalace",
@@ -3668,6 +4367,10 @@ const configKeys = {
3668
4367
  "mempalace.diary_journal": "mempalace",
3669
4368
  "mempalace.auto_capture_hooks": "mempalace",
3670
4369
  "workflow.nyquist_validation": "nyquist",
4370
+ "review.models.ollama": "ollama",
4371
+ "review.ollama_host": "ollama",
4372
+ "review.max_prompt_tokens_per_reviewer.ollama": "ollama",
4373
+ "review.models.opencode": "opencode",
3671
4374
  "workflow.pattern_mapper": "pattern-mapper",
3672
4375
  "profile-pipeline.enabled": "profile-pipeline",
3673
4376
  "workflow.research": "research",
@@ -3694,6 +4397,12 @@ const configSchema = {
3694
4397
  "default": true,
3695
4398
  "description": "Require an explicit API-coverage decision (full-by-default, opt-out-not-opt-in) before a phase that integrates an external API/SDK/service can seal. At plan:pre the planner is prompted to enumerate the API surface into COVERAGE.md; at verify:pre a blocking gate fails the seal unless the matrix exists with every non-integrated capability an explicit, reasoned opt-out. Independent of ai_integration_phase (applies to any external-API integration, not only AI)."
3696
4399
  },
4400
+ "review.models.agy": {
4401
+ "owner": "antigravity",
4402
+ "type": "string",
4403
+ "default": "",
4404
+ "description": "Model passed to the Antigravity reviewer lane. The key suffix is the lane binary/flag alias `agy`, not the slug `antigravity` — preserved verbatim so existing .planning/config.json files keep working."
4405
+ },
3697
4406
  "workflow.assumption_delta": {
3698
4407
  "owner": "assumption-delta",
3699
4408
  "type": "boolean",
@@ -3706,6 +4415,12 @@ const configSchema = {
3706
4415
  "default": false,
3707
4416
  "description": "Enable the blocking ship:pre gate for the broken-windows ledger. When true (opt-in), /gsd-ship blocks while .planning/WINDOWS.md has any open entry. When false (default), windows are still tracked (the executor and verifier still populate WINDOWS.md via gsd-tools windows append) but ship does not block — teams can adopt tracking before enforcement. Issue #1950."
3708
4417
  },
4418
+ "review.models.claude": {
4419
+ "owner": "claude",
4420
+ "type": "string",
4421
+ "default": "",
4422
+ "description": "Model passed to the Claude reviewer lane."
4423
+ },
3709
4424
  "claude_orchestration.enabled": {
3710
4425
  "owner": "claude-orchestration",
3711
4426
  "type": "boolean",
@@ -3746,6 +4461,12 @@ const configSchema = {
3746
4461
  "deep"
3747
4462
  ]
3748
4463
  },
4464
+ "review.models.codex": {
4465
+ "owner": "codex",
4466
+ "type": "string",
4467
+ "default": "",
4468
+ "description": "Model passed to the Codex reviewer lane."
4469
+ },
3749
4470
  "workflow.drift_threshold": {
3750
4471
  "owner": "drift",
3751
4472
  "type": "number",
@@ -3813,6 +4534,12 @@ const configSchema = {
3813
4534
  "default": true,
3814
4535
  "description": "Run the post-planning gap analysis report after plans are generated."
3815
4536
  },
4537
+ "review.models.gemini": {
4538
+ "owner": "gemini",
4539
+ "type": "string",
4540
+ "default": "",
4541
+ "description": "Model passed to the Gemini reviewer lane."
4542
+ },
3816
4543
  "graphify.enabled": {
3817
4544
  "owner": "graphify",
3818
4545
  "type": "boolean",
@@ -3825,6 +4552,48 @@ const configSchema = {
3825
4552
  "default": false,
3826
4553
  "description": "Enable the intel code-intelligence command."
3827
4554
  },
4555
+ "review.models.kimi-code": {
4556
+ "owner": "kimi-code",
4557
+ "type": "string",
4558
+ "default": "",
4559
+ "description": "Model passed to the Kimi Code reviewer lane."
4560
+ },
4561
+ "review.models.llama_cpp": {
4562
+ "owner": "llama-cpp",
4563
+ "type": "string",
4564
+ "default": "",
4565
+ "description": "Model requested from the llama.cpp reviewer lane; empty discovers the first model from /v1/models."
4566
+ },
4567
+ "review.llama_cpp_host": {
4568
+ "owner": "llama-cpp",
4569
+ "type": "string",
4570
+ "default": "",
4571
+ "description": "Base URL of the llama.cpp OpenAI-compatible server."
4572
+ },
4573
+ "review.max_prompt_tokens_per_reviewer.llama_cpp": {
4574
+ "owner": "llama-cpp",
4575
+ "type": "number",
4576
+ "default": -1,
4577
+ "description": "Prompt-token budget for the llama.cpp reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
4578
+ },
4579
+ "review.models.lm_studio": {
4580
+ "owner": "lm-studio",
4581
+ "type": "string",
4582
+ "default": "",
4583
+ "description": "Model requested from the LM Studio reviewer lane; empty discovers the first model from /v1/models."
4584
+ },
4585
+ "review.lm_studio_host": {
4586
+ "owner": "lm-studio",
4587
+ "type": "string",
4588
+ "default": "",
4589
+ "description": "Base URL of the LM Studio OpenAI-compatible server."
4590
+ },
4591
+ "review.max_prompt_tokens_per_reviewer.lm_studio": {
4592
+ "owner": "lm-studio",
4593
+ "type": "number",
4594
+ "default": -1,
4595
+ "description": "Prompt-token budget for the LM Studio reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
4596
+ },
3828
4597
  "mempalace.enabled": {
3829
4598
  "owner": "mempalace",
3830
4599
  "type": "boolean",
@@ -3896,6 +4665,30 @@ const configSchema = {
3896
4665
  "default": true,
3897
4666
  "description": "Enable Nyquist validation coverage auditing."
3898
4667
  },
4668
+ "review.models.ollama": {
4669
+ "owner": "ollama",
4670
+ "type": "string",
4671
+ "default": "",
4672
+ "description": "Model requested from the Ollama reviewer lane; empty discovers the first model from /v1/models."
4673
+ },
4674
+ "review.ollama_host": {
4675
+ "owner": "ollama",
4676
+ "type": "string",
4677
+ "default": "",
4678
+ "description": "Base URL of the Ollama OpenAI-compatible server."
4679
+ },
4680
+ "review.max_prompt_tokens_per_reviewer.ollama": {
4681
+ "owner": "ollama",
4682
+ "type": "number",
4683
+ "default": -1,
4684
+ "description": "Prompt-token budget for the Ollama reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"."
4685
+ },
4686
+ "review.models.opencode": {
4687
+ "owner": "opencode",
4688
+ "type": "string",
4689
+ "default": "",
4690
+ "description": "Model passed to the OpenCode reviewer lane."
4691
+ },
3899
4692
  "workflow.pattern_mapper": {
3900
4693
  "owner": "pattern-mapper",
3901
4694
  "type": "boolean",
@@ -3975,7 +4768,7 @@ const runtimes = {
3975
4768
  "antigravity": {
3976
4769
  "id": "antigravity",
3977
4770
  "role": "runtime",
3978
- "version": "1.8.0",
4771
+ "version": "1.9.0",
3979
4772
  "title": "Antigravity",
3980
4773
  "description": "Google Antigravity IDE — nested under ~/.gemini/antigravity; probed across 1.x and 2.x layouts; Gemini hook event dialect; flat skill layout; tier-1 support.",
3981
4774
  "tier": "core",
@@ -4056,13 +4849,15 @@ const runtimes = {
4056
4849
  "maxDepth": "undocumented",
4057
4850
  "background": true,
4058
4851
  "subagentToolkit": "full",
4059
- "backgroundDispatch": "undocumented"
4852
+ "backgroundDispatch": "undocumented",
4853
+ "isolation": "undocumented"
4060
4854
  },
4061
4855
  "modelMode": "passive",
4062
4856
  "hookBus": "host",
4063
4857
  "stateIO": "filesystem",
4064
4858
  "transport": "mcp",
4065
- "runtime": "go"
4859
+ "runtime": "go",
4860
+ "effortSurface": "undocumented"
4066
4861
  },
4067
4862
  "hostBehaviors": {
4068
4863
  "reviewerCli": true,
@@ -4071,12 +4866,53 @@ const runtimes = {
4071
4866
  "hookPathStyle": "raw",
4072
4867
  "globalDirResolver": "antigravity"
4073
4868
  }
4869
+ },
4870
+ "reviewer": {
4871
+ "slug": "antigravity",
4872
+ "flags": [
4873
+ "--antigravity",
4874
+ "--agy"
4875
+ ],
4876
+ "transport": "spawn",
4877
+ "probe": {
4878
+ "kind": "command-exists",
4879
+ "binary": "agy"
4880
+ },
4881
+ "invoke": {
4882
+ "binary": "agy",
4883
+ "args": [
4884
+ "--print-timeout",
4885
+ "540s",
4886
+ "{{model}}",
4887
+ "-p",
4888
+ "{{prompt}}"
4889
+ ],
4890
+ "promptChannel": "argv-file-ref",
4891
+ "outputChannel": "stdout",
4892
+ "modelArg": "--model",
4893
+ "effortChannel": "none"
4894
+ },
4895
+ "timeoutFloorMs": 600000,
4896
+ "emptyOutput": "handler-owned",
4897
+ "reviewsSection": "Antigravity",
4898
+ "evidenceClass": "source-grounded",
4899
+ "requiresBinaries": [],
4900
+ "promptBudgetKey": null,
4901
+ "modelConfigKey": "review.models.agy",
4902
+ "handler": "antigravity"
4903
+ },
4904
+ "config": {
4905
+ "review.models.agy": {
4906
+ "type": "string",
4907
+ "default": "",
4908
+ "description": "Model passed to the Antigravity reviewer lane. The key suffix is the lane binary/flag alias `agy`, not the slug `antigravity` — preserved verbatim so existing .planning/config.json files keep working."
4909
+ }
4074
4910
  }
4075
4911
  },
4076
4912
  "augment": {
4077
4913
  "id": "augment",
4078
4914
  "role": "runtime",
4079
- "version": "1.8.0",
4915
+ "version": "1.9.0",
4080
4916
  "title": "Augment Code",
4081
4917
  "description": "Augment Code CLI — commands + nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
4082
4918
  "tier": "core",
@@ -4170,20 +5006,22 @@ const runtimes = {
4170
5006
  "maxDepth": "undocumented",
4171
5007
  "background": true,
4172
5008
  "subagentToolkit": "full",
4173
- "backgroundDispatch": "undocumented"
5009
+ "backgroundDispatch": "undocumented",
5010
+ "isolation": "undocumented"
4174
5011
  },
4175
5012
  "modelMode": "passive",
4176
5013
  "hookBus": "host",
4177
5014
  "stateIO": "filesystem",
4178
5015
  "transport": "mcp",
4179
- "runtime": "node"
5016
+ "runtime": "node",
5017
+ "effortSurface": "undocumented"
4180
5018
  }
4181
5019
  }
4182
5020
  },
4183
5021
  "claude": {
4184
5022
  "id": "claude",
4185
5023
  "role": "runtime",
4186
- "version": "1.8.0",
5024
+ "version": "1.9.0",
4187
5025
  "title": "Claude Code",
4188
5026
  "description": "Anthropic Claude Code — primary development runtime; tier-1 support with full hook surface and skills-based global install.",
4189
5027
  "tier": "core",
@@ -4254,14 +5092,17 @@ const runtimes = {
4254
5092
  "maxDepth": 5,
4255
5093
  "background": true,
4256
5094
  "subagentToolkit": "full",
4257
- "backgroundDispatch": false
5095
+ "backgroundDispatch": false,
5096
+ "isolation": "harness-worktree"
4258
5097
  },
4259
5098
  "modelMode": "passive",
4260
5099
  "hookBus": "host",
4261
5100
  "stateIO": "filesystem",
4262
5101
  "transport": "mcp",
4263
- "runtime": "node"
5102
+ "runtime": "node",
5103
+ "effortSurface": "argv"
4264
5104
  },
5105
+ "harnessIsolationFlag": "isolation=\"worktree\"",
4265
5106
  "hostBehaviors": {
4266
5107
  "attributionSource": "settings-json-commit",
4267
5108
  "authorsCanonicalWorkflow": true,
@@ -4283,12 +5124,51 @@ const runtimes = {
4283
5124
  "hyphenNameAgentBody": true,
4284
5125
  "reviewerCli": true
4285
5126
  }
5127
+ },
5128
+ "reviewer": {
5129
+ "slug": "claude",
5130
+ "flags": [
5131
+ "--claude"
5132
+ ],
5133
+ "transport": "spawn",
5134
+ "probe": {
5135
+ "kind": "command-exists",
5136
+ "binary": "claude"
5137
+ },
5138
+ "invoke": {
5139
+ "binary": "claude",
5140
+ "args": [
5141
+ "{{model}}",
5142
+ "{{effort}}",
5143
+ "-p",
5144
+ "-"
5145
+ ],
5146
+ "promptChannel": "stdin",
5147
+ "outputChannel": "stdout",
5148
+ "modelArg": "--model",
5149
+ "effortChannel": "argv"
5150
+ },
5151
+ "timeoutFloorMs": 1200000,
5152
+ "emptyOutput": "stub-with-stderr",
5153
+ "reviewsSection": "Claude",
5154
+ "evidenceClass": "source-grounded",
5155
+ "requiresBinaries": [],
5156
+ "promptBudgetKey": null,
5157
+ "modelConfigKey": "review.models.claude",
5158
+ "handler": null
5159
+ },
5160
+ "config": {
5161
+ "review.models.claude": {
5162
+ "type": "string",
5163
+ "default": "",
5164
+ "description": "Model passed to the Claude reviewer lane."
5165
+ }
4286
5166
  }
4287
5167
  },
4288
5168
  "cline": {
4289
5169
  "id": "cline",
4290
5170
  "role": "runtime",
4291
- "version": "1.8.0",
5171
+ "version": "1.9.0",
4292
5172
  "title": "Cline",
4293
5173
  "description": "Cline (VS Code extension) — global-only nested-skill layout; cline-rules hook surface (.clinerules); no hook events emitted; tier-2 support.",
4294
5174
  "tier": "core",
@@ -4336,13 +5216,15 @@ const runtimes = {
4336
5216
  "maxDepth": 1,
4337
5217
  "background": true,
4338
5218
  "subagentToolkit": "read-only",
4339
- "backgroundDispatch": false
5219
+ "backgroundDispatch": false,
5220
+ "isolation": "undocumented"
4340
5221
  },
4341
5222
  "modelMode": "active",
4342
5223
  "hookBus": "host",
4343
5224
  "stateIO": "filesystem",
4344
5225
  "transport": "mcp",
4345
- "runtime": "node"
5226
+ "runtime": "node",
5227
+ "effortSurface": "undocumented"
4346
5228
  },
4347
5229
  "hostBehaviors": {
4348
5230
  "reapplyCommand": "/gsd-update --reapply",
@@ -4357,7 +5239,7 @@ const runtimes = {
4357
5239
  "codebuddy": {
4358
5240
  "id": "codebuddy",
4359
5241
  "role": "runtime",
4360
- "version": "1.8.0",
5242
+ "version": "1.9.0",
4361
5243
  "title": "CodeBuddy",
4362
5244
  "description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
4363
5245
  "tier": "core",
@@ -4452,13 +5334,15 @@ const runtimes = {
4452
5334
  "maxDepth": 1,
4453
5335
  "background": true,
4454
5336
  "subagentToolkit": "full",
4455
- "backgroundDispatch": false
5337
+ "backgroundDispatch": false,
5338
+ "isolation": "undocumented"
4456
5339
  },
4457
5340
  "modelMode": "passive",
4458
5341
  "hookBus": "host",
4459
5342
  "stateIO": "filesystem",
4460
5343
  "transport": "mcp",
4461
- "runtime": "node"
5344
+ "runtime": "node",
5345
+ "effortSurface": "undocumented"
4462
5346
  },
4463
5347
  "hostBehaviors": {
4464
5348
  "reportCommandsDir": true
@@ -4468,7 +5352,7 @@ const runtimes = {
4468
5352
  "codex": {
4469
5353
  "id": "codex",
4470
5354
  "role": "runtime",
4471
- "version": "1.8.0",
5355
+ "version": "1.9.0",
4472
5356
  "title": "OpenAI Codex CLI",
4473
5357
  "description": "OpenAI Codex CLI — shell-var command style; per-agent sandbox tiers; config.toml + hooks.json hook surface; tier-1 support.",
4474
5358
  "tier": "core",
@@ -4532,13 +5416,23 @@ const runtimes = {
4532
5416
  "maxDepth": 1,
4533
5417
  "background": true,
4534
5418
  "subagentToolkit": "full",
4535
- "backgroundDispatch": true
5419
+ "backgroundDispatch": true,
5420
+ "isolation": "orchestrator-worktree"
4536
5421
  },
4537
5422
  "modelMode": "passive",
4538
5423
  "hookBus": "host",
4539
5424
  "stateIO": "filesystem",
4540
5425
  "transport": "mcp",
4541
- "runtime": "node"
5426
+ "runtime": "node",
5427
+ "effortSurface": "argv"
5428
+ },
5429
+ "orchestratorExec": {
5430
+ "command": "codex",
5431
+ "args": [
5432
+ "exec"
5433
+ ],
5434
+ "cwdFlag": "--cd",
5435
+ "promptFlag": null
4542
5436
  },
4543
5437
  "hostBehaviors": {
4544
5438
  "reapplyCommand": "$gsd-update --reapply",
@@ -4548,12 +5442,55 @@ const runtimes = {
4548
5442
  "frontmatterDialect": "codex",
4549
5443
  "reviewerCli": true
4550
5444
  }
5445
+ },
5446
+ "reviewer": {
5447
+ "slug": "codex",
5448
+ "flags": [
5449
+ "--codex"
5450
+ ],
5451
+ "transport": "spawn",
5452
+ "probe": {
5453
+ "kind": "command-exists",
5454
+ "binary": "codex"
5455
+ },
5456
+ "invoke": {
5457
+ "binary": "codex",
5458
+ "args": [
5459
+ "exec",
5460
+ "--ephemeral",
5461
+ "{{model}}",
5462
+ "{{effort}}",
5463
+ "--skip-git-repo-check",
5464
+ "{{output}}",
5465
+ "-"
5466
+ ],
5467
+ "promptChannel": "stdin",
5468
+ "outputChannel": "file-arg",
5469
+ "outputArg": "-o",
5470
+ "modelArg": "--model",
5471
+ "effortChannel": "argv"
5472
+ },
5473
+ "timeoutFloorMs": 1200000,
5474
+ "emptyOutput": "stub-with-stderr",
5475
+ "reviewsSection": "Codex",
5476
+ "evidenceClass": "source-grounded",
5477
+ "requiresBinaries": [],
5478
+ "promptBudgetKey": null,
5479
+ "modelConfigKey": "review.models.codex",
5480
+ "handler": null
5481
+ },
5482
+ "config": {
5483
+ "review.models.codex": {
5484
+ "type": "string",
5485
+ "default": "",
5486
+ "description": "Model passed to the Codex reviewer lane."
5487
+ }
4551
5488
  }
4552
5489
  },
4553
5490
  "copilot": {
4554
5491
  "id": "copilot",
4555
5492
  "role": "runtime",
4556
- "version": "1.8.0",
5493
+ "version": "1.9.0",
4557
5494
  "title": "GitHub Copilot",
4558
5495
  "description": "GitHub Copilot (VS Code) — markdown config format; copilot-inline hook surface; no hook events emitted; flat skill nesting (unconfirmed recursive loader); tier-2 support.",
4559
5496
  "tier": "core",
@@ -4627,13 +5564,15 @@ const runtimes = {
4627
5564
  "maxDepth": 1,
4628
5565
  "background": true,
4629
5566
  "subagentToolkit": "full",
4630
- "backgroundDispatch": false
5567
+ "backgroundDispatch": false,
5568
+ "isolation": "undocumented"
4631
5569
  },
4632
5570
  "modelMode": "passive",
4633
5571
  "hookBus": "host",
4634
5572
  "stateIO": "filesystem",
4635
5573
  "transport": "mcp",
4636
- "runtime": "undocumented"
5574
+ "runtime": "undocumented",
5575
+ "effortSurface": "undocumented"
4637
5576
  },
4638
5577
  "hostBehaviors": {
4639
5578
  "reapplyCommand": "/gsd-update --reapply",
@@ -4646,7 +5585,7 @@ const runtimes = {
4646
5585
  "cursor": {
4647
5586
  "id": "cursor",
4648
5587
  "role": "runtime",
4649
- "version": "1.8.0",
5588
+ "version": "1.9.0",
4650
5589
  "title": "Cursor",
4651
5590
  "description": "Cursor IDE — skills + converted commands artifact layout; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.",
4652
5591
  "tier": "core",
@@ -4736,14 +5675,17 @@ const runtimes = {
4736
5675
  "maxDepth": 2,
4737
5676
  "background": true,
4738
5677
  "subagentToolkit": "full",
4739
- "backgroundDispatch": true
5678
+ "backgroundDispatch": true,
5679
+ "isolation": "harness-worktree"
4740
5680
  },
4741
5681
  "modelMode": "passive",
4742
5682
  "hookBus": "host",
4743
5683
  "stateIO": "filesystem",
4744
5684
  "transport": "mcp",
4745
- "runtime": "node"
5685
+ "runtime": "node",
5686
+ "effortSurface": "undocumented"
4746
5687
  },
5688
+ "harnessIsolationFlag": "--worktree",
4747
5689
  "hostBehaviors": {
4748
5690
  "reapplyCommand": "gsd-update --reapply (mention the skill name)",
4749
5691
  "frontmatterDialect": "cursor",
@@ -4762,12 +5704,47 @@ const runtimes = {
4762
5704
  ],
4763
5705
  "reviewerCli": true
4764
5706
  }
5707
+ },
5708
+ "reviewer": {
5709
+ "slug": "cursor",
5710
+ "flags": [
5711
+ "--cursor"
5712
+ ],
5713
+ "transport": "spawn",
5714
+ "probe": {
5715
+ "kind": "command-exists",
5716
+ "binary": "cursor-agent"
5717
+ },
5718
+ "invoke": {
5719
+ "binary": "cursor-agent",
5720
+ "args": [
5721
+ "-p",
5722
+ "--mode",
5723
+ "ask",
5724
+ "--trust",
5725
+ "--output-format",
5726
+ "text",
5727
+ "{{prompt}}"
5728
+ ],
5729
+ "promptChannel": "argv-file-ref",
5730
+ "outputChannel": "stdout",
5731
+ "modelArg": null,
5732
+ "effortChannel": "none"
5733
+ },
5734
+ "timeoutFloorMs": 900000,
5735
+ "emptyOutput": "stub-with-stderr",
5736
+ "reviewsSection": "Cursor",
5737
+ "evidenceClass": "source-grounded",
5738
+ "requiresBinaries": [],
5739
+ "promptBudgetKey": null,
5740
+ "modelConfigKey": null,
5741
+ "handler": null
4765
5742
  }
4766
5743
  },
4767
5744
  "hermes": {
4768
5745
  "id": "hermes",
4769
5746
  "role": "runtime",
4770
- "version": "1.8.0",
5747
+ "version": "1.9.0",
4771
5748
  "title": "Hermes Agent",
4772
5749
  "description": "Hermes Agent (NousResearch) — skills nest under skills/gsd/ category bucket; nested skill layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
4773
5750
  "tier": "core",
@@ -4843,20 +5820,22 @@ const runtimes = {
4843
5820
  "maxDepth": 1,
4844
5821
  "background": true,
4845
5822
  "subagentToolkit": "read-only",
4846
- "backgroundDispatch": false
5823
+ "backgroundDispatch": false,
5824
+ "isolation": "undocumented"
4847
5825
  },
4848
5826
  "modelMode": "active",
4849
5827
  "hookBus": "host",
4850
5828
  "stateIO": "filesystem",
4851
5829
  "transport": "mcp",
4852
- "runtime": "python"
5830
+ "runtime": "python",
5831
+ "effortSurface": "undocumented"
4853
5832
  }
4854
5833
  }
4855
5834
  },
4856
5835
  "kilo": {
4857
5836
  "id": "kilo",
4858
5837
  "role": "runtime",
4859
- "version": "1.8.0",
5838
+ "version": "1.9.0",
4860
5839
  "title": "Kilo Code",
4861
5840
  "description": "Kilo Code — XDG-based config dir; global skills at ~/.kilo/skills (separate from XDG config); flat command/ + skills artifact layout; no lifecycle hook registration; tier-2 support.",
4862
5841
  "tier": "core",
@@ -4937,13 +5916,15 @@ const runtimes = {
4937
5916
  "maxDepth": -1,
4938
5917
  "background": true,
4939
5918
  "subagentToolkit": "undocumented",
4940
- "backgroundDispatch": false
5919
+ "backgroundDispatch": false,
5920
+ "isolation": "undocumented"
4941
5921
  },
4942
5922
  "modelMode": "active",
4943
5923
  "hookBus": "host",
4944
5924
  "stateIO": "filesystem",
4945
5925
  "transport": "mcp",
4946
- "runtime": "bun"
5926
+ "runtime": "bun",
5927
+ "effortSurface": "undocumented"
4947
5928
  },
4948
5929
  "hostBehaviors": {
4949
5930
  "reapplyCommand": "/gsd-update --reapply",
@@ -4963,7 +5944,7 @@ const runtimes = {
4963
5944
  "kimi": {
4964
5945
  "id": "kimi",
4965
5946
  "role": "runtime",
4966
- "version": "1.8.0",
5947
+ "version": "1.9.0",
4967
5948
  "title": "Kimi CLI",
4968
5949
  "description": "Kimi CLI (Moonshot AI) — generic agents root at ~/.config/agents; skills + kimi-agents artifact layout; native config.toml [[hooks]] bus at ~/.kimi/config.toml; background dispatch; tier-2 support.",
4969
5950
  "tier": "core",
@@ -5030,13 +6011,23 @@ const runtimes = {
5030
6011
  "maxDepth": 1,
5031
6012
  "background": true,
5032
6013
  "subagentToolkit": "undocumented",
5033
- "backgroundDispatch": true
6014
+ "backgroundDispatch": true,
6015
+ "isolation": "orchestrator-worktree"
5034
6016
  },
5035
6017
  "modelMode": "passive",
5036
6018
  "hookBus": "host",
5037
6019
  "stateIO": "filesystem",
5038
6020
  "transport": "mcp",
5039
- "runtime": "python"
6021
+ "runtime": "python",
6022
+ "effortSurface": "undocumented"
6023
+ },
6024
+ "orchestratorExec": {
6025
+ "command": "kimi",
6026
+ "args": [
6027
+ "--print"
6028
+ ],
6029
+ "cwdFlag": "--work-dir",
6030
+ "promptFlag": "--prompt"
5040
6031
  },
5041
6032
  "hostBehaviors": {
5042
6033
  "reapplyCommand": "/skill:gsd-update --reapply",
@@ -5048,10 +6039,142 @@ const runtimes = {
5048
6039
  }
5049
6040
  }
5050
6041
  },
6042
+ "kimi-code": {
6043
+ "id": "kimi-code",
6044
+ "role": "runtime",
6045
+ "version": "1.9.0",
6046
+ "title": "Kimi Code CLI",
6047
+ "description": "Kimi Code CLI (Moonshot AI, Node) — Agent Skills auto-discovered at ~/.kimi-code/skills; global AGENTS.md at ~/.kimi-code/AGENTS.md; native config.toml + [[hooks]] bus; three built-in subagents (coder/explore/plan), NO custom named subagents; background dispatch; tier-2 support. Distinct from Python kimi-cli (the 'kimi' capability) per ADR-1239 EoS — Kimi Code cannot dispatch named subagents so the kimi-agents YAML layout does NOT apply; persona injection rides the existing ${AGENT_SKILLS_*} workflow fallback. Install-layout, agent-install-check, and install-time decision (kimi vs kimi-code) land in follow-up PRs; this descriptor is the EoS foundation.",
6048
+ "tier": "core",
6049
+ "requires": [],
6050
+ "engines": {
6051
+ "gsd": ">=1.7.0"
6052
+ },
6053
+ "runtime": {
6054
+ "configHome": {
6055
+ "kind": "dot-home",
6056
+ "name": ".kimi-code",
6057
+ "env": [
6058
+ "KIMI_CODE_HOME"
6059
+ ],
6060
+ "probe": [
6061
+ "~/.kimi-code"
6062
+ ],
6063
+ "probeExists": "config.toml"
6064
+ },
6065
+ "localConfigDir": ".kimi-code",
6066
+ "configFormat": "none",
6067
+ "artifactLayout": {
6068
+ "global": [
6069
+ {
6070
+ "kind": "skills",
6071
+ "destSubpath": "skills",
6072
+ "prefix": "gsd-",
6073
+ "nesting": "flat",
6074
+ "recursive": false,
6075
+ "converter": "convertClaudeCommandToKimiCodeSkill"
6076
+ }
6077
+ ],
6078
+ "local": []
6079
+ },
6080
+ "commandStyle": "slash-hyphen",
6081
+ "hooksSurface": "kimi-hooks-toml",
6082
+ "hookEvents": "claude",
6083
+ "sandboxTier": "none",
6084
+ "supportTier": 2,
6085
+ "installSurface": "profile-marker-only",
6086
+ "writesSharedSettings": false,
6087
+ "permissionWriter": null,
6088
+ "extendedHookEvents": [
6089
+ "SubagentStop",
6090
+ "Stop",
6091
+ "PreCompact",
6092
+ "SubagentStart"
6093
+ ],
6094
+ "hostIntegration": {
6095
+ "embeddingMode": "declarative",
6096
+ "commandSurface": "slash-file",
6097
+ "dispatch": {
6098
+ "namedDispatch": false,
6099
+ "nested": true,
6100
+ "maxDepth": "undocumented",
6101
+ "background": true,
6102
+ "subagentToolkit": "built-in-only",
6103
+ "backgroundDispatch": true,
6104
+ "builtInSubagents": [
6105
+ "coder",
6106
+ "explore",
6107
+ "plan"
6108
+ ],
6109
+ "isolation": "orchestrator-worktree"
6110
+ },
6111
+ "modelMode": "passive",
6112
+ "hookBus": "host",
6113
+ "stateIO": "filesystem",
6114
+ "transport": "mcp",
6115
+ "runtime": "node"
6116
+ },
6117
+ "orchestratorExec": {
6118
+ "command": "kimi",
6119
+ "args": [],
6120
+ "cwdFlag": null,
6121
+ "promptFlag": "--prompt"
6122
+ },
6123
+ "hostBehaviors": {
6124
+ "reapplyCommand": "/skill:gsd-update --reapply",
6125
+ "localInstallDeferred": true,
6126
+ "verificationStyle": "kimi-code",
6127
+ "agentManifestStyle": "none",
6128
+ "doneBannerStyle": "kimi-code",
6129
+ "skipSharedHooksInstall": true,
6130
+ "namedSubagentsSupported": false
6131
+ }
6132
+ },
6133
+ "reviewer": {
6134
+ "slug": "kimi-code",
6135
+ "flags": [
6136
+ "--kimi-code"
6137
+ ],
6138
+ "transport": "spawn",
6139
+ "probe": {
6140
+ "kind": "command-capability",
6141
+ "binary": "kimi",
6142
+ "needle": "--output-format",
6143
+ "timeoutMs": 5000
6144
+ },
6145
+ "invoke": {
6146
+ "binary": "kimi",
6147
+ "args": [
6148
+ "{{model}}",
6149
+ "-p",
6150
+ "{{prompt}}"
6151
+ ],
6152
+ "promptChannel": "argv-file-ref",
6153
+ "outputChannel": "stdout",
6154
+ "modelArg": "-m",
6155
+ "effortChannel": "none"
6156
+ },
6157
+ "timeoutFloorMs": 900000,
6158
+ "emptyOutput": "stub-with-stderr",
6159
+ "reviewsSection": "Kimi Code",
6160
+ "evidenceClass": "source-grounded",
6161
+ "requiresBinaries": [],
6162
+ "promptBudgetKey": null,
6163
+ "modelConfigKey": "review.models.kimi-code",
6164
+ "handler": null
6165
+ },
6166
+ "config": {
6167
+ "review.models.kimi-code": {
6168
+ "type": "string",
6169
+ "default": "",
6170
+ "description": "Model passed to the Kimi Code reviewer lane."
6171
+ }
6172
+ }
6173
+ },
5051
6174
  "opencode": {
5052
6175
  "id": "opencode",
5053
6176
  "role": "runtime",
5054
- "version": "1.8.0",
6177
+ "version": "1.9.0",
5055
6178
  "title": "OpenCode",
5056
6179
  "description": "OpenCode — XDG-based config dir; flat commands/ + skills artifact layout; settings-json config format; no lifecycle hook registration; tier-2 support.",
5057
6180
  "tier": "core",
@@ -5125,15 +6248,25 @@ const runtimes = {
5125
6248
  "namedDispatch": true,
5126
6249
  "nested": "undocumented",
5127
6250
  "maxDepth": "undocumented",
5128
- "background": true,
6251
+ "background": false,
5129
6252
  "subagentToolkit": "full",
5130
- "backgroundDispatch": true
6253
+ "backgroundDispatch": false,
6254
+ "isolation": "orchestrator-worktree"
5131
6255
  },
5132
6256
  "modelMode": "active",
5133
6257
  "hookBus": "host",
5134
6258
  "stateIO": "filesystem",
5135
6259
  "transport": "mcp",
5136
- "runtime": "bun"
6260
+ "runtime": "bun",
6261
+ "effortSurface": "argv"
6262
+ },
6263
+ "orchestratorExec": {
6264
+ "command": "opencode",
6265
+ "args": [
6266
+ "run"
6267
+ ],
6268
+ "cwdFlag": "--dir",
6269
+ "promptFlag": null
5137
6270
  },
5138
6271
  "hostBehaviors": {
5139
6272
  "reapplyCommand": "/gsd-update --reapply",
@@ -5152,12 +6285,53 @@ const runtimes = {
5152
6285
  "skipCodexSkillsManifest": true,
5153
6286
  "reviewerCli": true
5154
6287
  }
6288
+ },
6289
+ "reviewer": {
6290
+ "slug": "opencode",
6291
+ "flags": [
6292
+ "--opencode"
6293
+ ],
6294
+ "transport": "spawn",
6295
+ "probe": {
6296
+ "kind": "command-exists",
6297
+ "binary": "opencode"
6298
+ },
6299
+ "invoke": {
6300
+ "binary": "opencode",
6301
+ "args": [
6302
+ "run",
6303
+ "{{model}}",
6304
+ "{{effort}}",
6305
+ "--format",
6306
+ "json",
6307
+ "-"
6308
+ ],
6309
+ "promptChannel": "stdin",
6310
+ "outputChannel": "stdout",
6311
+ "modelArg": "--model",
6312
+ "effortChannel": "argv"
6313
+ },
6314
+ "timeoutFloorMs": 660000,
6315
+ "emptyOutput": "stub-with-stderr",
6316
+ "reviewsSection": "OpenCode",
6317
+ "evidenceClass": "source-grounded",
6318
+ "requiresBinaries": [],
6319
+ "promptBudgetKey": null,
6320
+ "modelConfigKey": "review.models.opencode",
6321
+ "handler": "opencode"
6322
+ },
6323
+ "config": {
6324
+ "review.models.opencode": {
6325
+ "type": "string",
6326
+ "default": "",
6327
+ "description": "Model passed to the OpenCode reviewer lane."
6328
+ }
5155
6329
  }
5156
6330
  },
5157
6331
  "pi": {
5158
6332
  "id": "pi",
5159
6333
  "role": "runtime",
5160
- "version": "1.8.0",
6334
+ "version": "1.9.0",
5161
6335
  "title": "pi",
5162
6336
  "description": "pi (pi.dev) — bun-runtime programmatic-CLI; TS ExtensionAPI (registerCommand/registerTool/registerProvider/pi.on); single native-extension file at ~/.pi/agent/extensions/gsd.js (.js, not .cjs — pi's extension auto-discovery accepts only .ts/.js, #2470); no shared-settings hook surface; tier-2 support.",
5163
6337
  "tier": "core",
@@ -5196,13 +6370,15 @@ const runtimes = {
5196
6370
  "maxDepth": 0,
5197
6371
  "background": false,
5198
6372
  "backgroundDispatch": false,
5199
- "subagentToolkit": "undocumented"
6373
+ "subagentToolkit": "undocumented",
6374
+ "isolation": "none"
5200
6375
  },
5201
6376
  "modelMode": "active",
5202
6377
  "hookBus": "host",
5203
6378
  "stateIO": "session-log-append",
5204
6379
  "transport": "native-extension",
5205
- "runtime": "bun"
6380
+ "runtime": "bun",
6381
+ "effortSurface": "undocumented"
5206
6382
  },
5207
6383
  "hostBehaviors": {
5208
6384
  "nativePlugin": {
@@ -5217,7 +6393,7 @@ const runtimes = {
5217
6393
  "qwen": {
5218
6394
  "id": "qwen",
5219
6395
  "role": "runtime",
5220
- "version": "1.8.0",
6396
+ "version": "1.9.0",
5221
6397
  "title": "Qwen Code",
5222
6398
  "description": "Qwen Code (Alibaba) — nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
5223
6399
  "tier": "core",
@@ -5296,13 +6472,15 @@ const runtimes = {
5296
6472
  "maxDepth": 1,
5297
6473
  "background": true,
5298
6474
  "subagentToolkit": "full",
5299
- "backgroundDispatch": false
6475
+ "backgroundDispatch": false,
6476
+ "isolation": "undocumented"
5300
6477
  },
5301
6478
  "modelMode": "passive",
5302
6479
  "hookBus": "host",
5303
6480
  "stateIO": "filesystem",
5304
6481
  "transport": "mcp",
5305
- "runtime": "node"
6482
+ "runtime": "node",
6483
+ "effortSurface": "undocumented"
5306
6484
  },
5307
6485
  "hostBehaviors": {
5308
6486
  "skillPriorityFrontmatter": true,
@@ -5317,12 +6495,41 @@ const runtimes = {
5317
6495
  "hyphenNameAgentBody": true,
5318
6496
  "reviewerCli": true
5319
6497
  }
6498
+ },
6499
+ "reviewer": {
6500
+ "slug": "qwen",
6501
+ "flags": [
6502
+ "--qwen"
6503
+ ],
6504
+ "transport": "spawn",
6505
+ "probe": {
6506
+ "kind": "command-exists",
6507
+ "binary": "qwen"
6508
+ },
6509
+ "invoke": {
6510
+ "binary": "qwen",
6511
+ "args": [
6512
+ "-"
6513
+ ],
6514
+ "promptChannel": "stdin",
6515
+ "outputChannel": "stdout",
6516
+ "modelArg": null,
6517
+ "effortChannel": "none"
6518
+ },
6519
+ "timeoutFloorMs": 900000,
6520
+ "emptyOutput": "stub-with-stderr",
6521
+ "reviewsSection": "Qwen",
6522
+ "evidenceClass": "source-grounded",
6523
+ "requiresBinaries": [],
6524
+ "promptBudgetKey": null,
6525
+ "modelConfigKey": null,
6526
+ "handler": null
5320
6527
  }
5321
6528
  },
5322
6529
  "trae": {
5323
6530
  "id": "trae",
5324
6531
  "role": "runtime",
5325
- "version": "1.8.0",
6532
+ "version": "1.9.0",
5326
6533
  "title": "Trae IDE",
5327
6534
  "description": "Trae IDE — nested-skill artifact layout; no hook surface (profile-marker-only config); tier-2 support.",
5328
6535
  "tier": "core",
@@ -5395,13 +6602,15 @@ const runtimes = {
5395
6602
  "maxDepth": "undocumented",
5396
6603
  "background": true,
5397
6604
  "subagentToolkit": "undocumented",
5398
- "backgroundDispatch": "undocumented"
6605
+ "backgroundDispatch": "undocumented",
6606
+ "isolation": "undocumented"
5399
6607
  },
5400
6608
  "modelMode": "passive",
5401
6609
  "hookBus": "engine",
5402
6610
  "stateIO": "filesystem",
5403
6611
  "transport": "mcp",
5404
- "runtime": "node"
6612
+ "runtime": "node",
6613
+ "effortSurface": "undocumented"
5405
6614
  },
5406
6615
  "hostBehaviors": {
5407
6616
  "skipSharedHooksInstall": true,
@@ -5412,7 +6621,7 @@ const runtimes = {
5412
6621
  "vscode": {
5413
6622
  "id": "vscode",
5414
6623
  "role": "runtime",
5415
- "version": "1.8.0",
6624
+ "version": "1.9.0",
5416
6625
  "title": "VS Code",
5417
6626
  "description": "VS Code — Marketplace/VSIX extension; no file-projected config directory; IDE-profile reference host (active vscode.lm model, engine-owned hook bus, sandboxed globalState/workspaceState stateIO).",
5418
6627
  "tier": "core",
@@ -5450,20 +6659,22 @@ const runtimes = {
5450
6659
  "maxDepth": 5,
5451
6660
  "background": true,
5452
6661
  "subagentToolkit": "undocumented",
5453
- "backgroundDispatch": "undocumented"
6662
+ "backgroundDispatch": "undocumented",
6663
+ "isolation": "undocumented"
5454
6664
  },
5455
6665
  "modelMode": "active",
5456
6666
  "hookBus": "engine",
5457
6667
  "stateIO": "sandboxed-storage",
5458
6668
  "transport": "mcp",
5459
- "runtime": "sandboxed-web"
6669
+ "runtime": "sandboxed-web",
6670
+ "effortSurface": "undocumented"
5460
6671
  }
5461
6672
  }
5462
6673
  },
5463
6674
  "windsurf": {
5464
6675
  "id": "windsurf",
5465
6676
  "role": "runtime",
5466
- "version": "1.8.0",
6677
+ "version": "1.9.0",
5467
6678
  "title": "Windsurf",
5468
6679
  "description": "Windsurf (Codeium) — workspace workflow artifact layout for slash commands; Cascade native hooks.json blocking hook bus (pre_write_code, pre_run_command); tier-2 support.",
5469
6680
  "tier": "core",
@@ -5529,13 +6740,15 @@ const runtimes = {
5529
6740
  "maxDepth": "undocumented",
5530
6741
  "background": "undocumented",
5531
6742
  "subagentToolkit": "undocumented",
5532
- "backgroundDispatch": "undocumented"
6743
+ "backgroundDispatch": "undocumented",
6744
+ "isolation": "none"
5533
6745
  },
5534
6746
  "modelMode": "passive",
5535
6747
  "hookBus": "host",
5536
6748
  "stateIO": "filesystem",
5537
6749
  "transport": "mcp",
5538
- "runtime": "undocumented"
6750
+ "runtime": "undocumented",
6751
+ "effortSurface": "undocumented"
5539
6752
  },
5540
6753
  "hostBehaviors": {
5541
6754
  "skipSharedHooksInstall": true,
@@ -5548,7 +6761,7 @@ const runtimes = {
5548
6761
  "zcode": {
5549
6762
  "id": "zcode",
5550
6763
  "role": "runtime",
5551
- "version": "1.8.0",
6764
+ "version": "1.9.0",
5552
6765
  "title": "ZCode",
5553
6766
  "description": "ZCode (Z.ai) — desktop Agentic Development Environment for GLM-5.2; Claude-shaped nested skills at ~/.zcode/skills/<name>/SKILL.md, slash commands, named subagents, native MCP; declarative plugin surface; profile-marker install; tier-2 community support.",
5554
6767
  "tier": "core",
@@ -5637,13 +6850,15 @@ const runtimes = {
5637
6850
  "maxDepth": "undocumented",
5638
6851
  "background": false,
5639
6852
  "subagentToolkit": "full",
5640
- "backgroundDispatch": false
6853
+ "backgroundDispatch": false,
6854
+ "isolation": "none"
5641
6855
  },
5642
6856
  "modelMode": "passive",
5643
6857
  "hookBus": "host",
5644
6858
  "stateIO": "filesystem",
5645
6859
  "transport": "mcp",
5646
- "runtime": "electron"
6860
+ "runtime": "electron",
6861
+ "effortSurface": "undocumented"
5647
6862
  },
5648
6863
  "hostBehaviors": {
5649
6864
  "skipSharedHooksInstall": true
@@ -5812,19 +7027,25 @@ const _requiresGraph = {
5812
7027
  "cline": [],
5813
7028
  "code-review": [],
5814
7029
  "codebuddy": [],
7030
+ "coderabbit": [],
5815
7031
  "codex": [],
5816
7032
  "copilot": [],
5817
7033
  "cursor": [],
5818
7034
  "drift": [],
5819
7035
  "external-job": [],
5820
7036
  "gap-analysis": [],
7037
+ "gemini": [],
5821
7038
  "graphify": [],
5822
7039
  "hermes": [],
5823
7040
  "intel": [],
5824
7041
  "kilo": [],
5825
7042
  "kimi": [],
7043
+ "kimi-code": [],
7044
+ "llama-cpp": [],
7045
+ "lm-studio": [],
5826
7046
  "mempalace": [],
5827
7047
  "nyquist": [],
7048
+ "ollama": [],
5828
7049
  "opencode": [],
5829
7050
  "pattern-mapper": [
5830
7051
  "research"