feat(#3673): add dispatch.maxConcurrency axis and dispatch-capacity query (#4162)

* test(#3673): add failing tests for dispatch.maxConcurrency axis and dispatch-capacity CLI route

Extends tests/host-integration.test.cjs with negotiateHostCapabilities
maxConcurrency negotiation coverage (test matrix rows 1-15, including a
fast-check property test) and a new #3673 dispatch-capacity CLI route
describe block spawning the real gsd-tools.cjs (rows 16-25). Extends
tests/host-integration-validator-parity.test.cjs with an all-19-descriptor
maxConcurrency presence/validity sweep (row 26) and adds a hostile-input
validator test to host-integration.test.cjs (row 27).

The dispatch.maxConcurrency field does not exist yet, so these tests fail.

* feat(#3673): add dispatch.maxConcurrency axis, negotiation, validator parity, and the dispatch-capacity query

Adds a numeric dispatch.maxConcurrency sub-field to the Host-Integration
Interface (ADR-1239 Phase 1), following the existing dispatch.isolation
sub-field pattern: DispatchCapability interface, SAFE_DEFAULTS/PROFILE_BASELINES
floors, and a negotiateHostCapabilities branch that passes through a positive
safe integer and fails closed to 1 otherwise (no engine-side reduction, per
the design doc's explicit rejection of a min(host,engine) rule).

capability-validator.cjs gains parity validation for the new field (optional,
positive safe integer or the "undocumented" sentinel — mirroring isolation's
"added after existing descriptors" treatment).

gsd-tools.cjs gains a new `query dispatch-capacity` route, a pure-read sibling
of `dispatch-isolation` with no side effects: live env
(GSD_DISPATCH_MAX_CONCURRENCY) > descriptor > fallback-to-1 precedence.

All 19 capabilities/*/capability.json descriptors now declare
dispatch.maxConcurrency: claude carries the one cited value (20, per
code.claude.com/docs/en/sub-agents); the other 18 carry "undocumented"
(not yet researched for this axis).

* docs(#3673): document dispatch.maxConcurrency and add its citation row to the capability matrix

Updates docs/reference/host-integration-interface.md's dispatch struct entry
(also backfilling the previously-undocumented isolation/backgroundDispatch
sub-fields found stale in the same table) and adds fail-closed/live-transport
precedence prose for the new maxConcurrency field.

Adds a dispatch.maxConcurrency row (with citation) to all 19 host sections in
docs/reference/host-integration-capability-matrix.md — required for
tests/host-integration-descriptors.test.cjs's kimi-code matrix-parity check,
which asserts every declared dispatch sub-axis is documented there.

Updates docs/how-to/add-or-update-a-host-integration.md's dispatch checklist
and example descriptor block to mention maxConcurrency (and, likewise
backfilling a stale gap, isolation/backgroundDispatch).

* fix(#3673): extract shared maxConcurrency validator, drop dead reserved-name check

Exports isPositiveSafeInteger from src/host-integration.cts as the single
source of truth for the dispatch.maxConcurrency positive-safe-integer
contract; negotiateHostCapabilities and gsd-tools.cjs's routeDispatchCapacity
now both call it instead of independently reimplementing the same predicate.

Also removes the __proto__/constructor/prototype reserved-name branch from
capability-validator.cjs's maxConcurrency check — copy-pasted from the
string-enum fields above it, but unreachable for a numeric field (the
generic positive-safe-integer branch already rejects any string) and absent
from maxDepth, the field the code's own comment claims to mirror.

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-01 21:39:12 -04:00
committed by GitHub
parent b848b23861
commit c0fd2e3f4c
28 changed files with 714 additions and 67 deletions

View File

@@ -30,7 +30,7 @@ Read the docs and map them to the closed vocabulary. Do not pick a value unless
|---|---|
| `embeddingMode` | An in-process programmatic plugin/extension API (`imperative`) vs. configuration files only (`declarative`). |
| `commandSurface` | How custom commands are authored/invoked: `slash-file` (.md), `slash-toml`, `slash-programmatic`, `palette`, `prose-only`. |
| `dispatch` | Sub-agent delegation: `namedDispatch`, `nested`, `maxDepth` (int; `-1` = documented-unbounded), `background`, `subagentToolkit` (`full`/`read-only`). |
| `dispatch` | Sub-agent delegation: `namedDispatch`, `nested`, `maxDepth` (int; `-1` = documented-unbounded), `background`, `subagentToolkit` (`full`/`read-only`/`built-in-only`), `backgroundDispatch`, `isolation` (`harness-worktree`/`orchestrator-worktree`/`none`, #2584), `maxConcurrency` (positive integer — how many same-wave executors this host can run concurrently; no engine-side ceiling, unlike `maxDepth`; #3673). |
| `modelMode` | A programmatic model request/provider API (`active`) vs. instruction/per-agent-field only (`passive`). |
| `hookBus` | The host fires lifecycle events a plugin subscribes to (`host`), an extension host owns the bus (`engine`), or no bus (`none`). **Independent of `hooksSurface`** — e.g. opencode has `hooksSurface: none` but `hookBus: host`. |
| `stateIO` | `filesystem`, `sandboxed-storage` (web IDE, no arbitrary FS), or `session-log-append`. |
@@ -48,7 +48,7 @@ not state:
"hostIntegration": {
"embeddingMode": "declarative",
"commandSurface": "slash-file",
"dispatch": { "namedDispatch": true, "nested": false, "maxDepth": 1, "background": false, "subagentToolkit": "undocumented" },
"dispatch": { "namedDispatch": true, "nested": false, "maxDepth": 1, "background": false, "subagentToolkit": "undocumented", "backgroundDispatch": false, "isolation": "undocumented", "maxConcurrency": "undocumented" },
"modelMode": "passive",
"hookBus": "host",
"stateIO": "filesystem",
@@ -60,7 +60,7 @@ not state:
**When to use `undocumented`:** only when you searched and the host's docs genuinely do not state the
axis. It validates, but `negotiateHostCapabilities` **fail-closes** on it (degrades to the most
restrictive known value) — so it is always safe and never a silent capability claim. A dispatch
boolean or `maxDepth` may also be `"undocumented"`.
boolean, `maxDepth`, `isolation`, or `maxConcurrency` may also be `"undocumented"`.
**Do not conflate the orthogonal axes:** `commandStyle` (GSD's emission style) is *not*
`commandSurface` (the host's surface type); the `hookEvents` dialect is *not* `hookBus` (bus

View File

@@ -86,6 +86,7 @@ Module entry and `.gsd/phase/feat-2871-trigger-resolution/40-design.md`.
| dispatch.subagentToolkit | full | https://code.claude.com/docs/en/sub-agents | "If all tools remain selected, the subagent inherits all tools available to the main conversation." |
| dispatch.backgroundDispatch | false | https://code.claude.com/docs/en/sub-agents | "Background subagents are limited to a depth of five and cannot spawn further, " |
| dispatch.isolation | harness-worktree | https://code.claude.com/docs/en/sub-agents ; Claude Code Agent tool (`Agent(isolation="worktree")`) | The Claude Code Agent tool accepts an `isolation="worktree"` harness primitive — the host's own harness creates + binds a git worktree per executor; GSD passes the flag and calls no git itself (#2584) |
| dispatch.maxConcurrency | 20 | https://code.claude.com/docs/en/sub-agents | The subagent documentation states a default concurrent-subagent limit of 20, configurable via the `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS` environment variable (#3673). |
Sources consulted:
- https://code.claude.com/docs/en/sub-agents
@@ -124,6 +125,7 @@ Sources consulted:
| dispatch.subagentToolkit | full | https://developers.openai.com/codex/multi-agent | "Subagents inherit the sandbox policy and tool surface from the parent session." |
| dispatch.backgroundDispatch | true | https://github.com/openai/codex/blob/main/codex-rs/core/templates/collab/experimental_prompt.md | "Sub-agents have access to the same set of tools as you do so you must tell them if they are allowed to spawn sub-agents themselves or not." The config (codex-rs/config/src/config_toml.rs) exposes an |
| dispatch.isolation | orchestrator-worktree | https://learn.chatgpt.com/docs/environments/git-worktrees ; https://github.com/openai/codex/blob/main/codex-rs/utils/cli/src/shared_options.rs | "Worktrees are available only in Codex in the ChatGPT desktop app." (no native CLI worktree) + `codex exec --cd <dir>` sets an explicit working root, so GSD creates+manages the worktree and points the executor at it (#2584) |
| dispatch.maxConcurrency | undocumented | https://developers.openai.com/codex/config-reference | `agents.max_concurrent_threads_per_session` is a documented config key, but the reference states no numeric default — "Codex chooses the default" — so there is no single value to cite (#3673). |
**GSD integration status — Phase D dogfood complete (#2088, ADR-1239).** Codex installs through the `declarative` embedding adapter (`createDeclarativeAdapter` → `installRuntimeArtifacts`); the hardcoded `runtime === 'codex'`/`isCodex` projection is folded into descriptor-driven `runtime.hostBehaviors`, and install/uninstall output is byte-parity-gated at the time (`tests/fixtures/golden-install-parity/codex.json`; superseded by the differential attribution check, #2724). Three capability upgrades land, each with a test driving the user-reachable surface:
@@ -169,6 +171,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://opencode.ai/docs/agents | "The 'general' subagent \"Has full tool access (except todo), so it can make file changes when needed.\"" |
| dispatch.backgroundDispatch | false | https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/effect/runtime-flags.ts ; https://github.com/anomalyco/opencode/issues/29638 ; https://github.com/anomalyco/opencode/issues/14195 | "Concurrent dispatch requires the opt-in `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS` flag (default `false`), so it cannot be relied on. #14195: \"the session loop does `tasks.pop()` to grab a single subtask, `await`s it, then `continue`s the loop — so even 3 simultaneous Task calls run sequentially.\" Declaring `true` would overstate the capability, against the fail-closed posture negotiation is built for. (#2598 — corrects #2087)" |
| dispatch.isolation | orchestrator-worktree | https://opencode.ai/docs/cli ; opencode.ai/docs/plugins ; opencode issues #14195/#29638/#5887 | "`opencode run --dir <path>` sets an explicit working root at the process level" — native subagent dispatch is synchronous-only, so GSD creates + manages the worktree and process-spawns the executor into it via `--dir` (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://opencode.ai/docs/plugins
@@ -204,6 +207,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://cursor.com/docs/subagents | "Subagents can utilize MCP tools, inheriting all tools available to their parent agent, including those from configured s" |
| dispatch.backgroundDispatch | true | https://cursor.com/docs/subagents (FAQ: Can subagents launch other subagents?) and https://cursor.com/docs/sdk/typescript (Subagents > Nested subagents) | FAQ: "As of Cursor 2.5, subagents have the capability to launch child subagents, enabling the creation of a hierarchical structure for coordinated tasks. This nested launching functionality requires T |
| dispatch.isolation | harness-worktree | https://cursor.com/docs/cli/reference/parameters ; cursor.com/docs/cli/using ; cursor.com/docs/cli/changelog | "`-w, --worktree [name]` — cursor-agent creates/binds a git worktree per agent (`~/.cursor/worktrees/…`); native parallel-agent dispatch" (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://cursor.com/docs/subagents
@@ -241,6 +245,7 @@ Sources consulted:
| dispatch.subagentToolkit | read-only | /cline/cline (Context7) — https://github.com/cline/cline/blob/main/docs/features/subagents.mdx | "Subagents are equipped with tools for read-only operations, including reading file contents (read_file), listing directo" |
| dispatch.backgroundDispatch | false | https://docs.cline.bot/features/subagents (mirrored at https://github.com/cline/cline/blob/main/docs/features/subagents.mdx) | "They cannot edit files, use the browser, or spawn nested subagents" — and from the GitHub source: "subagents are restricted from editing files, using the browser, accessing MCP servers, or creating n |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://github.com/cline/cline/blob/main/docs/sdk/plugins.mdx
@@ -279,6 +284,7 @@ Sources consulted:
| dispatch.subagentToolkit | read-only | https://hermes-agent.nousresearch.com/docs/guides/delegation-patterns | "Nested delegation is opt-in; by default, leaf subagents cannot call delegate_task, clarify, memory, send_message, or exe" |
| dispatch.backgroundDispatch | false | https://github.com/nousresearch/hermes-agent/blob/main/website/docs/user-guide/features/delegation.md (via Context7 query of /nousresearch/hermes-agent) | "Nested delegation is an opt-in feature, requiring role=\"orchestrator\" for children and an increased max_spawn_depth from its default of 1. It can also be globally disabled with orchestrator_enabled |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://hermes-agent.nousresearch.com/docs/user-guide/features/delegation
@@ -317,6 +323,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://antigravity.google/docs/cli/features | "Capabilities: Subagents have full access to tools such as code search, file editing, terminal commands, and web searches to complete their assigned tasks." (#2096 EoS migration — the page is JS-rendered/blank on a static fetch; confirmed via headless-browser render) |
| dispatch.backgroundDispatch | undocumented | no authoritative doc — Multiple sources consulted: antigravity.google/docs/cli-subagents (returned blank/JS-rendered), antigravity.google/docs/agent (blank), github.com/google-antigravity/antigravity-cli README, Context7 /google-antigravity/antigravity-cli | All documentation consulted describes a two-level orchestrator→subagent architecture. Background subagents run asynchronously while the main agent continues accepting prompts. The DataCamp tutorial st |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://github.com/alphaperseii3000/google-antigravity-docs/blob/master/google-antigravity-docs.md
@@ -356,6 +363,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://docs.augmentcode.com/cli/subagents | "If neither [tools nor disabled_tools] is specified, the subagent has access to all tools (default behavior)." |
| dispatch.backgroundDispatch | undocumented | no authoritative doc — https://docs.augmentcode.com/cosmos/automations | The Augment Code (Cosmos) docs describe workers as 'sub-agents launched mid-session by a manager Expert using the worker-launch command. Each worker is its own session with its own messages and permis |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://docs.augmentcode.com/cli/plugins
@@ -420,6 +428,7 @@ upgrade coverage is in `tests/augment-upgrades.test.cjs`.
| dispatch.subagentToolkit | full | https://qwenlm.github.io/qwen-code-docs/en/users/features/sub-agents/ | "When omitted, the subagent inherits all available tools from the parent session." |
| dispatch.backgroundDispatch | false | https://qwenlm.github.io/qwen-code-docs/en/users/features/sub-agents/ (official Qwen Code documentation, 'Subagents' user guide page) and https://qwenlm.github.io/qwen-code-docs/en/design/fork-subagent/fork-subagent-design (Qwen Code fork-subagent design document, section '4. Recursive Fork Prevention') | The official user-facing Qwen Code docs state verbatim: "Fork children cannot create further forks. If a fork attempts spawning another fork, it receives an error instructing direct task execution ins |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://qwenlm.github.io/qwen-code-docs/en/developers/channel-plugins
@@ -457,6 +466,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://www.codebuddy.ai/docs/cli/sub-agents | "By default, sub-agents inherit all tools when the tools field is omitted ... Sub-agents can access MCP tools from config" |
| dispatch.backgroundDispatch | false | https://www.codebuddy.ai/docs/cli/sub-agents | "This prevents infinite nesting of agents (sub-agents cannot spawn other sub-agents)" — the restriction is stated as universal in the Sub-Agents documentation page. The daemon/background docs (https:/ |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://www.codebuddy.ai/docs/cli/plugins
@@ -490,6 +500,7 @@ Sources consulted:
| dispatch.subagentToolkit | full | https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli | "By default, custom agents have access to all tools. If you restrict an agent's access, a tools specification is added" |
| dispatch.backgroundDispatch | false | https://code.visualstudio.com/docs/copilot/agents/subagents | "By default, subagents cannot spawn further subagents. This prevents infinite recursion when agents accidentally call themselves in a loop." The setting `chat.subagents.allowInvocationsFromSubagents` |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://github.com/github/copilot-cli/blob/main/README.md (via Context7 /github/copilot-cli)
@@ -526,6 +537,7 @@ Documentation gaps:
| dispatch.subagentToolkit | undocumented | no authoritative doc — searched: https://kilo.ai/docs/customize/custom-subagents | — |
| dispatch.backgroundDispatch | false | https://kilo.ai/docs/automate/tools/new-task | "Importantly, subagents cannot spawn further subagents; only primary agents can use the `new_task` tool." |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://kilo.ai/docs/automate/extending/plugins
@@ -564,6 +576,7 @@ Documentation gaps:
| dispatch.subagentToolkit | undocumented | no authoritative doc — searched: https://docs.devin.ai/cli/subagents.md | — |
| dispatch.backgroundDispatch | undocumented | no authoritative doc — https://docs.devin.ai/desktop/cascade/cascade and https://docs.devin.ai/desktop/devin-local (official Windsurf/Devin docs, via docs.windsurf.com redirects) | The Windsurf/Cascade docs describe a background planning agent only in these terms: "In the background, a specialized planning agent continuously refines the long-term plan while your selected model f |
| dispatch.isolation | none | shipped descriptor (`dispatch.backgroundDispatch: undocumented`) | no documented background/concurrent-dispatch primitive — isolation is moot; same-wave plans run inline (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://docs.devin.ai/desktop/cascade/workflows
@@ -606,6 +619,7 @@ Documentation gaps:
| dispatch.subagentToolkit | undocumented | no authoritative doc — searched: https://docs.trae.ai/ide/agent | — |
| dispatch.backgroundDispatch | undocumented | no authoritative doc — https://docs.trae.ai/ide/agent; https://github.com/bytedance/trae-agent/blob/main/docs/roadmap.md | Trae's official documentation (docs.trae.ai) and the trae-agent GitHub roadmap do not document background/async agent dispatch or whether a background-spawned agent can itself spawn further sub-agents |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://docs.trae.ai/ide/model-context-protocol
@@ -648,6 +662,7 @@ Documentation gaps:
| dispatch.subagentToolkit | undocumented | no authoritative doc — searched: https://moonshotai.github.io/kimi-cli/en/customization/agents.html | — |
| dispatch.backgroundDispatch | true (#2095 Upgrade 2; was `false`) | https://moonshotai.github.io/kimi-cli/en/customization/agents.html | "Subagents support foreground and background modes. The `run_in_background` parameter allows tasks to execute asynchronously" (same evidence as dispatch.background above — the root agent's `Agent` tool call itself takes the `run_in_background` param) |
| dispatch.isolation | orchestrator-worktree | https://github.com/moonshotai/kimi-cli/blob/main/docs/en/faq.md ; /docs/en/customization/agents.md | "`--work-dir` flag sets an explicit working directory"; concurrent "explore" subagents documented — GSD creates + manages the worktree and points the executor at it via `--work-dir` (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://moonshotai.github.io/kimi-cli/en/customization/hooks.html
@@ -688,6 +703,7 @@ Documentation gaps:
| dispatch.subagentToolkit | built-in-only | https://github.com/moonshotai/kimi-code/blob/main/docs/en/customization/agents.md | The three built-ins carry deliberately different tool surfaces — coder "Shares most of the main Agent's toolset; can run shell commands, maintain todo lists, enter Plan mode, and invoke Agent Skills"; explore "Performs read-only operations only and does not modify any files"; plan "Even shell commands are not available". No single `full`/`read-only` value covers the set, so the `built-in-only` member applies (degrades closed to `read-only` when negotiated). |
| dispatch.backgroundDispatch | true | https://github.com/moonshotai/kimi-code/blob/main/docs/en/reference/tools.md ; /docs/en/customization/agents.md | The `coder` built-in "can dispatch its own nested sub-agents" and the `Agent` tool's `run_in_background` is a call-time parameter available to it, so a background-dispatched sub-agent may itself dispatch further. `AgentSwarm` additionally fans out concurrently: "By default the tool ramps up concurrency without an upper limit (5 subagents start immediately, then 1 more every 700 ms); set `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` to a positive integer to cap how many subagents run at the same time during that ramp, or leave it unset for no cap." |
| dispatch.isolation | orchestrator-worktree | https://github.com/moonshotai/kimi-code/blob/main/docs/en/reference/tools.md ; ADR-1239 §Codex-binding amendment | Neither `Agent` nor `AgentSwarm` exposes a working-directory/cwd parameter — sub-agents inherit the CLI's process cwd — and the CLI has no `--work-dir`-style flag (unlike `kimi`). GSD therefore creates, validates and merges the worktree itself and spawns the executor with that cwd (#2584). |
| dispatch.maxConcurrency | undocumented | https://github.com/moonshotai/kimi-code/blob/main/docs/en/reference/tools.md | `AgentSwarm` concurrency is configurable ("set `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` to a positive integer to cap how many subagents run at the same time … or leave it unset for no cap") but the CLI states no bound as its OWN default — "By default the tool ramps up concurrency without an upper limit" — so there is no single default integer to cite, only a user-configurable env var (#3673). |
**Negotiation note.** Because `dispatch.namedDispatch` is `false`, `negotiateHostCapabilities` caps `nested`, `maxDepth`, `background` and `backgroundDispatch` to `false`/`0` in the **effective** axes for structural consistency (`src/host-integration.cts`). The declared values above are still the host-capability record the matrix exists to hold; they are what a future named-dispatch upgrade would negotiate against.
@@ -732,6 +748,7 @@ Documentation gaps:
| dispatch.subagentToolkit | full | https://zcode.z.ai/en/docs/subagents | "**general-purpose** is the default built-in subagent ... It has access to all tools"; custom subagents default to "All permissions by default" (inherits every tool). |
| dispatch.backgroundDispatch | false | https://zcode.z.ai/en/docs/subagents | "Background execution is not enabled yet" — background dispatch is therefore impossible. |
| dispatch.isolation | none | https://zcode.z.ai/en/docs/subagents (shipped descriptor: `dispatch.backgroundDispatch: false`) | "Background execution is not enabled yet" — no concurrent fan-out primitive, so same-wave plans run inline/sequentially (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://zcode.z.ai/en/docs/skill
@@ -774,6 +791,7 @@ EoS migration status (#2101, ADR-1239): ZCode's install is fully dogfooded throu
| dispatch.subagentToolkit | undocumented | no authoritative doc — searched: https://pi.dev/docs/latest/extensions | pi has no named-dispatch primitive (see `dispatch.namedDispatch`), so there is no subagent tool-surface to classify as `full`/`read-only`. |
| dispatch.backgroundDispatch | false | no authoritative doc — searched: https://pi.dev/docs/latest/extensions | Same gap as `dispatch.background` — no background-dispatch primitive is documented, so a background-dispatched agent spawning further named sub-agents is not possible. |
| dispatch.isolation | none | shipped descriptor (`dispatch.background: false`, `dispatch.backgroundDispatch: false`) | pi has no named-dispatch/background-dispatch primitive documented — cannot fan out concurrently, so isolation is moot (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://pi.dev
@@ -824,6 +842,7 @@ EoS migration status (#2102 Stage 2, ADR-1239): Stage 1's "in-process `gsd-core`
| dispatch.subagentToolkit | undocumented | no authoritative doc found at authoring time | VS Code's subagent documentation does not state whether a subagent's tool surface is restricted to read-only tools or the full set an extension registers; recorded `undocumented` (fails closed to `read-only` in negotiation) rather than guessed. |
| dispatch.backgroundDispatch | undocumented | no authoritative doc found at authoring time | Whether a background-dispatched subagent can itself spawn further NAMED subagents (the #853 discriminator) is not stated in the sources reviewed; recorded `undocumented` (fails closed to `false`) rather than guessed. |
| dispatch.isolation | undocumented | not researched / no concurrent fan-out documented for this axis | no authoritative source consulted for concurrent-executor isolation on this host — fails closed to `none` (sequential) in negotiation (#2584) |
| dispatch.maxConcurrency | undocumented | not researched / no documented concurrent-subagent capacity for this axis | no authoritative source consulted for concurrent-executor capacity on this host — fails closed to `1` in negotiation (#3673) |
Sources consulted:
- https://code.visualstudio.com/api/references/vscode-api

View File

@@ -27,7 +27,7 @@ value (or the `undocumented` sentinel):
|---|---|
| `embeddingMode` | `imperative` \| `declarative` |
| `commandSurface` | `slash-file` \| `slash-programmatic` \| `slash-toml` \| `palette` \| `prose-only` |
| `dispatch` | struct: `{ namedDispatch, nested, maxDepth, background, subagentToolkit, backgroundDispatch }` |
| `dispatch` | struct: `{ namedDispatch, nested, maxDepth, background, subagentToolkit, backgroundDispatch, isolation, maxConcurrency }` |
| `modelMode` | `active` \| `passive` |
| `hookBus` | `host` \| `engine` \| `none` |
| `stateIO` | `filesystem` \| `sandboxed-storage` \| `session-log-append` |
@@ -35,6 +35,19 @@ value (or the `undocumented` sentinel):
| `runtime` | `node` \| `bun` \| `sandboxed-web` \| `python` \| `go` \| `rust` \| `electron` \| `other` |
| `effortSurface` | `argv` \| `none` |
`dispatch.isolation` (`harness-worktree` \| `orchestrator-worktree` \| `none`, added #2584)
and `dispatch.maxConcurrency` (a positive integer, added #3673) are two dispatch
sub-fields with their own per-field fail-closed floors — unlike the other five
dispatch fields, they are not gated on `namedDispatch`. `dispatch.maxConcurrency`
degrades to `1` (strictly sequential) on anything other than a positive safe
integer (missing, the `undocumented` sentinel, zero, negative, fractional, an
unsafe integer, or a non-numeric type); there is no negotiated host/engine
reduction the way `maxDepth` has one — the resolved value passes through
unchanged. Its live transport (`GSD_DISPATCH_MAX_CONCURRENCY`) is read only at
the CLI query layer (`gsd-tools query dispatch-capacity`), never inside this
pure negotiation module, and takes precedence over the descriptor value, which
in turn takes precedence over the `1` fallback.
## Classification + negotiation
- `profileOf(axes)` → `'programmatic-cli'` \| `'declarative-cli'` \| `'ide'` \| `null`.