* fix(#2603): document kimi-code in the host-integration matrix; correct 3 inherited axes The matrix — ADR-1239's deployment source-of-truth — had a section for 18 of 19 installed runtimes but none for `kimi-code`, so its `hostIntegration` axes shipped with no citation and no evidence quote. Sourcing every axis independently against Kimi Code CLI's own docs (the issue's explicit requirement — `kimi` and `kimi-code` are distinct products) showed three values had been inherited from the Python `kimi` descriptor rather than sourced: - `embeddingMode` imperative -> declarative. Kimi Code plugins are a `kimi.plugin.json` manifest plus markdown Skills with no in-process programmatic API (docs/en/customization/plugins.md) — the same shape as `codex`. - `dispatch.nested` false -> true. The `coder` built-in "can dispatch its own nested sub-agents when a task decomposes naturally" (docs/en/customization/agents.md). The Python `kimi` CLI genuinely prohibits nesting; Kimi Code does not. - `dispatch.maxDepth` 1 -> "undocumented". Nesting is documented but no depth bound is published, so the fail-closed sentinel applies over a guessed integer. `dispatch.namedDispatch` deliberately stays `false`: GSD's kimi-code artifact layout installs Agent Skills only (no `agents` kind), so no named GSD subagent is registered with the host and `resolveDispatchType` maps every role onto coder/explore/plan. Flipping it would reintroduce the dispatch failure recorded in docs/migration/kimi-to-kimi-code.md. The matrix records the host-capability nuance under Documentation gaps instead. Behaviourally inert: `namedDispatch:false` already caps nested/maxDepth/background/ backgroundDispatch to false/0 in the effective axes (host-integration.cts:493-499), and the install adapter is not selected by `embeddingMode` (install.js:543 always uses the imperative adapter). The one visible effect is the curated profile pin, which moves programmatic-cli -> declarative-cli. Also fixes the axes legend, which omitted the `built-in-only` subagentToolkit member that has been in the closed vocabulary since kimi-code shipped. Same defect class and countermeasure as #2598: pin the corrected values and require the matrix to agree with the descriptor, because a descriptor/matrix disagreement is how the gap survived. Closes #2603 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QT3ibz5qJuDuGqpTGRYVGf * fix(#2603): report the maxDepth `undocumented` sentinel as a sentinel, not as malformed Surfaced by the orthogonal review of this change. `negotiateHostCapabilities` emits a sentinel-specific warning for every dispatch sub-axis carrying the documented `undocumented` value — namedDispatch, nested, background, subagentToolkit, backgroundDispatch, isolation — except `maxDepth`, which fell through to the numeric guard and reported `host dispatch.maxDepth is missing or not a number — treating as 0`. That message is indistinguishable from a genuinely malformed descriptor, so a correctly fail-closed descriptor reads as broken. Six shipped runtimes carry the sentinel here (antigravity, augment, opencode, trae, windsurf, zcode) and this PR's kimi-code correction adds a seventh, which is why it is fixed here rather than left in place. The numeric guard keeps firing for genuinely malformed values; both paths still degrade `effective.dispatch.maxDepth` closed to 0. Covered by three tests, including the boundary case that the sentinel carve-out must not swallow a real malformed value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QT3ibz5qJuDuGqpTGRYVGf * chore(#2603): backfill changeset PR number (#2687) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -454,6 +454,13 @@ function negotiateHostCapabilities(
|
||||
if (hostDispatch.isolation === 'undocumented') {
|
||||
warnings.push(`dispatch.isolation is undocumented — degraded closed (none)`);
|
||||
}
|
||||
if (hostDispatch.maxDepth === UNDOCUMENTED) {
|
||||
// #2603: maxDepth was the one dispatch sub-axis with no sentinel-specific
|
||||
// warning, so a descriptor carrying the documented fail-closed sentinel was
|
||||
// reported as `missing or not a number` — indistinguishable from a genuinely
|
||||
// malformed descriptor. Six shipped runtimes use the sentinel here.
|
||||
warnings.push(`dispatch.maxDepth is undocumented — degraded closed (0)`);
|
||||
}
|
||||
|
||||
effectiveNamedDispatch = (hostDispatch.namedDispatch === true) && engineDispatch.namedDispatch;
|
||||
effectiveNested = (hostDispatch.nested === true) && engineDispatch.nested;
|
||||
@@ -475,10 +482,14 @@ function negotiateHostCapabilities(
|
||||
? hostIso as DispatchIsolation
|
||||
: 'none';
|
||||
|
||||
// maxDepth: missing/non-number/non-finite → 0 + warning
|
||||
// maxDepth: missing/non-number/non-finite → 0 + warning. The documented
|
||||
// 'undocumented' sentinel also degrades to 0, but is reported by the
|
||||
// sentinel-specific warning above rather than as a malformed value (#2603).
|
||||
let hostMaxDepth: number;
|
||||
if (typeof hostDispatch.maxDepth !== 'number' || !Number.isFinite(hostDispatch.maxDepth)) {
|
||||
warnings.push(`host dispatch.maxDepth is missing or not a number — treating as 0`);
|
||||
if (hostDispatch.maxDepth !== UNDOCUMENTED) {
|
||||
warnings.push(`host dispatch.maxDepth is missing or not a number — treating as 0`);
|
||||
}
|
||||
hostMaxDepth = 0;
|
||||
} else {
|
||||
hostMaxDepth = hostDispatch.maxDepth;
|
||||
|
||||
Reference in New Issue
Block a user