kimi-plugin-cc 2.0.7

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 (190) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +16 -0
  3. package/.claude-plugin/plugin.json +32 -0
  4. package/CHANGELOG.md +1096 -0
  5. package/LICENSE +201 -0
  6. package/README.md +772 -0
  7. package/agents/kimi-ask.md +82 -0
  8. package/agents/kimi-challenge.md +82 -0
  9. package/agents/kimi-pursue.md +91 -0
  10. package/agents/kimi-rescue.md +85 -0
  11. package/agents/kimi-review.md +82 -0
  12. package/agents/kimi-swarm-write.md +92 -0
  13. package/agents/kimi-swarm.md +83 -0
  14. package/commands/README.md +16 -0
  15. package/commands/ask.md +32 -0
  16. package/commands/cancel.md +17 -0
  17. package/commands/challenge.md +29 -0
  18. package/commands/pursue.md +37 -0
  19. package/commands/replay.md +13 -0
  20. package/commands/rescue.md +32 -0
  21. package/commands/result.md +13 -0
  22. package/commands/review.md +29 -0
  23. package/commands/setup.md +23 -0
  24. package/commands/status.md +13 -0
  25. package/commands/swarm.md +38 -0
  26. package/dist/background-spawn.js +224 -0
  27. package/dist/cli-cancellation.js +43 -0
  28. package/dist/cli-client.js +845 -0
  29. package/dist/commands/ask.js +327 -0
  30. package/dist/commands/cancel.js +178 -0
  31. package/dist/commands/cli-helpers.js +112 -0
  32. package/dist/commands/models.js +140 -0
  33. package/dist/commands/not-implemented.js +4 -0
  34. package/dist/commands/pursue.js +311 -0
  35. package/dist/commands/registry.js +87 -0
  36. package/dist/commands/repair-sessions.js +159 -0
  37. package/dist/commands/replay.js +123 -0
  38. package/dist/commands/rescue.js +333 -0
  39. package/dist/commands/result.js +58 -0
  40. package/dist/commands/review-gate.js +393 -0
  41. package/dist/commands/review.js +218 -0
  42. package/dist/commands/setup.js +1132 -0
  43. package/dist/commands/status.js +27 -0
  44. package/dist/commands/swarm.js +576 -0
  45. package/dist/commands/worker.js +31 -0
  46. package/dist/companion.js +114 -0
  47. package/dist/config.js +22 -0
  48. package/dist/errors.js +40 -0
  49. package/dist/git.js +215 -0
  50. package/dist/hooks/approval-hook.js +112 -0
  51. package/dist/hooks/approval-policy.js +254 -0
  52. package/dist/hooks/config-safety.js +637 -0
  53. package/dist/hooks/install-paths.js +504 -0
  54. package/dist/hooks/install.js +281 -0
  55. package/dist/hooks/managed-block.js +745 -0
  56. package/dist/hooks/review-gate-stop.js +19 -0
  57. package/dist/job-store.js +559 -0
  58. package/dist/jobs.js +202 -0
  59. package/dist/kimi-command.js +72 -0
  60. package/dist/kimi-engine.js +624 -0
  61. package/dist/kimi-errors.js +220 -0
  62. package/dist/kimi-home.js +9 -0
  63. package/dist/kimi-timeouts.js +68 -0
  64. package/dist/kimi-version-probe.js +1410 -0
  65. package/dist/logging.js +22 -0
  66. package/dist/native-v2-preflight.js +417 -0
  67. package/dist/package.json +1 -0
  68. package/dist/parsing.js +553 -0
  69. package/dist/paths.js +27 -0
  70. package/dist/plugin-data.js +98 -0
  71. package/dist/process-tree.js +448 -0
  72. package/dist/render.js +159 -0
  73. package/dist/rescue-approval.js +951 -0
  74. package/dist/schemas/review-gate-output.js +43 -0
  75. package/dist/session-title.js +293 -0
  76. package/dist/stream-json.js +498 -0
  77. package/dist/types.js +1 -0
  78. package/dist/vendor/shell-quote/LICENSE +24 -0
  79. package/dist/vendor/shell-quote/index.js +1 -0
  80. package/dist/vendor/shell-quote/parse.js +229 -0
  81. package/dist/vendor/smol-toml/LICENSE +24 -0
  82. package/dist/vendor/smol-toml/date.js +127 -0
  83. package/dist/vendor/smol-toml/error.js +63 -0
  84. package/dist/vendor/smol-toml/extract.js +100 -0
  85. package/dist/vendor/smol-toml/parse.js +148 -0
  86. package/dist/vendor/smol-toml/primitive.js +179 -0
  87. package/dist/vendor/smol-toml/struct.js +184 -0
  88. package/dist/vendor/smol-toml/util.js +113 -0
  89. package/dist/version.js +7 -0
  90. package/docs/migration.md +215 -0
  91. package/docs/models.md +82 -0
  92. package/docs/registry-releases.md +70 -0
  93. package/docs/safety.md +318 -0
  94. package/docs/session-visibility.md +32 -0
  95. package/hooks/README.md +9 -0
  96. package/hooks/hooks.json +16 -0
  97. package/package.json +67 -0
  98. package/plugins/kimi-codex/.codex-plugin/plugin.json +39 -0
  99. package/plugins/kimi-codex/dist/background-spawn.js +224 -0
  100. package/plugins/kimi-codex/dist/cli-cancellation.js +43 -0
  101. package/plugins/kimi-codex/dist/cli-client.js +845 -0
  102. package/plugins/kimi-codex/dist/commands/ask.js +327 -0
  103. package/plugins/kimi-codex/dist/commands/cancel.js +178 -0
  104. package/plugins/kimi-codex/dist/commands/cli-helpers.js +112 -0
  105. package/plugins/kimi-codex/dist/commands/models.js +140 -0
  106. package/plugins/kimi-codex/dist/commands/not-implemented.js +4 -0
  107. package/plugins/kimi-codex/dist/commands/pursue.js +311 -0
  108. package/plugins/kimi-codex/dist/commands/registry.js +87 -0
  109. package/plugins/kimi-codex/dist/commands/repair-sessions.js +159 -0
  110. package/plugins/kimi-codex/dist/commands/replay.js +123 -0
  111. package/plugins/kimi-codex/dist/commands/rescue.js +333 -0
  112. package/plugins/kimi-codex/dist/commands/result.js +58 -0
  113. package/plugins/kimi-codex/dist/commands/review-gate.js +393 -0
  114. package/plugins/kimi-codex/dist/commands/review.js +218 -0
  115. package/plugins/kimi-codex/dist/commands/setup.js +1132 -0
  116. package/plugins/kimi-codex/dist/commands/status.js +27 -0
  117. package/plugins/kimi-codex/dist/commands/swarm.js +576 -0
  118. package/plugins/kimi-codex/dist/commands/worker.js +31 -0
  119. package/plugins/kimi-codex/dist/companion.js +114 -0
  120. package/plugins/kimi-codex/dist/config.js +22 -0
  121. package/plugins/kimi-codex/dist/errors.js +40 -0
  122. package/plugins/kimi-codex/dist/git.js +215 -0
  123. package/plugins/kimi-codex/dist/hooks/approval-hook.js +112 -0
  124. package/plugins/kimi-codex/dist/hooks/approval-policy.js +254 -0
  125. package/plugins/kimi-codex/dist/hooks/config-safety.js +637 -0
  126. package/plugins/kimi-codex/dist/hooks/install-paths.js +504 -0
  127. package/plugins/kimi-codex/dist/hooks/install.js +281 -0
  128. package/plugins/kimi-codex/dist/hooks/managed-block.js +745 -0
  129. package/plugins/kimi-codex/dist/hooks/review-gate-stop.js +19 -0
  130. package/plugins/kimi-codex/dist/job-store.js +559 -0
  131. package/plugins/kimi-codex/dist/jobs.js +202 -0
  132. package/plugins/kimi-codex/dist/kimi-command.js +72 -0
  133. package/plugins/kimi-codex/dist/kimi-engine.js +624 -0
  134. package/plugins/kimi-codex/dist/kimi-errors.js +220 -0
  135. package/plugins/kimi-codex/dist/kimi-home.js +9 -0
  136. package/plugins/kimi-codex/dist/kimi-timeouts.js +68 -0
  137. package/plugins/kimi-codex/dist/kimi-version-probe.js +1410 -0
  138. package/plugins/kimi-codex/dist/logging.js +22 -0
  139. package/plugins/kimi-codex/dist/native-v2-preflight.js +417 -0
  140. package/plugins/kimi-codex/dist/package.json +1 -0
  141. package/plugins/kimi-codex/dist/parsing.js +553 -0
  142. package/plugins/kimi-codex/dist/paths.js +27 -0
  143. package/plugins/kimi-codex/dist/plugin-data.js +98 -0
  144. package/plugins/kimi-codex/dist/process-tree.js +448 -0
  145. package/plugins/kimi-codex/dist/render.js +159 -0
  146. package/plugins/kimi-codex/dist/rescue-approval.js +951 -0
  147. package/plugins/kimi-codex/dist/schemas/review-gate-output.js +43 -0
  148. package/plugins/kimi-codex/dist/session-title.js +293 -0
  149. package/plugins/kimi-codex/dist/stream-json.js +498 -0
  150. package/plugins/kimi-codex/dist/types.js +1 -0
  151. package/plugins/kimi-codex/dist/vendor/shell-quote/LICENSE +24 -0
  152. package/plugins/kimi-codex/dist/vendor/shell-quote/index.js +1 -0
  153. package/plugins/kimi-codex/dist/vendor/shell-quote/parse.js +229 -0
  154. package/plugins/kimi-codex/dist/vendor/smol-toml/LICENSE +24 -0
  155. package/plugins/kimi-codex/dist/vendor/smol-toml/date.js +127 -0
  156. package/plugins/kimi-codex/dist/vendor/smol-toml/error.js +63 -0
  157. package/plugins/kimi-codex/dist/vendor/smol-toml/extract.js +100 -0
  158. package/plugins/kimi-codex/dist/vendor/smol-toml/parse.js +148 -0
  159. package/plugins/kimi-codex/dist/vendor/smol-toml/primitive.js +179 -0
  160. package/plugins/kimi-codex/dist/vendor/smol-toml/struct.js +184 -0
  161. package/plugins/kimi-codex/dist/vendor/smol-toml/util.js +113 -0
  162. package/plugins/kimi-codex/dist/version.js +7 -0
  163. package/plugins/kimi-codex/scripts/companion.sh +37 -0
  164. package/plugins/kimi-codex/scripts/review-gate-hook.sh +32 -0
  165. package/plugins/kimi-codex/skills/kimi-ask/SKILL.md +31 -0
  166. package/plugins/kimi-codex/skills/kimi-ask/agents/openai.yaml +6 -0
  167. package/plugins/kimi-codex/skills/kimi-cancel/SKILL.md +25 -0
  168. package/plugins/kimi-codex/skills/kimi-cancel/agents/openai.yaml +6 -0
  169. package/plugins/kimi-codex/skills/kimi-challenge/SKILL.md +31 -0
  170. package/plugins/kimi-codex/skills/kimi-challenge/agents/openai.yaml +6 -0
  171. package/plugins/kimi-codex/skills/kimi-pursue/SKILL.md +30 -0
  172. package/plugins/kimi-codex/skills/kimi-pursue/agents/openai.yaml +6 -0
  173. package/plugins/kimi-codex/skills/kimi-replay/SKILL.md +25 -0
  174. package/plugins/kimi-codex/skills/kimi-replay/agents/openai.yaml +6 -0
  175. package/plugins/kimi-codex/skills/kimi-rescue/SKILL.md +30 -0
  176. package/plugins/kimi-codex/skills/kimi-rescue/agents/openai.yaml +6 -0
  177. package/plugins/kimi-codex/skills/kimi-result/SKILL.md +25 -0
  178. package/plugins/kimi-codex/skills/kimi-result/agents/openai.yaml +6 -0
  179. package/plugins/kimi-codex/skills/kimi-review/SKILL.md +31 -0
  180. package/plugins/kimi-codex/skills/kimi-review/agents/openai.yaml +6 -0
  181. package/plugins/kimi-codex/skills/kimi-setup/SKILL.md +32 -0
  182. package/plugins/kimi-codex/skills/kimi-setup/agents/openai.yaml +6 -0
  183. package/plugins/kimi-codex/skills/kimi-status/SKILL.md +25 -0
  184. package/plugins/kimi-codex/skills/kimi-status/agents/openai.yaml +6 -0
  185. package/plugins/kimi-codex/skills/kimi-swarm/SKILL.md +31 -0
  186. package/plugins/kimi-codex/skills/kimi-swarm/agents/openai.yaml +6 -0
  187. package/plugins/kimi-codex/skills/kimi-swarm-write/SKILL.md +32 -0
  188. package/plugins/kimi-codex/skills/kimi-swarm-write/agents/openai.yaml +6 -0
  189. package/scripts/companion.sh +37 -0
  190. package/scripts/review-gate-hook.sh +32 -0
@@ -0,0 +1,1410 @@
1
+ // Probe the installed kimi-code CLI version and check it against the
2
+ // range kimi-plugin-cc has been tested against.
3
+ //
4
+ // Why this exists (H6, Codex post-hotfix audit Area 8):
5
+ //
6
+ // kimi-code 0.2.0 introduced wire protocol 1.1 and a new "warn-and-
7
+ // replay" code path for sessions from newer protocol versions. A
8
+ // future 0.3.0 could replay an older session with an invisible warning
9
+ // and produce flattened output that silently differs from what our
10
+ // plugin captured originally — see PR #49 (cf2227e) and PR #22
11
+ // (2004aed) in the 0.2.0 changeset. The alpha.5 hotfix exists because
12
+ // *this exact failure mode already happened once* (kimi-code 0.2.0
13
+ // moved the session resume hint from stderr to a stream-json meta
14
+ // record, and our plugin captured nothing until we noticed).
15
+ //
16
+ // The defensible posture has two consumers: setup probes the installed
17
+ // command and warns outside the tested range; model jobs probe the exact
18
+ // command + prefix tuple to build a fail-closed execution plan before spawn.
19
+ // The latter is the durable engine-provenance gate: an operation outside its
20
+ // certified engine/version range is refused rather than guessed.
21
+ //
22
+ // This is belt-and-suspenders for the alpha.4 `warnIfSessionIdMissing`
23
+ // surface: that warning fires when capture demonstrably fails on a
24
+ // completed job; this one fires before any job runs, on the theory
25
+ // that "you're running a kimi-code we haven't tested" is worth knowing
26
+ // even if the first job happens to work.
27
+ //
28
+ // What this module is NOT:
29
+ //
30
+ // - Not, by itself, the policy decision. setup still warns; the execution-
31
+ // plan layer (`kimi-engine.ts`) decides whether an exact result is certified.
32
+ // - Not a substitute for upstream compatibility testing. The right
33
+ // long-term answer is for kimi-code to advertise wire-protocol
34
+ // compatibility via a stable feature flag or version field in its
35
+ // stream-json output. Until upstream lands that, this is the best
36
+ // signal we can give users.
37
+ // - Not a license to infer historical versions. Old job rows remain unknown
38
+ // unless their saved logs contain positive evidence.
39
+ import { spawn } from "node:child_process";
40
+ /** Maximum time to wait for `kimi --version` to print and exit. */
41
+ const KIMI_VERSION_PROBE_TIMEOUT_MS = 5_000;
42
+ /**
43
+ * The range of kimi-code package versions kimi-plugin-cc has been
44
+ * actively tested against. Bump these when a new kimi-code release is
45
+ * verified to work end-to-end (production smoke + full test suite).
46
+ *
47
+ * Versions are matched as `<major>.<minor>` pairs — patch versions are
48
+ * always accepted within a known minor. A version of `0.2.5` is
49
+ * considered tested if `{0, 2}` is in this set.
50
+ *
51
+ * Why store as `{major, minor}` and not a semver range string: avoids a
52
+ * semver parser dependency for a one-off comparison, and the range
53
+ * shape is naturally tied to kimi-code's own release cadence (0.x
54
+ * pre-1.0, minor bumps for behavioral change).
55
+ */
56
+ export const KIMI_TESTED_MINORS = [
57
+ { major: 0, minor: 1 },
58
+ { major: 0, minor: 2 },
59
+ // 0.3 and 0.4 added in v1.0.1 (2026-05-27) after the 4-reviewer audit
60
+ // verified compat through @moonshot-ai/kimi-code@0.4.0. See
61
+ // docs/upstream-compat-audit.md for the playbook and
62
+ // .claude/kimi-code-research/reports/31-35-* for the audit reports.
63
+ // Tag: compat-verified-kimi-code-0.4.0 on commit b67263c.
64
+ { major: 0, minor: 3 },
65
+ { major: 0, minor: 4 },
66
+ // 0.5 added in v1.0.2 (2026-05-28) after a same-day 4-reviewer audit
67
+ // verified compat through @moonshot-ai/kimi-code@0.5.0. The hook
68
+ // engine moved path (agent/hooks/ → session/hooks/) but is
69
+ // byte-identical; run-prompt.ts and rpc/events.ts are byte-identical;
70
+ // the new --auto CLI flag is rejected when combined with -p. See
71
+ // .claude/kimi-code-research/reports/36-40-* for the audit reports.
72
+ // Tag: compat-verified-kimi-code-0.5.0.
73
+ { major: 0, minor: 5 },
74
+ // 0.6 added in v1.0.4 (2026-05-31) after a 4-reviewer audit verified
75
+ // compat through @moonshot-ai/kimi-code@0.6.0, backed by a GREEN
76
+ // real-binary smoke (`bun run smoke:real`) against the installed 0.6.0
77
+ // binary — "tested" is earned end-to-end, not source-reading-only. The
78
+ // hook engine (session/hooks/), policy queue order (policies/index.ts),
79
+ // and CLI argv (options.ts/commands.ts) are byte-identical; the
80
+ // stream-json resume-hint writer is byte-identical. The +17-line
81
+ // run-prompt.ts change is a resume-session workDir guard that runs
82
+ // before permission forcing and cannot fire for the plugin (we always
83
+ // resume from the originating cwd). The permission/index.ts
84
+ // `rpc?.requestApproval` refactor is dead code in -p mode (shadowed by
85
+ // auto-mode-approve at index 4; the hook policy is index 0;
86
+ // requestApproval is always present). See
87
+ // .claude/kimi-code-research/reports/47-51-* for the
88
+ // audit reports. Tag: compat-verified-kimi-code-0.6.0.
89
+ { major: 0, minor: 6 },
90
+ // 0.7 / 0.8 / 0.9 added in v1.0.5 (2026-06-03) after a 4-reviewer audit
91
+ // + an independent cross-model (codex) adversarial pass certified compat
92
+ // through @moonshot-ai/kimi-code@0.9.0, backed by a GREEN real-binary
93
+ // smoke (`bun run smoke:real`) against BOTH the installed 0.8.0 binary
94
+ // and a temp-installed 0.9.0 binary (KIMI_PLUGIN_CC_KIMI_BIN override) —
95
+ // "tested" is earned end-to-end on 0.9.0, not source-reading-only. This
96
+ // was a 3-minor catch-up (61 commits). The safety chain is intact:
97
+ // PreToolCallHookPermissionPolicy is still index 0 (auto-approve index 4);
98
+ // the hook engine (session/hooks/engine.ts, runner.ts) and the
99
+ // policy/stream-json writers are byte-identical 0.6.0→0.9.0. The notable
100
+ // 0.7–0.9 additions are all compat-benign for a `kimi -p` wrapper:
101
+ // - Permission approval hooks (PermissionRequest/PermissionResult, #336)
102
+ // are fire-and-forget OBSERVABILITY (fireAndForgetTrigger + void) that
103
+ // fire only in the rpc.requestApproval/ask branch — dead in -p auto
104
+ // mode (shadowed by auto-mode-approve), cannot deny.
105
+ // - Headless goal mode (kimi -p "/goal ...", #270) is double-gated:
106
+ // experimental flag goal-command (default false, env
107
+ // KIMI_CODE_EXPERIMENTAL_GOAL_COMMAND) AND a /goal-prefixed prompt.
108
+ // The plugin's read-only and rescue commands set no
109
+ // KIMI_CODE_EXPERIMENTAL_* env and never send /goal. (The v1.1
110
+ // /kimi:pursue command intentionally opts into goal-command per-job
111
+ // and sends /goal, but every tool call still passes the index-0
112
+ // PreToolUse hook on every continuation turn — see docs/safety.md.)
113
+ // - The new deny-all policy is unshift-ed only onto SUBAGENT policy
114
+ // stacks (a deny, more restrictive) — never the main -p agent.
115
+ // - New default-approved goal tools (GetGoal/SetGoalBudget/UpdateGoal)
116
+ // have no fs/git/config side effects; the plugin enforces read-only by
117
+ // allow-list (deny-by-default), so new upstream tools cannot slip
118
+ // through. CreateGoal is NOT auto-approved.
119
+ // - Background auto-upgrade (#334, default on) does not swap the binary
120
+ // for the plugin's own -p spawns (source forced 'unsupported'); the
121
+ // out-of-band drift it introduces is exactly what this probe catches.
122
+ // See .claude/kimi-code-research/reports/52-60 for the audit reports.
123
+ // Tag: compat-verified-kimi-code-0.9.0.
124
+ { major: 0, minor: 7 },
125
+ { major: 0, minor: 8 },
126
+ { major: 0, minor: 9 },
127
+ // 0.10 / 0.11 / 0.12 added in v1.1.1 (2026-06-09) after a 4-reviewer audit
128
+ // (+ adversarial pass) certified compat through @moonshot-ai/kimi-code@0.12.0,
129
+ // backed by a GREEN real-binary smoke against the installed 0.12.0 binary
130
+ // (review/challenge/ask/review_gate all hook-denied; the pursue goal-mode
131
+ // safety smoke wrote zero files across a full budget). The safety chain is
132
+ // intact: PreToolCallHookPermissionPolicy is still index 0 (auto-approve
133
+ // index 4); the hook engine (session/hooks/{engine,runner,types}.ts) and the
134
+ // stream-json writer are byte-identical 0.9.0→0.12.0 (03-hooks.diff is 0 bytes
135
+ // across all five tags). Notable 0.10–0.12 changes, all compat-benign for a
136
+ // `kimi -p` wrapper:
137
+ // - Goal-mode experimental gate REMOVED in 0.12.0 (#569, commit d7407b0):
138
+ // headless goal mode now triggers on the `/^\/goal(\s|$)/` prompt prefix
139
+ // ALONE — the KIMI_CODE_EXPERIMENTAL_GOAL_COMMAND env gate is gone (still
140
+ // present 0.9.0–0.11.0). This WEAKENS the old "double-gated" claim to a
141
+ // single gate, but the plugin never relied on the env gate: read-only
142
+ // commands hard-prefix an English instruction line so their trimmed
143
+ // prompt never starts with `/goal` (cannot enter goal mode), and the
144
+ // index-0 hook denies every write regardless. /kimi:pursue still sets the
145
+ // env var per-spawn — now redundant on 0.12 but harmless (unknown
146
+ // experimental flag ids resolve to undefined) and still required on
147
+ // 0.8–0.11.
148
+ // - AgentSwarm tool + swarm mode (#424): the new swarm-approve policy sits
149
+ // at index ~14 (below hook(0)/auto-approve(4)), is approve-only and
150
+ // double-guarded, and swarmMode.enter() runs INSIDE the tool's execute()
151
+ // (after the index-0 hook already gated the AgentSwarm call). Swarm
152
+ // subagents use the STANDARD permission stack (hook at index 0, NO
153
+ // deny-all): the lone DenyAllPermissionPolicy.unshift in subagent-host.ts
154
+ // is inside startBtw() (the side-question/"btw" path), NOT the swarm spawn
155
+ // path (re-verified against the 0.18.0 checkout 2026-06-20 during the v1.4
156
+ // write-swarm build — earlier notes here mis-cited it as "inherit
157
+ // deny-all"). So a `coder` swarm subagent's write IS gated solely by our
158
+ // index-0 hook — which is exactly what makes /kimi:swarm --write possible.
159
+ // - New `doctor` subcommand + a `program.argument('[args...]')` unknown-
160
+ // positional error: both unreachable — the plugin passes the prompt as
161
+ // the VALUE of `-p, --prompt`, never a bare positional.
162
+ // See .claude/kimi-code-research/reports/61-65 for the audit reports.
163
+ // Tag: compat-verified-kimi-code-0.12.0.
164
+ { major: 0, minor: 10 },
165
+ { major: 0, minor: 11 },
166
+ { major: 0, minor: 12 },
167
+ // 0.13 / 0.14 added in v1.2.3 (2026-06-12) after a 4-reviewer audit
168
+ // (+ adversarial pass) certified compat through @moonshot-ai/kimi-code@0.14.1,
169
+ // backed by a GREEN real-binary smoke against the installed 0.14.1 binary
170
+ // (review/challenge/ask/review_gate all hook-denied; pursue goal-mode wrote
171
+ // zero files across a multi-turn budget; the swarm smoke confirmed a spawned
172
+ // swarm subagent's forced write is hook-denied). The safety chain is intact:
173
+ // - The hook engine (session/hooks/{engine,runner}.ts) and the
174
+ // pre-tool-call-hook.ts policy are byte-identical 0.12.0→0.14.1; the only
175
+ // change under session/hooks/ is an additive `Interrupt` event type
176
+ // (types.ts), inert for a PreToolUse-only consumer.
177
+ // - The stream-json writer (writeResumeHint/PromptJsonWriter) and the
178
+ // records/ dir are byte-identical; the goal.summary shape is unchanged
179
+ // (smoke parsed turnsUsed/tokensUsed/goalId cleanly on 0.14.1).
180
+ // - CLI argv (options.ts/commands.ts) is byte-identical 0.12.0→0.14.1.
181
+ // PreToolCallHookPermissionPolicy is STILL index 0. Two permission-stack
182
+ // changes, both compat-benign:
183
+ // - NEW AgentSwarmExclusiveDenyPermissionPolicy at index 1 (#643):
184
+ // a pure DENY that fires only on multi/mixed-AgentSwarm batches
185
+ // ("first non-undefined wins" → it can never pre-empt the index-0 hook).
186
+ // It enforces "one AgentSwarm per response, alone in its batch" — a
187
+ // behavioral refinement for /kimi:swarm coordinators, not a write surface.
188
+ // - REMOVED CwdOutsideFileWriteAskPermissionPolicy: this was an `ask`
189
+ // policy sitting AFTER auto-mode-approve, so it was already dead in `-p`
190
+ // auto mode. Its removal opens zero new write surface — the plugin owns
191
+ // workspace confinement via rescue-approval.ts, never kimi's cwd-ask.
192
+ // NB: the new index-1 deny shifts AutoModeApprovePermissionPolicy from
193
+ // index 4 (its position 0.6.0–0.12.0) to index 5 in 0.14.1. The STRUCTURAL
194
+ // invariant is unchanged — every policy between the index-0 hook and the
195
+ // first approve is a DENY, so nothing approves before the hook denies.
196
+ // Other 0.13/0.14 additions are off our `-p` path: a new packages/protocol/
197
+ // REST+WebSocket control API (a separate transport — run-prompt.ts does not
198
+ // import it; `-p` stdout stays the direct PromptJsonWriter), session-lifecycle
199
+ // changes that only HELP our cancellation story (active-turn cancel on close +
200
+ // BACKGROUND_KEEP_ALIVE_ON_EXIT default flipped true→false), an `alwaysThinking`
201
+ // model-capability flag (read-only detection, the H5 thinking-control knob is
202
+ // still upstream-blocked), a SIGHUP cleanup handler (exit 129; SIGTERM still
203
+ // exits 143 and runs cleanup — our SIGTERM→SIGKILL reaping is unaffected), and
204
+ // a new builtin `import-from-cc-codex` skill (not a plugin surface).
205
+ // See .claude/kimi-code-research/reports/72-76 for the audit reports.
206
+ // Tag: compat-verified-kimi-code-0.14.1.
207
+ { major: 0, minor: 13 },
208
+ { major: 0, minor: 14 },
209
+ // 0.14.2 (patch, 2026-06-13) verified COMPAT-PRESERVED within the already-
210
+ // listed {0,14} — no array change needed (membership is minor-level).
211
+ // The 0.14.1→0.14.2 diff leaves our surfaces 0-byte: the permission policy
212
+ // queue (PreToolCallHookPermissionPolicy still index 0), the hook engine
213
+ // (session/hooks/), and the stream-json writer + records/ are all unchanged,
214
+ // and the AgentSwarm tool name is unchanged. The patch is a repo-wide
215
+ // `.md`→`.md?raw` bundler-import migration + a Bash-tool stdout/stderr
216
+ // streaming `onUpdate` callback (observability; approval path untouched) + a
217
+ // run-prompt.ts config-diagnostics line written to STDERR (humans-only) +
218
+ // removal of three `!promptMode`-gated CLI conflict checks (dead in `-p`).
219
+ // Backed by a GREEN `bun run smoke:real` on the operator's auto-upgraded
220
+ // 0.14.2 binary (review/challenge/ask/review_gate hook-denied; pursue
221
+ // goal-mode wrote zero files; swarm subagent write hook-denied).
222
+ // Tag: compat-verified-kimi-code-0.14.2.
223
+ // 0.14.3 (patch, 2026-06-14) verified COMPAT-PRESERVED within the already-
224
+ // listed {0,14} — no array change needed. All four scoped diffs
225
+ // (@moonshot-ai/kimi-code@0.14.2..0.14.3) are 0-byte: run-prompt.ts +
226
+ // options.ts/commands.ts, the permission policy queue
227
+ // (PreToolCallHookPermissionPolicy still index 0), the hook engine, and
228
+ // records/ + session/. The entire patch is one TUI change — PR #713,
229
+ // "Refresh provider model metadata before opening the model picker": the
230
+ // interactive `/model` slash command (tui/commands/config.ts +
231
+ // dispatch.ts) now calls a new `refreshOAuthProviderModels()` (a scoped
232
+ // 'oauth' variant added to tui/controllers/auth-flow.ts +
233
+ // tui/utils/refresh-providers.ts) with a 2s timeout before opening the
234
+ // picker. None of it is on the `-p` headless path (refreshAllProviderModels
235
+ // is invoked only from the TUI auth-flow controller; the sole reference
236
+ // outside tui/ is a JSDoc mention in cli/sub/provider.ts, the `kimi
237
+ // provider` subcommand we never invoke, which doesn't call it; the new
238
+ // `scope` param is optional, defaulting to 'all'). Backed by a GREEN `bun run
239
+ // smoke:real` on the operator's 0.14.3 binary (7 pass / 0 fail;
240
+ // review/challenge/ask/review_gate hook-denied; pursue goal-mode wrote
241
+ // zero files; swarm subagent write hook-denied).
242
+ // Tag: compat-verified-kimi-code-0.14.3.
243
+ // 0.15 (new minor, 2026-06-16) verified COMPAT-PRESERVED — added to the
244
+ // tested set because crossing the 0.14→0.15 minor boundary fired the H9
245
+ // "newer than tested max" probe warning (the operator's binary auto-upgraded
246
+ // to 0.15.0 out-of-band, PR #334 drift). All four scoped diffs
247
+ // (@moonshot-ai/kimi-code@0.14.3..0.15.0) leave our load-bearing surfaces
248
+ // 0-byte, re-confirmed independently by `git diff` byte-count (not just
249
+ // report 78): permission/ (PreToolCallHookPermissionPolicy STILL index 0,
250
+ // AgentSwarmExclusiveDenyPermissionPolicy still index 1), the hook engine
251
+ // (agent + session hooks/), run-prompt.ts, and cli commands.ts/options.ts.
252
+ // The only changed scoped surface is records/ + session/ (~5.3 KB), all
253
+ // internal persistence/plumbing off the -p path: PR #786 drops
254
+ // app_version/resumed from the persisted .records/ metadata artifact (NOT
255
+ // the -p stdout stream — that writer is the byte-identical PromptJsonWriter),
256
+ // a SessionSkillRegistry rename (#784), and a static model-capability lookup
257
+ // (#776). 0.15.0 also adds an ADDITIVE `transport:'sse'` MCP config variant
258
+ // (config/schema.ts) the plugin never writes, plus TUI/system-prompt churn.
259
+ // Backed by a GREEN `bun run smoke:real` on the operator's 0.15.0 binary
260
+ // (report 78: 7 pass / 0 fail; review/challenge/ask/review_gate hook-denied;
261
+ // pursue goal-mode wrote zero files, goal.summary parsed cleanly
262
+ // turnsUsed:2 tokensUsed:51199; swarm subagent write hook-denied).
263
+ // See .claude/kimi-code-research/reports/78-upstream-0150-surface.md.
264
+ // Tag: compat-verified-kimi-code-0.15.0.
265
+ { major: 0, minor: 15 },
266
+ // 0.16 (new minor, 2026-06-17) verified COMPAT-PRESERVED — the operator's
267
+ // binary auto-upgraded 0.15.0→0.16.0 within a day (PR #334 drift), re-firing
268
+ // the H9 "newer than tested max" probe warning. permission/, the hook engine
269
+ // (agent + session hooks/), and run-prompt.ts are 0-byte vs 0.15.0
270
+ // (independent `git diff` byte-count). The only CLI argv change registers a
271
+ // new `kimi vis` subcommand (a visualization server) — off the -p path; our
272
+ // -p/-r/--output-format/-m/--skills-dir flags are untouched. The records/ +
273
+ // session/ + replay/ + agent/ changes (a compaction refactor, a new
274
+ // llm-request-logger, replay-build additions) are internal and off the -p
275
+ // stdout stream our parser reads. Backed by a GREEN `bun run smoke:real` on
276
+ // the operator's 0.16.0 binary (7 pass / 0 fail; review/challenge/ask/
277
+ // review_gate hook-denied; pursue goal-mode wrote zero files, goal.summary
278
+ // parsed cleanly turnsUsed:2 tokensUsed:52211; swarm subagent write denied).
279
+ // Tag: compat-verified-kimi-code-0.16.0.
280
+ { major: 0, minor: 16 },
281
+ // 0.17 / 0.18 added in v1.2.6 (2026-06-19) — the 0.16.0→0.18.0 jump
282
+ // (0.17.0/0.17.1/0.18.0) verified COMPAT-PRESERVED by a reproduced
283
+ // source-level audit. The operator's binary auto-upgraded past the tested
284
+ // 0.16 max (PR #334 drift), firing the H9 "newer than tested max" probe
285
+ // warning. The safety chain is intact:
286
+ // - 03-hooks.diff is 0 bytes (BOTH agent/hooks/ AND session/hooks/) and
287
+ // pre-tool-call-hook.ts is 0-byte 0.16.0→0.18.0 — the hook engine and the
288
+ // policy that wires our PreToolUse hook in are byte-identical.
289
+ // - PreToolCallHookPermissionPolicy is STILL index 0,
290
+ // AgentSwarmExclusiveDenyPermissionPolicy still index 1, and
291
+ // AutoModeApprovePermissionPolicy still index 5 (the first approve; every
292
+ // policy between the index-0 hook and it is a DENY). The ONLY permission
293
+ // change is a NEW GoalStartReviewAskPermissionPolicy (#839, "guided goal
294
+ // authoring") inserted at index ~10 (AFTER auto-mode-approve): an `ask`
295
+ // gated to a MODEL-ISSUED CreateGoal in NON-auto mode (it returns early
296
+ // when permission.mode === 'auto'), so it is triple-dead on the `-p` auto
297
+ // path and is an `ask` that cannot approve a write. It does not affect
298
+ // /kimi:pursue, which uses the /goal COMMAND path, runs auto, and is
299
+ // governed by the index-0 hook on every turn.
300
+ // - options.ts is BYTE-IDENTICAL (argv intact: -p/-r/--output-format/-m/
301
+ // --skills-dir; --auto/--yolo/--plan still rejected with -p). run-prompt.ts
302
+ // changes ONLY in a telemetry refactor (the `started` event moved into
303
+ // harness `sessionStartedProperties`); the permission-forcing chain
304
+ // (permission:'auto', forcePromptPermission, installHeadlessHandlers) and
305
+ // the stream-json writer (PromptJsonWriter/resume_hint/goal.summary) are
306
+ // unchanged.
307
+ // Off-path additions (all benign for a `kimi -p` wrapper):
308
+ // - A new `kimi server`/`kimi web` subcommand stack (#625, "Kimi web app +
309
+ // daemon gateway") — like `vis`/`doctor`, never invoked; the plugin passes
310
+ // the prompt as the VALUE of `-p`, never a bare positional.
311
+ // - Session ARCHIVE (#625): an `archived` flag + archive()/includeArchive in
312
+ // the session store + rpc core-api (the surface the Kimi web UI lists/
313
+ // archives sessions through). The plugin owns its OWN SQLite job store and
314
+ // never reads kimi's session list — off our path.
315
+ // - OAuth-error fidelity (provider-manager throws the original error instead
316
+ // of re-wrapping every failure as loginRequired) — off the -p stdout shape;
317
+ // an expired token still surfaces as auth.login_required (the smoke's
318
+ // operator-auth false-alarm note in docs/upstream-compat-audit.md holds).
319
+ // - git-context process disposal + a turn-counter restore fix
320
+ // (records/index.ts, the record-RESTORE path) — both off the -p stdout
321
+ // stream our parser reads.
322
+ // - NEW in 0.18.0: KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY (#888) — an opt-in
323
+ // HARD cap on concurrent AgentSwarm subagents. /kimi:swarm now sets it from
324
+ // --cap (v1.2.6); older binaries ignore the unknown env var.
325
+ // SMOKE: the 0.16.0→0.18.0 source audit was prepared in a cloud session with
326
+ // no kimi binary, so its Phase 1b smoke was deferred. It was then run locally
327
+ // against the operator's installed 0.18.0 binary before merge — GREEN, 7 pass
328
+ // / 0 fail: review/challenge/ask/review_gate forced writes hook-denied; pursue
329
+ // multi-turn goal wrote zero files (`goal.summary` parsed cleanly turnsUsed:2);
330
+ // a spawned swarm subagent's forced write hook-denied. Six-reviewer + adversarial
331
+ // re-verification all returned CONFIRMED-SAFE (the new --cap → env wiring round-
332
+ // trips safely across 19 edge inputs; identical positive-integer validator).
333
+ // Tag: compat-verified-kimi-code-0.18.0.
334
+ { major: 0, minor: 17 },
335
+ { major: 0, minor: 18 },
336
+ // 0.19 (new minor, 2026-06-23) verified COMPAT-PRESERVED — added to the
337
+ // tested set in v1.5.1 because crossing the 0.18→0.19 minor fired the H9
338
+ // "newer than tested max" probe warning (the operator's binary auto-upgraded
339
+ // 0.18.0→0.19.1 out-of-band, PR #334 drift). Backed by a GREEN
340
+ // `bun run smoke:real` on the operator's 0.19.1 binary (9 pass / 0 fail):
341
+ // review/challenge/ask/review_gate forced writes hook-denied; pursue
342
+ // multi-turn goal wrote zero files (`goal.summary` parsed cleanly
343
+ // turnsUsed:2 tokensUsed:73631); a spawned read-only swarm subagent's forced
344
+ // write hook-denied; and BOTH write-swarm assertions held on 0.19.1 — a
345
+ // `coder` subagent's edits landed only in the throwaway worktree
346
+ // (patchBytes=306, userTreeClean=true) and an out-of-trusted-root absolute
347
+ // write was hook-denied. The safety chain is intact:
348
+ // - 03-hooks.diff is 0 bytes (BOTH agent/hooks/ AND session/hooks/) —
349
+ // the hook engine is byte-identical 0.18.0→0.19.1.
350
+ // - The permission policy queue (policies/index.ts) is BYTE-IDENTICAL:
351
+ // PreToolCallHookPermissionPolicy STILL index 0,
352
+ // AgentSwarmExclusiveDenyPermissionPolicy index 1,
353
+ // AutoModeApprovePermissionPolicy index 5 (first approve; every policy
354
+ // between the index-0 hook and it is a DENY). `permission:'auto'` is
355
+ // still hard-coded in run-prompt.ts createSession.
356
+ // The minor that bumped 0.18→0.19.0 is #812 "workspace add-dir support"
357
+ // (commit c0eeca2): a new repeatable --add-dir <dir> flag, additionalDirs
358
+ // plumbed through Session, and GitCwdWriteApprovePermissionPolicy widened to
359
+ // approve writes within cwd OR any additional dir. Compat-benign for the
360
+ // plugin — but NOT because additionalDirs is empty (see the CORRECTION
361
+ // below). The real reasons:
362
+ // - GitCwdWriteApprovePermissionPolicy is the ONLY permission consumer of
363
+ // additionalDirs (git-cwd-write-approve.ts:26 is the sole
364
+ // getAdditionalDirs() call in agent/permission/), and it sits at index 17
365
+ // — the last approve before FallbackAsk (the tail at index 18), BELOW
366
+ // AutoModeApprovePermissionPolicy (index 5). On the `-p` auto path
367
+ // auto-approve decides first for anything the index-0 hook did not deny,
368
+ // so GitCwdWriteApprove is STRUCTURALLY UNREACHABLE → its add-dir
369
+ // widening is dead for us regardless of what additionalDirs contains.
370
+ // - Read-only commands: the index-0 hook denies every write before any
371
+ // approve policy runs. Write commands (rescue/pursue/swarm-write): the
372
+ // index-0 hook confines to a SINGLE root via rescue-approval.ts, which
373
+ // never reads additionalDirs — the upstream widening cannot leak into our
374
+ // allowlist. The 0.19.1 smoke proves it empirically (write-swarm
375
+ // userTreeClean=true; an out-of-trusted-root write hook-denied).
376
+ // - isWithinWorkspace with additionalDirs=[] is byte-for-byte the old
377
+ // isWithinDirectory(cwd) (path-access.ts:159-163 checks workspaceDir then
378
+ // loops the list), so even in the non-`-p` modes where GitCwdWriteApprove
379
+ // DOES run, the empty-list case is unchanged.
380
+ // CORRECTION to an earlier mental model: additionalDirs is NOT guaranteed
381
+ // empty for a plugin `-p` spawn even with no --add-dir. #812 also wired an
382
+ // UNCONDITIONAL read of the project-local <root>/.kimi-code/local.toml
383
+ // `[workspace] additional_dir` into BOTH the -p create AND resume bootstraps
384
+ // (rpc/core-impl.ts:238 createSessionWithOverrides + :363
385
+ // resumeSessionWithOverrides, via config/workspace-local.ts; both ABSENT at
386
+ // 0.18.0). So getAdditionalDirs() can be non-empty whenever such a file
387
+ // exists in the repo — but per the reasons above that changes no approve/deny
388
+ // decision on our path. (Swarm `coder` subagents inherit the coordinator's
389
+ // additionalDirs; the same index-0 hook gating applies.)
390
+ // Other 0.18.0→0.19.1 changes are off the `-p` path: #963 (commit 4292ae9)
391
+ // adds a new `turn.ended` terminal `reason:'filtered'` (provider content
392
+ // filter) surfaced as a human string — a new failure REASON, not a new
393
+ // stdout record SHAPE, so the role-keyed stream-json parser is unaffected;
394
+ // #821 (detach-to-background) was already triaged in the forward-scans; and
395
+ // 0.19.1 over 0.19.0 is ci/ACP/kimi-web-UI only (0-byte load-bearing diff —
396
+ // its #992 `fix(acp)` only re-routes the workspace-local read's kaos handle).
397
+ // NEXT-AUDIT NOTE: the workspace-local additional_dir auto-load is LIVE on
398
+ // the -p path NOW (shipped 0.19.0/#812, not a future risk). It stays
399
+ // hook-bound for us, but the "plugin never passes --add-dir ⟹ additionalDirs
400
+ // empty" assumption is broken upstream — re-confirm each audit that the
401
+ // index-0 hook still pre-empts GitCwdWriteApprove, and consider a defensive
402
+ // assert/scrub if a future minor lets additionalDirs reach a policy ABOVE our
403
+ // hook. See .claude/kimi-code-research/reports/85-upstream-0191-surface.md.
404
+ // Tag: compat-verified-kimi-code-0.19.1.
405
+ { major: 0, minor: 19 },
406
+ // 0.20 (new minor, 2026-06-26) verified COMPAT-PRESERVED — the operator's
407
+ // binary auto-upgraded 0.19.2→0.20.0 (PR #334 drift), crossing the 0.19→0.20
408
+ // minor and firing the H9 "newer than tested max" probe warning. (npm went
409
+ // straight 0.19.2→0.20.0; no 0.19.3. 0.19.1→0.19.2 was already 0-byte on all
410
+ // load-bearing surfaces — report 86 — so the 0.19.1..0.20.0 diff below loses
411
+ // no signal.) The safety chain is intact, re-verified by `git diff … | wc -c`:
412
+ // - 02-permission.diff is 0 bytes AND 03-hooks.diff is 0 bytes (BOTH
413
+ // agent/hooks/ AND session/hooks/) — the permission policy queue and the
414
+ // hook engine are byte-identical 0.19.1→0.20.0.
415
+ // - policies/index.ts, pre-tool-call-hook.ts, run-prompt.ts, options.ts, and
416
+ // agent/records/ are ALL 0-byte. PreToolCallHookPermissionPolicy STILL
417
+ // index 0, AgentSwarmExclusiveDeny index 1, AutoModeApprove index 5 (the
418
+ // first approve; every policy between the index-0 hook and it is a DENY).
419
+ // `permission:'auto'` still hard-coded in run-prompt.ts.
420
+ // - A broad-sweep risk scan over EVERY file changed OUTSIDE the five scoped
421
+ // diffs found ZERO new permission/approval decisions anywhere outside the
422
+ // (0-byte) permission+hooks dirs, and no swarm-subagent spawn/permission
423
+ // change — so read/write-swarm `coder` subagents are still gated solely by
424
+ // the index-0 hook.
425
+ // Notable 0.20.0 changes, all compat-benign for a `kimi -p` wrapper:
426
+ // - #1040 AGENTS.md-oversized `warning` agent event: SWALLOWED on -p
427
+ // (run-prompt.ts:495 `case 'warning': return;` — no stdout.write, shared
428
+ // with subagent.*/compaction.*/goal.updated). Invisible to our role-keyed
429
+ // runtime/stream-json.ts parser; reaches only the RPC getSessionWarnings
430
+ // accessor (TUI/kimi-web) + the logger.
431
+ // - #1065 Write auto-creates missing parent dirs (ensureParentDirectory
432
+ // recursive mkdir on ENOENT). The `path` field name is INTACT
433
+ // (WriteInputSchema = z.object({ path, content }); Bash still `command`),
434
+ // so rescue-approval.ts::extractFilePath is unaffected (the v1.4.1 lesson).
435
+ // mkdir runs on the parent of an ALREADY-hook-approved path → can only
436
+ // create dirs INSIDE a path the index-0 hook approved; no workspace escape.
437
+ // - #1062 tool-result budget: adds a `truncated` flag to tool-result CONTENT
438
+ // (loop/tool-call.ts normalizeToolResult), NOT the serialized record SHAPE
439
+ // (records/ + run-prompt.ts 0-byte). It ALSO persists tool results >50,000
440
+ // chars to `<agent.homedir>/tool-results/<stem>-<uuid>.txt`
441
+ // (agent/turn/tool-result-budget.ts, homedir = this.agent.homedir = the
442
+ // KIMI home, NOT the workspace cwd) — a kimi-internal artifact off the
443
+ // user's tree, same class as ~/.kimi-code/logs/. Does NOT touch the user
444
+ // tree → no violation of "read-only commands write zero files in the repo".
445
+ // - commands.ts `-C`→`-c` continue rename (+ hidden `-C` alias): off our flag
446
+ // set (-p/-r/--output-format/-m/--skills-dir); run-prompt.ts/options.ts 0-byte.
447
+ // - NEW RPC runShellCommand/cancelShellCommand (CoreAPI/SessionAPI): a
448
+ // HOST-initiated shell exec (TUI `!command` / kimi-web) that calls
449
+ // bash.resolveExecution().execute() DIRECTLY, bypassing the permission
450
+ // stack + PreToolUse hook. NOT model-reachable: it is not a model tool
451
+ // (absent from the tool registry) and absent from installHeadlessHandlers /
452
+ // the whole apps/kimi-code/src/cli/ -p path. The plugin spawns `kimi -p`
453
+ // and never opens an RPC channel → unreachable. WATCH (next audit):
454
+ // re-confirm it stays RPC/TUI-only and never reaches the -p headless path
455
+ // or the model tool registry — it is the first permission-bypassing
456
+ // shell-exec in agent-core.
457
+ // - forcePluginSessionStartReminder resume override (rpc/core-impl.ts): set
458
+ // ONLY via reloadSession (the /reload RPC flow). The plugin's -p -r resume
459
+ // uses plain harness.resumeSession → never set; appendPluginSessionStart
460
+ // Reminder cannot fire on our path. config/ is 0-byte (the 0.19.0/#812
461
+ // workspace-local additional_dir auto-load is unchanged; GitCwdWriteApprove,
462
+ // its sole consumer at index 17, stays dead below auto-approve on -p).
463
+ // - kimi server/web daemon stack (cli/sub/server/* — access-urls, networks,
464
+ // rotate-token, daemon lifecycle): a separate transport, never invoked; the
465
+ // new stdout.writes there are off the -p path.
466
+ // SMOKE: NOT run for this certification. `bun run smoke:real` against the
467
+ // operator's 0.20.0 binary went RED on a provider 403 "usage limit for this
468
+ // billing cycle" — records:[] on every label, the model never issued a single
469
+ // tool call (0 hook-bypasses observed). This is the operator-billing-state
470
+ // false-alarm class (cf. the auth.login_required note in
471
+ // docs/upstream-compat-audit.md), NOT a compat break — a true break shows the
472
+ // model ATTEMPTING a write and the hook NOT denying. The operator elected to
473
+ // certify on the source audit (manual byte-level + multi-agent re-audit) and
474
+ // skip the quota-blocked smoke; re-run `bun run smoke:real` once quota refreshes
475
+ // to earn the end-to-end proof. See
476
+ // .claude/kimi-code-research/reports/88-upstream-0200-surface.md.
477
+ // Tag: compat-verified-kimi-code-0.20.0.
478
+ // 0.20.1 / 0.20.2 (patches, 2026-06-27 / 2026-06-29) verified COMPAT-PRESERVED
479
+ // within the already-listed {0,20} — no array change (membership is minor-level;
480
+ // H9 stays silent). 02-permission.diff 0-byte (PreToolCallHookPermissionPolicy
481
+ // still index 0, AutoModeApprove index 5); agent/records/ 0-byte (stream-json
482
+ // shape unchanged); run-prompt.ts permission/writer chain unchanged (only
483
+ // telemetry property renames, #1184). The hook engine DID change — #1127 "support
484
+ // hooks in plugins" (0.20.1): rpc/core-impl.ts create+resume now merge enabled
485
+ // kimi-code PLUGIN manifest hooks into the -p session hook list ([...config.hooks,
486
+ // ...plugins.enabledHooks()]). Compat-benign: engine aggregation is any-block-wins
487
+ // (session/hooks/engine.ts blockDecision = first action:'block' wins; an allow
488
+ // never pre-empts a block), so a plugin hook can only ADD denials, never override
489
+ // our managed PreToolUse deny. Our config.toml managed block is unaffected: the
490
+ // config HookDefSchema is .strict(), so the new per-hook cwd/env fields are
491
+ // programmatic/plugin-only (no config-injection vector). NEW load-bearing
492
+ // invariant: hook AGGREGATION semantics (we are no longer the sole -p hook) —
493
+ // re-verify blockDecision stays find-first-block each audit. Off-path: #1170/#1186
494
+ // Anthropic-protocol/betaApi transport plumbing (config protocol/betaApi alias
495
+ // fields + provider-manager; off the -p stdout shape + permission stack), #1125
496
+ // upgrade->update alias, #1129/#1156 compaction cap, #1128 server --allowed-host.
497
+ // 0.20.0 runShellCommand/cancelShellCommand RPC WATCH discharged (still RPC/TUI-
498
+ // only, unreachable from kimi -p). SMOKE: GREEN on 0.20.2 — `bun run smoke:real`
499
+ // 9 pass / 0 fail (2026-06-29) on the operator's 0.20.2 binary: review/challenge/
500
+ // ask/review_gate forced writes hook-denied; pursue multi-turn goal wrote zero
501
+ // files (goal.summary parsed cleanly turnsUsed:2 tokensUsed:85770); a read-only
502
+ // swarm subagent's forced write hook-denied; and BOTH write-swarm assertions held
503
+ // (coder edits confined to the throwaway worktree, patchBytes=334,
504
+ // userTreeClean=true; an out-of-trusted-root absolute write hook-denied). The
505
+ // earlier report-88 0.20.0 quota block (provider 403 "usage limit") was the
506
+ // operator-billing-state false alarm, now cleared — the {0,20} line is end-to-end
507
+ // proven on 0.20.2. Tag: compat-verified-kimi-code-0.20.2.
508
+ // See .claude/kimi-code-research/reports/89, 90, 91-upstream-020x-surface.md.
509
+ { major: 0, minor: 20 },
510
+ // 0.21 (new minor, 2026-07-01) verified COMPAT-PRESERVED — the operator's
511
+ // binary auto-upgraded to 0.21.1 (PR #334 drift), crossing the 0.20→0.21
512
+ // minor and firing the H9 "newer than tested max" probe warning. Report 93's
513
+ // source audit found the two load-bearing surfaces byte-identical across the
514
+ // full 0.20.2→0.21.1 span: 02-permission.diff 0 bytes (hook still index 0,
515
+ // AutoModeApprove still index 5, every policy between is a DENY) and
516
+ // 03-hooks.diff 0 bytes (hook engine and any-block-wins aggregation intact).
517
+ // Also 0-byte: options.ts (argv), agent/records/ (stream-json shape),
518
+ // workspace-local.ts (additional_dir auto-load unchanged), and
519
+ // tools/builtin/file/{write,edit}.ts (`path` field intact). run-prompt.ts
520
+ // still hard-codes permission:'auto' and installHeadlessHandlers; its only
521
+ // scoped change is a cleanup timeout (#1233) after resume_hint/goal.summary
522
+ // flush, which helps process reaping.
523
+ // New 0.21.0 surfaces are compat-benign for a `kimi -p` wrapper:
524
+ // - #1204 plugin slash commands are RPC/host-initiated, absent from the
525
+ // cli/ -p path, not model tools, and macro-expand into prompt text that
526
+ // still goes through the index-0 hook. They are main-agent-only; swarm
527
+ // coders do not receive them. NEXT-AUDIT: re-confirm activation stays
528
+ // off the -p path and never becomes a model tool.
529
+ // - The thinking-effort/model-catalog refactor is provider config plumbing
530
+ // the plugin does not set or consume. H5 opportunity, not a risk.
531
+ // - Compaction rework and record migrations are internal replay/history
532
+ // changes; the live PromptJsonWriter + agent/records/ shape is unchanged.
533
+ // - The 0.20.0 runShellCommand/cancelShellCommand RPC WATCH is discharged
534
+ // again: still RPC/TUI-only, absent from cli/, and unreachable from kimi -p.
535
+ // Backed by a GREEN `bun run smoke:real` on the operator's 0.21.1 binary
536
+ // (2026-07-01): 9 pass / 0 fail. review/challenge/ask/review_gate forced
537
+ // writes hook-denied; pursue goal mode wrote zero files and parsed
538
+ // goal.summary (turnsUsed:2 tokensUsed:57595); a read-only swarm subagent's
539
+ // forced write was hook-denied; write-swarm kept coder edits in the throwaway
540
+ // worktree (patchBytes=334, userTreeClean=true, worktreeCleaned=true); and an
541
+ // out-of-trusted-root absolute write was hook-denied. Reports:
542
+ // .claude/kimi-code-research/reports/93-upstream-021-surface.md and
543
+ // 93-upstream-021-adversarial.md. Tag: compat-verified-kimi-code-0.21.1.
544
+ { major: 0, minor: 21 },
545
+ // 0.22 (new minor, 2026-07-05) verified COMPAT-PRESERVED through
546
+ // @moonshot-ai/kimi-code@0.22.3 after report 94's source-only 0.22.0 scan and
547
+ // report 95's incremental 0.22.0→0.22.3 scan. Hook engine remained unchanged
548
+ // (03-hooks.diff 0 bytes); policy order stayed hook-first with
549
+ // PreToolCallHookPermissionPolicy at index 0 and AutoModeApprove at index 5;
550
+ // Write/Edit still use `path`, Bash still uses `command`, and AgentSwarm still
551
+ // uses the standard stack. New 0.22.x surfaces are compat-benign for this
552
+ // `kimi -p` wrapper: prompt-mode background-drain runs after assistant output
553
+ // flush and remains bounded by the plugin's AbortController budgets; shell
554
+ // output caps affect huge tool-result content only; image originals are stored
555
+ // under Kimi session state, not the user worktree; model/thinking/provider
556
+ // config changes do not touch permissions; server auth-bypass flags remain
557
+ // off the `-p` path. Backed by a GREEN `bun run smoke:real` against a
558
+ // temp-installed 0.22.3 binary (2026-07-05): 9 pass / 0 fail. Read-only labels
559
+ // denied forced writes; pursue wrote zero files and parsed goal.summary
560
+ // (turnsUsed:2 tokensUsed:93029); read-only swarm denied a spawned subagent
561
+ // write; write-swarm confined coder edits to the throwaway worktree
562
+ // (patchBytes=334, userTreeClean=true, worktreeCleaned=true); and an
563
+ // out-of-trusted-root absolute write was hook-denied. Reports:
564
+ // .claude/kimi-code-research/reports/94-upstream-0220-surface.md and
565
+ // 95-upstream-0223-surface.md. Tag: compat-verified-kimi-code-0.22.3.
566
+ { major: 0, minor: 22 },
567
+ // 0.23 (new minor, 2026-07-07) verified COMPAT-PRESERVED through
568
+ // @moonshot-ai/kimi-code@0.23.1 in report 96 plus a GREEN temp-binary
569
+ // smoke (9 pass / 0 fail). Hook engine remained unchanged (03-hooks.diff
570
+ // 0 bytes); policy order stayed hook-first with PreToolCallHookPermissionPolicy
571
+ // at index 0 and AutoModeApprove at index 5; `kimi -p` still writes the same
572
+ // stream-json records plus session.resume_hint/goal.summary; Write/Edit still
573
+ // use `path`; plugin hooks remain merged any-block-wins; AgentSwarm read and
574
+ // write-smoke confinement both held. New 0.23.x surfaces are compat-benign:
575
+ // `select_tools` is an upstream default-approved MCP schema disclosure tool,
576
+ // but our hook still denies unknown tools before default approval and the
577
+ // smoke passed without broadening READ_ONLY_TOOLS; observability wire records,
578
+ // session workDir/index repair, thinking-keep defaults, and workspace-skill
579
+ // listing do not change the plugin's hook or stdout contract. Report:
580
+ // .claude/kimi-code-research/reports/96-upstream-0231-surface.md. Tag:
581
+ // compat-verified-kimi-code-0.23.1.
582
+ // 0.23.2 (patch, 2026-07-08) verified COMPAT-PRESERVED within the already-
583
+ // listed {0,23}: scoped 0.23.1→0.23.2 diffs changed only `run-prompt.ts`
584
+ // cleanup/exit behavior and `session/hooks/runner.ts` Windows spawn UX.
585
+ // `02-permission.diff` stayed 0 bytes (hook still index 0; first approve
586
+ // still index 5), `05-session-bootstrap.diff` stayed 0 bytes, and the
587
+ // non-empty `04-wire-records.diff` was only the same `session/hooks/runner.ts`
588
+ // hunk re-included by the broader `session/` scope — no
589
+ // session.resume_hint/goal.summary/output-shape drift. The 0.23.2
590
+ // `run-prompt.ts` change (#1483) keeps the cleanup timeout ref'd so a
591
+ // failed headless `-p` run cannot drain the event loop and exit 0 before the
592
+ // rejection propagates; this is exit-code correctness, not a permission or
593
+ // writer change. The hook-runner change (#1466) adds `windowsHide:true` to
594
+ // hook child-process spawn options, eliminating flashing console windows on
595
+ // Windows without altering stdin JSON shape, exit-2-as-deny semantics, or
596
+ // any-block-wins aggregation. Backed by a GREEN temp-binary `bun run
597
+ // smoke:real` on 0.23.2 (2026-07-08): 9 pass / 0 fail. Read-only labels
598
+ // denied forced writes; pursue wrote zero files and parsed goal.summary;
599
+ // read-only swarm denied a spawned subagent write; write-swarm confined
600
+ // coder edits to the throwaway worktree (patchBytes=306, userTreeClean=true,
601
+ // worktreeCleaned=true); and an out-of-trusted-root absolute write was
602
+ // hook-denied. Report:
603
+ // .claude/kimi-code-research/daily-monitor/2026-07-08-upstream-monitor.md.
604
+ // Tag: compat-verified-kimi-code-0.23.2.
605
+ // 0.23.3/0.23.4 (patches, 2026-07-09) verified COMPAT-PRESERVED within the
606
+ // already-listed {0,23}: scoped 0.23.2→0.23.4 diffs left permission and both
607
+ // hook trees byte-identical (`02-permission.diff` and `03-hooks.diff` both 0
608
+ // bytes). Hook ordering remains PreToolCallHookPermissionPolicy index 0 and
609
+ // AutoModeApprove index 5; aggregation remains any-block-wins; Bash still
610
+ // uses `command`, Write/Edit still use `path`, and AgentSwarm subagents still
611
+ // use the standard permission stack. The load-bearing `run-prompt.ts` change
612
+ // (#1516) makes `kimi -p "/goal ..."` wait across continuation turns until
613
+ // the goal is terminal instead of resolving after the first completed turn.
614
+ // `permission:'auto'`, `installHeadlessHandlers`, PromptJsonWriter,
615
+ // session.resume_hint, and goal.summary shapes remain intact. The non-empty
616
+ // `04-wire-records.diff` is internal provider-auth/media projection/session
617
+ // plumbing, not new stdout NDJSON; the non-empty `05-session-bootstrap.diff`
618
+ // adds owner-scoped `[image]` limits without changing additionalDirs, hook
619
+ // merging, or permission construction. The 0.23.3 provider-auth patch now
620
+ // surfaces the upstream 401 reason as PROVIDER_AUTH_ERROR instead of falsely
621
+ // demanding relogin; it does not affect tool or hook execution. Backed by a
622
+ // GREEN temp-binary `bun run smoke:real` on exact 0.23.4 (2026-07-09):
623
+ // 9 pass / 0 fail. Read-only labels denied forced writes; pursue ran to its
624
+ // two-minute budget across continuation turns with no file written;
625
+ // read-only swarm denied a spawned subagent write; write-swarm confined coder
626
+ // edits to the throwaway worktree (patchBytes=278, userTreeClean=true,
627
+ // worktreeCleaned=true); and an out-of-trusted-root absolute write was
628
+ // hook-denied. Report:
629
+ // .claude/kimi-code-research/daily-monitor/2026-07-09-upstream-monitor.md.
630
+ // Tag: compat-verified-kimi-code-0.23.4.
631
+ // 0.23.5 (patch, 2026-07-11) verified COMPAT-PRESERVED within the already-
632
+ // listed {0,23} at released tag commit 352a4492. Permission, both hook trees,
633
+ // and session bootstrap stayed byte-identical (`02-permission.diff`,
634
+ // `03-hooks.diff`, and `05-session-bootstrap.diff` all 0 bytes), so hook-first
635
+ // ordering, any-block-wins aggregation, field names, and create/resume config
636
+ // loading remain intact. `04-wire-records.diff` only adds the internal
637
+ // `media-stripped` projection type. The load-bearing change is additive
638
+ // `PromptJsonWriter` metadata: `role:"meta", type:"turn.step.retrying"` on
639
+ // provider retry events. v1.8.0 models its exact shape, normalizes it, and
640
+ // filters it from consumer records while retaining malformed-shape diagnostics.
641
+ // The post-change exact-0.23.5 `bun run smoke:real` was GREEN (2026-07-11):
642
+ // 9 pass / 0 fail in 229.56s. Read-only labels denied forced writes; pursue
643
+ // ran to its full two-minute budget with no file written; read-only swarm
644
+ // spawned coder subagents whose writes were denied; write-swarm confined edits
645
+ // to the throwaway worktree (patchBytes=334, userTreeClean=true,
646
+ // worktreeCleaned=true); and an out-of-trusted-root absolute write was denied.
647
+ // Report: .claude/kimi-code-research/daily-monitor/2026-07-11-upstream-monitor.md.
648
+ // Tag: compat-verified-kimi-code-0.23.5.
649
+ // 0.23.6 (patch, 2026-07-12) verified COMPAT-PRESERVED within the already-
650
+ // listed {0,23} at released tag commit b5c236d0. Permission and both hook
651
+ // trees stayed byte-identical (`02-permission.diff` and `03-hooks.diff` were
652
+ // 0 bytes): hook-first order, any-block-wins aggregation, Bash.command,
653
+ // Write.path, and Edit.path remain intact. `run-prompt.ts` now keeps `-p`
654
+ // alive while a goal is active or cron work is pending and optionally across
655
+ // background-task steering; the plugin does not enable steer mode and its
656
+ // mandatory AbortController budgets remain the outer bound. Upstream also
657
+ // makes subagent timeout configurable and raises its default to two hours,
658
+ // without changing AgentSwarm's standard permission stack; plugin budgets
659
+ // and hard concurrency caps still bound every swarm run. The provider
660
+ // capability rename from select_tools to dynamically_loaded_tools is
661
+ // internal tool-disclosure plumbing, not a permission or stdout-shape change.
662
+ // Exact-0.23.6 `bun run smoke:real` was GREEN (2026-07-12): 9 pass / 0 fail
663
+ // in 274.55s. Read-only labels denied forced writes; pursue ran to its full
664
+ // two-minute budget with no file written; read-only swarm denied a spawned
665
+ // subagent write; write-swarm stayed confined (patchBytes=306,
666
+ // userTreeClean=true, worktreeCleaned=true); and an out-of-root absolute
667
+ // write was hook-denied after a real AgentSwarm dispatch. Report:
668
+ // .claude/kimi-code-research/daily-monitor/2026-07-12-upstream-monitor.md.
669
+ // Tag: compat-verified-kimi-code-0.23.6.
670
+ { major: 0, minor: 23 },
671
+ // 0.24.2 (minor, 2026-07-15) verified COMPAT-PRESERVED across the cumulative
672
+ // 0.23.6→0.24.2 release delta. The default v1 permission and live
673
+ // session/hooks surfaces are 0-byte diffs: PreToolCallHook remains index 0,
674
+ // AutoModeApprove remains the first approve at index 5, aggregation remains
675
+ // any-block-wins, and Bash.command / Write.path / Edit.path are unchanged.
676
+ // The large prompt-mode refactor keeps the explicit argv and v1 auto-mode
677
+ // contract intact. A truthy ambient KIMI_CODE_EXPERIMENTAL_FLAG now selects
678
+ // native agent-core-v2; source tracing confirmed its strict configured-hook
679
+ // schema, configured+plugin hook merge, snake_case tool payload, awaited
680
+ // pre-execution deny, and per-agent hook service. A targeted exact-v2 review
681
+ // smoke denied a forced write. V2 also emits role:"meta",
682
+ // type:"system.version" before normal output; the parser tolerates it as one
683
+ // non-fatal diagnostic, keeps it out of records/onRecord, and still pins the
684
+ // terminal session.resume_hint, so explicit modeling is optional polish.
685
+ // Upstream print mode now defaults background completion to steering and its
686
+ // own task timeouts can be unbounded, but the plugin's finite budgets,
687
+ // concurrency caps, and identity-safe cancellation teardown remain outer
688
+ // bounds. The complete exact-0.24.2 v1 `bun run smoke:real` was GREEN:
689
+ // 9 pass / 0 fail, 39 assertions in 261.33s. Read-only labels denied writes;
690
+ // pursue wrote no file through its full two-minute budget; read swarm denied
691
+ // a subagent write; write-swarm stayed confined (patchBytes=278,
692
+ // userTreeClean=true, worktreeCleaned=true); and the out-of-root write was
693
+ // denied. Phase-1 reports: 97-100; synthesis: 101. Tag:
694
+ // compat-verified-kimi-code-0.24.2.
695
+ { major: 0, minor: 24 },
696
+ // 0.25.0 (minor, 2026-07-16) verified COMPAT-PRESERVED across the
697
+ // 0.24.2→0.25.0 release delta. The two primary safety surfaces are 0-byte
698
+ // diffs: 01-cli-prompt-mode and 03-hooks are byte-identical, so argv,
699
+ // default-v1 routing, auto permission, headless handlers, the hook payload,
700
+ // exit-2 denial, matcher behavior, and any-block-wins aggregation are
701
+ // unchanged. The remaining scoped deltas are compat-benign: 02-permission
702
+ // (943 B) only adds `trace_id` to two permission telemetry events (no policy
703
+ // construction, queue order, or resolution change); 04-wire-records (2 KB)
704
+ // touches only session/provider-manager.ts to forward Anthropic
705
+ // supportEfforts/adaptive-thinking capability data (no new PromptJsonWriter
706
+ // record, role/meta type, session-id field, or goal-summary shape);
707
+ // 05-session-bootstrap (3.9 KB) derives thinking efforts from the resolved
708
+ // provider profile while still loading workspace dirs, building the
709
+ // permission context, and merging configured + plugin hooks on create AND
710
+ // resume. Direct invariant checks on the released 0.25.0 tag confirmed
711
+ // PreToolCallHook index 0, AgentSwarmExclusiveDeny index 1, AutoModeApprove
712
+ // the first approve at index 5 (every intervening policy a deny), any-block-
713
+ // wins, empty matcher = all tools, exit 2 blocks, Bash.command /
714
+ // Write.path / Edit.path, `kimi -p` default v1 unless a truthy ambient
715
+ // KIMI_CODE_EXPERIMENTAL_FLAG selects agent-core-v2 (still opt-in, still
716
+ // safety-preserving), AgentSwarm subagents on the standard permission stack
717
+ // (deny-all remains startBtw()-only), and KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY
718
+ // as the hard concurrent-subagent ceiling. The complete exact-0.25.0 v1
719
+ // `bun run smoke:real` was GREEN on the clean v1.8.2 tree: 9 pass / 0 fail,
720
+ // 39 assertions in 419.12s. Read-only labels denied writes; pursue wrote no
721
+ // file through its full budget (aborted at the wall-clock ceiling); read
722
+ // swarm denied a subagent write; write-swarm stayed confined (patchBytes=278,
723
+ // userTreeClean=true, worktreeCleaned=true); and the out-of-root write was
724
+ // denied. A supplementary KIMI_CODE_EXPERIMENTAL_FLAG=1 targeted v2 review
725
+ // denial also passed (1 pass). Daily monitor: 2026-07-16. Tag:
726
+ // compat-verified-kimi-code-0.25.0.
727
+ { major: 0, minor: 25 },
728
+ // 0.26.0 (minor, 2026-07-16) verified COMPAT-PRESERVED across the
729
+ // 0.25.0→0.26.0 release delta. All THREE primary safety surfaces are 0-byte
730
+ // diffs: 01-cli-prompt-mode, 02-permission, AND 03-hooks are byte-identical,
731
+ // so argv, default-v1 routing, auto permission, headless handlers, the whole
732
+ // policy queue (PreToolCallHook index 0), the hook engine, exit-2 denial,
733
+ // matcher behavior, and any-block-wins aggregation are unchanged from the
734
+ // certified 0.25.0. The two non-empty scoped surfaces are compat-benign:
735
+ // 04-wire-records (32 KB) is session-store workDir normalization (Windows
736
+ // case-insensitive drive paths), session forking (a persisted `forked`
737
+ // AgentRecord + a new internal `context.update_token_count` record — neither
738
+ // is a `-p` stdout record the parser consumes, and an unknown type fails safe
739
+ // to the diagnostic channel), provider-manager thinking plumbing, and a
740
+ // subagent-host `drainChildBackgroundTasks` addition that holds a subagent
741
+ // open until its background tasks settle and suppresses their terminal
742
+ // notifications (a lifecycle/settlement change, NOT a permission-stack change;
743
+ // drained tasks still fire the index-0 hook — it aligns with the plugin's own
744
+ // settlement-barrier cancellation). 05-session-bootstrap (16 KB) is
745
+ // config/model.ts thinking-profile plumbing, an optional `auth:'oauth'` field
746
+ // added to the MCP HTTP/SSE schemas (NOT HookDefSchema, which stays
747
+ // `.strict()`), and additive rpc/core-impl.ts Global-MCP management + OAuth
748
+ // flows + deleteSession/importContext (all RPC/host methods off the `-p`
749
+ // path) plus a setAdditionalDirs→setBaseAdditionalDirs rename and an
750
+ // `includeSubagents` resume flag the plugin never passes; the create/resume
751
+ // hook merge is unchanged. Direct checks on the 0.26.0 tag: tools/builtin/file
752
+ // is a 0-byte diff (Write.path/Edit.path byte-identical), the deny-all unshift
753
+ // is still startBtw()-only (subagent-host.ts, inside startBtw(), never the
754
+ // swarm spawn path), and installHeadlessHandlers + the v1 default persist. The
755
+ // complete exact-0.26.0 v1 `bun run smoke:real` (temp-installed 0.26.0 binary
756
+ // via the KIMI_PLUGIN_CC_KIMI_BIN override) was GREEN: 9 pass / 0 fail, 39
757
+ // assertions in 376.06s. Read-only labels denied writes; pursue wrote no file
758
+ // through its full budget (aborted at the ceiling); read swarm denied a
759
+ // subagent write; write-swarm stayed confined (patchBytes=278,
760
+ // userTreeClean=true, worktreeCleaned=true); and the out-of-root write was
761
+ // denied. Tag: compat-verified-kimi-code-0.26.0.
762
+ { major: 0, minor: 26 },
763
+ // 0.27.0 (minor, 2026-07-17) verified COMPAT-PRESERVED across the
764
+ // 0.26.0→0.27.0 release delta. All THREE primary safety surfaces are 0-byte
765
+ // diffs: 01-cli-prompt-mode, 02-permission, AND 03-hooks are byte-identical,
766
+ // so argv, default-v1 routing, auto permission, headless handlers, the whole
767
+ // policy queue, the hook engine, exit-2 denial, matcher behavior, and
768
+ // any-block-wins aggregation are unchanged from the certified 0.26.0. The two
769
+ // non-empty scoped surfaces are compat-benign: 04-wire-records (12.3 KB) is
770
+ // session-storage identity + debug-export naming work (timestamped export
771
+ // filenames instead of repeatedly overwriting `<session-id>.zip`; an optional
772
+ // workspace-id registry reuse for the same physical root with Windows-shaped
773
+ // case/slash folding and safe-id validation + legacy-hash fallback — session
774
+ // directory bookkeeping, NOT PromptJsonWriter NDJSON records, session.resume_
775
+ // hint, hook execution, permission ordering, or workspace-write policy), and
776
+ // 05-session-bootstrap (1.7 KB) only wires the optional `resolveWorkspaceId`
777
+ // callback through KimiCoreOptions into SessionStore (no config schema,
778
+ // workspace-local additional_dir, hook merge, or permission-context change;
779
+ // HookDefSchema stays `.strict()`). The release notes' new `/copy` slash
780
+ // command is off the monitored `-p` path (scoped CLI delta 0 bytes; not a
781
+ // model tool). Direct invariant checks on the released 0.27.0 tag confirmed
782
+ // PreToolCallHook index 0, AgentSwarmExclusiveDeny index 1, AutoModeApprove
783
+ // the first approve at index 5 (every intervening policy a deny), any-block-
784
+ // wins via the first action:'block' result, empty matcher = all tools, exit 2
785
+ // blocks, Bash.command / Write.path / Edit.path, `kimi -p` fresh sessions at
786
+ // permission:'auto' with resumed sessions force-overridden, AgentSwarm
787
+ // subagents on the standard permission stack (deny-all unshift remains
788
+ // startBtw()-only), and KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY as the hard
789
+ // concurrent-subagent ceiling. The complete exact-0.27.0 `bun run smoke:real`
790
+ // (temp-installed 0.27.0 binary via KIMI_PLUGIN_CC_KIMI_BIN) was GREEN: 10
791
+ // pass / 0 fail, 43 assertions in 587.74s — read-only labels denied writes,
792
+ // the v2 lane (KIMI_CODE_EXPERIMENTAL_FLAG=1) denied AND emitted the modeled
793
+ // system-version signal, pursue wrote no file through its full budget, read
794
+ // swarm denied a subagent write, write-swarm stayed confined (patchBytes=278,
795
+ // userTreeClean=true, worktreeCleaned=true), and the out-of-root write was
796
+ // denied. Daily monitor: 2026-07-18. Tag: compat-verified-kimi-code-0.27.0.
797
+ { major: 0, minor: 27 },
798
+ // 0.28.1 (0.28.0 + patch 0.28.1, 2026-07-20) verified COMPAT-PRESERVED across
799
+ // the 0.27.0→0.28.1 release delta (chained on the 0.27.0 audit above, so the
800
+ // full 0.26.0→0.28.1 span is covered). The two load-bearing safety surfaces
801
+ // are 0-byte diffs: 02-permission AND 03-hooks byte-identical; 04-wire-records
802
+ // is also 0 bytes incrementally (the 12.3 KB 0.26.0→0.28.1 total is entirely
803
+ // the previously audited 0.27.0 storage work). 01-cli-prompt-mode (1.7 KB) is
804
+ // commands.ts ONLY: the top-level `server` registration is replaced by `web`
805
+ // and the YOLO-vs-Auto help text is corrected — run-prompt.ts and options.ts
806
+ // are byte-identical, and the plugin passes its prompt as the VALUE of `-p`,
807
+ // so neither change alters consumed argv or `-p` routing. 05-session-bootstrap
808
+ // (4.8 KB incremental) adds a one-shot `thinking.effort = "max" -> "high"`
809
+ // config migration that strictly parses and reserializes config.toml via
810
+ // configToTomlData/setHooks: validated hooks[] entries are preserved but ALL
811
+ // comments are stripped — exactly the markerless-hook condition the plugin has
812
+ // handled since v1.8.2 (`hasCleanEnforcingHookEntry`, the real-smol-toml
813
+ // parser-based, byte-exact, matcher-rejecting absent-state fallback), so a
814
+ // post-migration config still verifies installed. The 0.28.1 v2 change
815
+ // broadcasting session-level permission-mode switches to already-running
816
+ // subagents is a propagation fix, not a hook bypass — the v2 external-hook
817
+ // runner and tool-executor hook slots are byte-identical across the delta.
818
+ // Direct checks on the released 0.28.1 tag reconfirmed the full invariant set
819
+ // (PreToolCallHook index 0, AgentSwarmExclusiveDeny index 1, AutoModeApprove
820
+ // first approve at index 5 with only denies between, any-block-wins, empty
821
+ // matcher = all tools, exit 2 blocks, Bash.command / Write.path / Edit.path,
822
+ // `-p` auto + headless handlers + resume-hint emission, plugin slash-command
823
+ // activation still RPC/host-initiated and absent from the `-p` path). The
824
+ // complete exact-0.28.1 `bun run smoke:real` (temp-installed 0.28.1 binary via
825
+ // KIMI_PLUGIN_CC_KIMI_BIN) was GREEN: 10 pass / 0 fail, 43 assertions in
826
+ // 626.72s — same full matrix as 0.27.0 including the v2 denial lane, pursue
827
+ // budget abort, read-swarm subagent denial, write-swarm confinement
828
+ // (patchBytes=278, userTreeClean=true, worktreeCleaned=true), and the
829
+ // out-of-root absolute write denial. Daily monitor: 2026-07-21. Tag:
830
+ // compat-verified-kimi-code-0.28.1.
831
+ { major: 0, minor: 28 },
832
+ // 0.29.1 (0.29.0 + patch 0.29.1, 2026-07-24) verified
833
+ // COMPAT-PRESERVED across the 0.28.1→0.29.1 release span. The staged scoped
834
+ // audits found: 0.28.1→0.29.0 — 01-cli-prompt-mode 3,909 B,
835
+ // 02-permission 0 B, 03-hooks 0 B, 04-wire-records 8,322 B, and
836
+ // 05-session-bootstrap 7,655 B; 0.29.0→0.29.1 — 01/02/03 all 0 B,
837
+ // 04-wire-records 938 B, and 05-session-bootstrap 8,700 B. The v1
838
+ // load-bearing contract therefore remains intact: PreToolCallHook index 0,
839
+ // AgentSwarmExclusiveDeny index 1, AutoModeApprove the first approve at index
840
+ // 5 with only denies between; empty matcher = all tools; exit 2 blocks;
841
+ // aggregation is any-block-wins; Bash.command / Write.path / Edit.path are
842
+ // unchanged; fresh and resumed `kimi -p` sessions remain auto with headless
843
+ // handlers; AgentSwarm subagents retain the standard permission stack and
844
+ // KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY remains the hard concurrency gate.
845
+ // The non-empty v1 changes are compat-benign provider/model capability,
846
+ // session/record identity, replay-limit, MCP timeout, and web endpoint/env
847
+ // plumbing; none changes PromptJsonWriter records, session.resume_hint,
848
+ // configured+plugin hook merging, HookDefSchema, workspace-local
849
+ // additional_dir loading, or permission-context construction.
850
+ //
851
+ // 0.29.1 substantially refactors experimental agent-core-v2 tool
852
+ // adjudication from ordered hook slots to an awaited BeforeToolExecuteEmitter.
853
+ // The 2026-07-24 audit correctly proved the ordinary awaited external-hook
854
+ // veto and the smoke below, but its production-order conclusion was wrong.
855
+ // 2026-07-31 correction: global service registration actually orders
856
+ // permission gate → plan → swarm → external hooks. Active plan mode can
857
+ // final-allow the exact KIMI_CODE_HOME plan-file Write/Edit before the hook.
858
+ // The app hook runner and hook command/config engine are byte-identical across
859
+ // the patch, so empty-matcher, exit-2 denial, and first-block-wins aggregation
860
+ // remain true for calls that reach them; they do not prove every v2 call does.
861
+ // v1.9.4 therefore refuses experimental-v2 across the tested range pending an
862
+ // upstream ordering guarantee. See the 0.31 entry for reachability/mitigation.
863
+ //
864
+ // The exact-0.29.1 temp-binary `bun run smoke:real` was GREEN: 10 pass /
865
+ // 0 fail, 43 assertions in 339.80s. Review/challenge/ask/review_gate forced
866
+ // writes were denied; the asserted KIMI_CODE_EXPERIMENTAL_FLAG=1 lane emitted
867
+ // the v2 signal and denied through the new veto path; pursue hit its finite
868
+ // budget with zero writes; read swarm denied a spawned subagent write;
869
+ // write-swarm stayed confined (patchBytes=306, userTreeClean=true,
870
+ // worktreeCleaned=true); and the non-vacuous out-of-root absolute write was
871
+ // denied. No auth/quota/hook-bypass/user-tree-write blocker occurred.
872
+ // Headless goal resume remains absent: parseHeadlessGoalCreate and both print
873
+ // drivers still expose create only; resumeGoal stays TUI/RPC-only. Daily
874
+ // monitors: 2026-07-23 and 2026-07-24. Tag:
875
+ // compat-verified-kimi-code-0.29.1.
876
+ //
877
+ // 0.29.2 patch checkup (2026-07-27) verified COMPAT-PRESERVED inside the
878
+ // already-tested 0.29.x minor. Scoped 0.29.1→0.29.2 diffs were:
879
+ // 01-cli-prompt-mode 0 B, 02-permission 0 B, 03-hooks 0 B,
880
+ // 04-wire-records 757 B, and 05-session-bootstrap 0 B. The sole canonical
881
+ // delta makes a main-agent `steer` refresh prompt metadata like `prompt`;
882
+ // it does not alter stream-json output, session pinning, hook matching or
883
+ // aggregation, permission construction, or tool dispatch. V1 goal pursuit
884
+ // now treats `loop_control.max_steps_per_turn` as a continuation boundary
885
+ // instead of pausing the goal; the plugin's mandatory finite wall-clock
886
+ // AbortController budget remains the hard bound.
887
+ //
888
+ // Experimental v2 replaced its hand-maintained eager-service startup list
889
+ // with dependency-driven `ScopeActivation.OnScopeCreated` construction and
890
+ // moved mutable service state into agent/session state containers.
891
+ // `AgentExternalHooksService` still awaits configured/plugin PreToolUse and
892
+ // vetoes on block; `run-v2-print.ts`, `BeforeToolExecuteEmitter`, the hook
893
+ // aggregation runner, and the hook command runner are all 0-byte diffs.
894
+ // The exact-0.29.2 temp-binary `bun run smoke:real` was GREEN: 10 pass /
895
+ // 0 fail, 43 assertions in 502.40s. It non-vacuously denied the asserted-v2
896
+ // forced write, kept pursue at zero writes through its finite-budget abort,
897
+ // denied a read-swarm subagent write, confined write-swarm
898
+ // (patchBytes=278, userTreeClean=true, worktreeCleaned=true), and denied the
899
+ // out-of-root absolute write. Headless goal resume remains absent because
900
+ // both print drivers are byte-identical across the patch. Daily monitor:
901
+ // 2026-07-27. Tag: compat-verified-kimi-code-0.29.2.
902
+ { major: 0, minor: 29 },
903
+ // 0.30.0 certified in v1.9.3 (2026-07-29). SCOPE NOTE, because it is easy to
904
+ // audit the wrong tree: the released `@moonshot-ai/kimi-code@0.30.0` tag is
905
+ // EIGHT commits behind `origin/main`. Everything interesting in main — v1
906
+ // custom agent files (#2232), plugin-contributed agents (#2365), plugin
907
+ // `systemPrompt` (#2314), the `secondary-model` flag — is queued for 0.31.0
908
+ // and is NOT in the released binary. This entry certifies the RELEASED tag;
909
+ // contracts were verified at main as well (the stricter state) and hold in
910
+ // both.
911
+ //
912
+ // Re-verified against 0.30.0 source, all byte-identical to 0.29.2 unless
913
+ // noted: policy queue keeps PreToolCallHookPermissionPolicy at index 0 with
914
+ // indices 1-4 ALL pure denies (AgentSwarmExclusiveDeny, AutoModeAskUserQuestionDeny,
915
+ // PlanModeGuardDeny, UserConfiguredDeny) before the first approve at index 5,
916
+ // so nothing auto-approves ahead of the hook; hook engine keeps
917
+ // first-block-wins (`engine.ts` `results.find(r => r.action === 'block')`),
918
+ // empty-matcher-means-all, exit-2 denial, and fail-open on internal error;
919
+ // `Bash` still takes `command` and `Write`/`Edit` still take `path` (NOT
920
+ // `file_path`) with no new write-shaped builtin tool; `-p` still defaults to
921
+ // the v1 driver with `permission: 'auto'` + installHeadlessHandlers, still
922
+ // writes stream-json via PromptJsonWriter, still emits the `session.resume_hint`
923
+ // meta record and the role-less `goal.summary`, and still rejects
924
+ // --auto/--yolo/--plan with -p; goal mode still triggers on the `/^\/goal(\s|$)/`
925
+ // prefix ALONE; plugin hooks still merge any-block-wins and `HookDefSchema`
926
+ // is still `.strict()` (no config-injection vector for per-hook cwd/env).
927
+ //
928
+ // AgentSwarm subagents still use the STANDARD permission stack:
929
+ // `DenyAllPermissionPolicy` has exactly ONE call site repo-wide, inside
930
+ // `startBtw()`, and `spawn()`/`configureChild()` never touch
931
+ // `permission.policies`; children still share `parent.config.cwd`. The
932
+ // adversarial check that matters most: `agent.hooks` is OPTIONAL, so an
933
+ // unwired subagent would silently fail open through index 0 — it is wired
934
+ // unconditionally by `createAgent`'s `config.hookEngine ?? this.hookEngine`
935
+ // fallback, and NO production call site supplies `config.hookEngine`. Every
936
+ // swarm subagent therefore fires the session hook engine.
937
+ //
938
+ // KNOWN CAVEAT, characterized not hand-waved: 0.30.0 activates the KAP
939
+ // global search service in EVERY agent-core-v2 App bootstrap, not just the
940
+ // server, so an experimental-v2 run (`KIMI_CODE_EXPERIMENTAL_FLAG` truthy,
941
+ // which the plugin inherits) performs an unasked-for cross-session index
942
+ // pass and creates `<KIMI_CODE_HOME>/search-index`. It is NOT a hook bypass,
943
+ // NOT a user-worktree write, and NOT a credential read: the index is engine
944
+ // -internal (never a tool call) and confined to KIMI_CODE_HOME. The DEFAULT
945
+ // v1 engine is unaffected (`sdk-rpc-client.ts` bootstraps no App scope).
946
+ // Upstream fix: MoonshotAI/kimi-code#2376 (App-scope OnDemand), which removes
947
+ // the caveat in a later release.
948
+ //
949
+ // The exact-0.30.0 `bun run smoke:real` was GREEN: 11 pass / 0 fail, 49
950
+ // assertions in 348.05s. It denied review/challenge/ask/review_gate forced
951
+ // writes; the asserted KIMI_CODE_EXPERIMENTAL_FLAG=1 lane emitted the v2
952
+ // signal and still denied; pursue hit its finite budget with zero writes;
953
+ // read swarm denied a spawned subagent write; write-swarm stayed confined
954
+ // (patchBytes=334, userTreeClean=true, worktreeCleaned=true); and the
955
+ // out-of-root absolute write was denied. NEW this release, and the reason the
956
+ // previous 0.30.0 smoke was green for the wrong reason: every isolated
957
+ // KIMI_CODE_HOME starts EMPTY and the indexer short-circuits on zero
958
+ // sessions, so the caveat path never ran. The populated-home case now asserts
959
+ // its OWN precondition (wire files > 0) and failed-loudly-or-proved rather
960
+ // than passing vacuously — it recorded index PRESENT with wire files=1 while
961
+ // writes stayed denied and no search index ever appeared in the workspace.
962
+ //
963
+ // RESIDUAL: write-swarm still runs against a session-less home, so "an
964
+ // un-awaited index sync cannot race the patch capture" is COMPOSED from two
965
+ // tests (index confined to KIMI_CODE_HOME; patch capture reads the ephemeral
966
+ // worktree) rather than observed end to end in one.
967
+ //
968
+ // 0.31 FOLLOW-UP (completed in v1.9.4): v1 custom agent files auto-scan project roots
969
+ // (`<git-root>/.kimi-code/agents`, `<git-root>/.agents/agents`) with NO flag
970
+ // gating, and an `override: true` file can replace the default `agent`
971
+ // profile. `AgentFileDefinition` carries no permission/hook/cwd field, so it
972
+ // reshapes the system prompt and the tool list only — every call still hits
973
+ // policy index 0, and our label allowlist fails closed on an unknown tool.
974
+ // It is a PROMPT-INJECTION surface for repo-scoped rescue/swarm-write, not a
975
+ // hook bypass. v1.9.4 documents this trust boundary in docs/safety.md.
976
+ // Daily monitor: 2026-07-29. Tag: compat-verified-kimi-code-0.30.0.
977
+ { major: 0, minor: 30 },
978
+ // 0.31.0 certified in v1.9.4 (2026-07-31) with one fail-closed runtime
979
+ // mitigation. Immutable tag audit: bc28e9d802fbec29395a7aed85e880679a050145.
980
+ // Canonical 0.30.0→0.31.0 scoped diffs were CLI 4,025 B, permission 0 B,
981
+ // hooks 0 B, wire/session 37,804 B, bootstrap/config 22,220 B, and the
982
+ // previously-audited v2 denial path 0 B. V1 keeps the index-0 hook, all-deny
983
+ // gap before first approve, any-block-wins hook aggregation, tool-input keys,
984
+ // standard swarm child stack, consumed argv, PromptJsonWriter shapes, terminal
985
+ // session hint, and create-only headless goal behavior. Parser/client tests
986
+ // passed 98/0/247 against the unchanged wire envelope.
987
+ //
988
+ // New v1 trust surface, documented rather than flattened: 0.31 discovers
989
+ // user/project/plugin custom agents and plugin system-prompt contributions.
990
+ // Project `override: true` can replace builtin `agent` or `coder` instructions
991
+ // and tool availability; the bound profile persists with the session. Profile
992
+ // schema cannot set hooks/permission/cwd or widen this plugin's allowlist, so
993
+ // this is prompt/task-fidelity risk, not a confinement bypass. Write-capable
994
+ // use in an untrusted repo must inspect those files first.
995
+ //
996
+ // CORRECTION to the 0.30.0 v2 judgement: external PreToolUse is awaited on
997
+ // ordinary calls, but production service order is permission gate → plan →
998
+ // swarm → external hooks. While plan mode is active, AgentPlanService
999
+ // final-allows a Write/Edit whose accesses target only the exact plan file;
1000
+ // final allow stops listener iteration before our hook. The path is confined
1001
+ // to KIMI_CODE_HOME, not the worktree, but violates the every-tool managed
1002
+ // hook contract. It is reachable fresh via user `default_plan_mode=true` and
1003
+ // on resume via restored PlanModel. The code is byte-identical in 0.30/0.31,
1004
+ // so this is newly discovered inherited evidence, not a new 0.31 regression.
1005
+ //
1006
+ // v1.9.4 therefore refuses upstream-equivalent truthy
1007
+ // KIMI_CODE_EXPERIMENTAL_FLAG values before spawn with
1008
+ // CLI_V2_HOOK_ORDER_UNSAFE / refusal_kind `v2-hook-order-unsafe`; unset/false
1009
+ // values preserve fresh and resumed default-v1 behavior. EnterPlanMode is
1010
+ // also explicitly denied for every managed label as defense in depth. Do not
1011
+ // re-enable v2 until an exact released tag orders external-hook veto before
1012
+ // every final allow and non-vacuous fresh-default-plan + restored-plan smoke
1013
+ // cases both prove the hook blocks the exact plan-file write.
1014
+ //
1015
+ // Exact-0.31.0 pre-mitigation smoke was GREEN 11/0/49 in 944.47s: all default
1016
+ // v1 forced writes, pursue budget, read-swarm child denial, write-swarm patch
1017
+ // capture/cleanup, and out-of-root denial passed; the populated-home case had
1018
+ // wire files=1 and kept the eager KAP index inside KIMI_CODE_HOME. The
1019
+ // ordinary fresh-v2 forced-write lane also denied, but did not cover
1020
+ // default_plan_mode and is not v2 certification. v1.9.4 replaces that lane
1021
+ // with an exact pre-spawn refusal assertion. The released 0.31.0 still
1022
+ // contains the KAP eager-index behavior; it is unreachable from plugin flows
1023
+ // while v2 is refused. MoonshotAI/kimi-code#2376 remains unmerged.
1024
+ //
1025
+ // 0.31.1 patch checkup (2026-08-01) verified COMPAT-PRESERVED inside the
1026
+ // already-tested 0.31.x minor. Scoped 0.31.0→0.31.1 diffs were:
1027
+ // 01-cli-prompt-mode 0 B, 02-permission 0 B, 03-hooks 0 B,
1028
+ // 04-wire-records 1,850 B, and 05-session-bootstrap 0 B. The sole canonical
1029
+ // delta adds a helper that strips the disabled no-op `model` parameter from
1030
+ // the Agent/AgentSwarm schemas. AgentSwarm keeps its exact tool name and
1031
+ // executor; the standard child permission stack, hook inheritance, cwd,
1032
+ // concurrency/timeout plumbing, and dispatch path are unchanged.
1033
+ //
1034
+ // The patch carries a large experimental-v2 refactor, but the print-mode
1035
+ // selection file and upstream truth table are byte-identical. The plugin
1036
+ // therefore still refuses every upstream-truthy KIMI_CODE_EXPERIMENTAL_FLAG
1037
+ // before spawn. The release supplies no external-hook-before-every-final-
1038
+ // allow guarantee, so it is not evidence for re-enabling v2. KAP global
1039
+ // search also remains App-scoped OnScopeCreated; #2376 is still unmerged.
1040
+ //
1041
+ // Exact-0.31.1 temp-binary smoke was GREEN: 10 pass / 0 fail, 42 assertions
1042
+ // in 349.27s. It denied every forced-write label, refused v2 before spawn,
1043
+ // kept pursue at zero writes through its finite-budget abort, denied a real
1044
+ // read-swarm child write, confined write-swarm (patchBytes=278,
1045
+ // userTreeClean=true, worktreeCleaned=true), and denied the non-vacuous
1046
+ // out-of-root coder write. Daily monitor: 2026-08-01. Tag:
1047
+ // compat-verified-kimi-code-0.31.1.
1048
+ { major: 0, minor: 31 },
1049
+ // 0.32–0.34 added in v1.9.6 (2026-08-08) after
1050
+ // auditing the cumulative 0.31.1→0.34.0 jump at immutable upstream commit
1051
+ // f0614c53e59f7e1e257412063b059b9eb82764cf. The scoped legacy-v1 permission,
1052
+ // hook, and bootstrap/config trees are 0-byte diffs; wire/session adds 55
1053
+ // internal v2-to-v1 resume lines without changing the consumed v1 envelope.
1054
+ //
1055
+ // The audit corrected a scope omission: 0.33.0 changed the selector in
1056
+ // experimental-v2.ts so unflagged print mode defaults to native v2. That
1057
+ // engine is still unsafe for this plugin because plan-file final allow can
1058
+ // stop listener iteration before the external PreToolUse hook. The runtime
1059
+ // containment therefore overwrites KIMI_CODE_LEGACY_FLAG=1 in every accepted
1060
+ // fresh/resumed child environment; truthy KIMI_CODE_EXPERIMENTAL_FLAG stays
1061
+ // an independent pre-spawn refusal. Older upstream releases ignore the
1062
+ // legacy flag. Native v2 is not certified or re-enabled by these entries.
1063
+ //
1064
+ // Exact-0.34.0 temp-binary smoke was GREEN: 11 pass / 0 fail, 54 assertions
1065
+ // in 460.09s. It proved fresh default_plan_mode=true and resumed sessions
1066
+ // remained on v1 with non-vacuous hook denials, denied every forced-write
1067
+ // label, bounded pursue, denied a real read-swarm child write, confined
1068
+ // write-swarm (patchBytes=278; user tree clean; worktree removed), and denied
1069
+ // the out-of-root coder write. Daily monitor: 2026-08-08.
1070
+ { major: 0, minor: 32 },
1071
+ { major: 0, minor: 33 },
1072
+ { major: 0, minor: 34 },
1073
+ // 0.35 added in v1.9.8 (2026-08-12) after the scoped source audit and
1074
+ // exact-binary smoke against immutable upstream commit
1075
+ // f6ee44e42641498f26635eec2e6799d13372885c. The canonical CLI, v1
1076
+ // permission, hook, and consumed wire/session surfaces were 0-byte diffs.
1077
+ // The 3,347-byte bootstrap diff only adds global MCP OAuth-status RPC
1078
+ // helpers; it does not alter -p session construction, hook merging,
1079
+ // permission context, cwd, or workspace-local config loading.
1080
+ //
1081
+ // Native v2 remains fail-closed: 0.35.0 still allows the plan listener to
1082
+ // final-allow exact plan-file writes before external hooks, so accepted
1083
+ // children stay pinned to legacy v1 and truthy experimental selectors still
1084
+ // refuse before spawn. The builtin coder profile also removes nested
1085
+ // Agent/AgentSwarm by default and builtin profiles are cloned per session;
1086
+ // neither change widens the plugin's write surface.
1087
+ //
1088
+ // Exact-0.35.0 temp-binary smoke was GREEN: 12 pass / 0 fail, 55 assertions
1089
+ // in 525.01s. Fresh/resumed default-plan runs stayed on v1 with hook-denied
1090
+ // writes; forced-write labels, pursue, read-swarm, write-swarm confinement,
1091
+ // and out-of-root denial all passed. Daily monitor: 2026-08-12.
1092
+ { major: 0, minor: 35 },
1093
+ // 0.36 added in v1.9.9 (2026-08-13) after the scoped source audit and
1094
+ // exact-binary smoke against immutable upstream commit
1095
+ // b6144f94ea6b22455a4e750d1750d220987e7bc2. The canonical CLI, v1
1096
+ // permission, and hook surfaces were 0-byte diffs. The wire/session diff
1097
+ // adds MCP OAuth credential coordination; bootstrap/config adds MCP OAuth
1098
+ // inspection plus v2 secondary-model pool config round-tripping. Neither
1099
+ // changes the supported -p stream, hook merge, permission context, cwd, or
1100
+ // workspace-local config loading.
1101
+ //
1102
+ // Native v2 remains fail-closed: 0.36.0 still allows the plan listener to
1103
+ // final-allow exact plan-file writes before external hooks, so accepted
1104
+ // children stay pinned to legacy v1 and truthy experimental selectors still
1105
+ // refuse before spawn. The added secondary-model pool keys are excluded
1106
+ // from the v1 derived-model patch recipe and do not widen write capability.
1107
+ //
1108
+ // Exact-0.36.0 temp-binary smoke was GREEN: 12 pass / 0 fail, 55 assertions
1109
+ // in 534.57s. Fresh/resumed default-plan runs stayed on v1 with hook-denied
1110
+ // writes; forced-write labels, v2 refusal, pursue, read-swarm, write-swarm
1111
+ // confinement, and out-of-root denial all passed. Daily monitor: 2026-08-13.
1112
+ { major: 0, minor: 36 },
1113
+ // 0.37–0.38 added in the 2026-08-24 compatibility catch-up after the
1114
+ // cumulative audit through immutable upstream commit
1115
+ // 0999454bdcb5ddd98f39bffee434dcf0a810f394 (tag @moonshot-ai/kimi-code@0.38.0).
1116
+ // Intermediate 0.37.0→0.37.1 and 0.37.1→0.37.2 scoped diffs were 0 bytes
1117
+ // across CLI prompt mode, permission, hooks, wire/session, and
1118
+ // session-bootstrap/config. The cumulative 0.36.1→0.38.0 audit likewise
1119
+ // found 0-byte CLI (except the off-path hidden __update_download command),
1120
+ // permission, and hook surfaces; 8,525 bytes of wire/session MCP OAuth and
1121
+ // background-write-drain plumbing; and 47,360 bytes of bootstrap/config
1122
+ // MCP registry/OAuth plus create/resume wiring with hook merge/cwd unchanged.
1123
+ // The 0.38.0 WaitFor tool is v2-only and remains outside the read-only
1124
+ // allowlist. Native v2 remains fail-closed: accepted children force
1125
+ // KIMI_CODE_LEGACY_FLAG=1, while truthy KIMI_CODE_EXPERIMENTAL_FLAG values
1126
+ // refuse before spawn; the plan-file final-allow ordering gap and KAP
1127
+ // follow-up therefore remain contained and uncertified.
1128
+ //
1129
+ // Exact-0.38.0 temp-binary smoke was GREEN: 12 pass / 0 fail, 55 assertions
1130
+ // in 381.64s. It denied every forced-write label, refused v2 before spawn,
1131
+ // kept fresh/resumed default-plan runs on v1, enforced the hook on every
1132
+ // pursue turn, denied a read-swarm child write, confined write-swarm
1133
+ // (patchBytes=278; user tree clean; worktree removed), and denied the
1134
+ // non-vacuous out-of-root coder write. Daily monitor: 2026-08-24.
1135
+ { major: 0, minor: 37 },
1136
+ { major: 0, minor: 38 },
1137
+ // 0.39.0 certified 2026-08-27 (same-day: npm publish 11:36Z, operator binary
1138
+ // self-upgraded within hours; tag @moonshot-ai/kimi-code@0.39.0, commit
1139
+ // 52e8d19d). Scoped diffs vs 0.38.0: CLI prompt mode (incl. the engine
1140
+ // selector experimental-v2.ts), permission, hooks, and wire/session all
1141
+ // 0-byte; bootstrap/config was 9,060 bytes of MCP-registry cwd threading +
1142
+ // OAuth verify tri-state only (create/resume session bootstrap and the
1143
+ // config/ dir byte-unchanged). The v1 tool-layer files outside the scoped
1144
+ // diffs (tools/policies/path-access.ts, tools/builtin/shell/bash.ts) are a
1145
+ // win32-only cygpath shell-path-bridge refactor, provably identity on POSIX
1146
+ // and post-hook defense-in-depth regardless; audits now also scope
1147
+ // packages/node-sdk/src (v1 portions) and packages/kaos/src, which are on
1148
+ // the -p path but were previously un-scoped (this release: additive/benign).
1149
+ //
1150
+ // New experimental features are both agent-core-v2-only and unreachable on
1151
+ // the pinned path: tower (KIMI_CODE_EXPERIMENTAL_TOWER; TUI /tower command;
1152
+ // zero agent-core presence, node-sdk setTowerMode hard-throws on v1) and
1153
+ // subagent fork (KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK / [experimental]
1154
+ // subagent_fork; the v1 flag registry cannot express either flag, and the
1155
+ // v1 AgentSwarm input schema is .strict() so a model-supplied fork arg is
1156
+ // rejected). Both are subsumed by KIMI_CODE_EXPERIMENTAL_FLAG, which still
1157
+ // refuses before spawn. Native v2 remains fail-closed: the plan listener
1158
+ // still final-allows exact plan-file writes before external hooks (sole
1159
+ // event.allow() call site; ordering is import-order with no contract, and
1160
+ // upstream's Permission.md documents the bypass as intended with listener
1161
+ // ordering an open design question), so accepted children stay pinned to
1162
+ // legacy v1. Remote Control (0.39.0, experimental) can patch hooks via a
1163
+ // tunneled config API; the per-spawn byte-exact hook verification catches
1164
+ // that as RECOVERABLE drift — fail-closed, no runtime change needed.
1165
+ //
1166
+ // Exact-0.39.0 temp-binary smoke was GREEN: 12 pass / 0 fail, 55 assertions
1167
+ // in 554.49s. It denied every forced-write label, refused v2 before spawn,
1168
+ // kept fresh/resumed default-plan runs on v1, enforced the hook on every
1169
+ // pursue turn, denied a read-swarm child write, confined write-swarm
1170
+ // (patchBytes=278; user tree clean; worktree removed), and denied the
1171
+ // non-vacuous out-of-root coder write. Reports 111-116; monitor 2026-08-27.
1172
+ //
1173
+ // 0.39.1 patch check certified 2026-08-29 (tag
1174
+ // @moonshot-ai/kimi-code@0.39.1, immutable commit 5efca0c3; published
1175
+ // 2026-08-28T10:01:03.520Z). All six playbook scopes are byte-identical to
1176
+ // 0.39.0: CLI prompt mode, permission, hooks, wire/session,
1177
+ // bootstrap/config, and v1 tools/SDK. Exact 0.39.1 and live upstream main
1178
+ // 9d2304c retain the same v2 plan-before-external-hook final-allow path; no
1179
+ // upstream issue/PR or released ordering API exists, so native v2 remains
1180
+ // fail-closed and the production capability matrix stays empty.
1181
+ //
1182
+ // The exact-0.39.1 temp binary passed the v1.9.12 release-candidate
1183
+ // smoke: 12 pass / 0 fail / 55 assertions in 400.68s. It proved forced-write
1184
+ // denials, v2 pre-spawn refusal, fresh/resumed default-plan legacy pinning,
1185
+ // pursue every-turn enforcement, real read-swarm child denial,
1186
+ // write-swarm confinement (patchBytes=278; user tree clean; worktree
1187
+ // removed), and out-of-root denial. Monitor: 2026-08-29.
1188
+ { major: 0, minor: 39 },
1189
+ // 0.40.0 certified 2026-09-02 (same-day: npm publish 05:58Z; tag
1190
+ // @moonshot-ai/kimi-code@0.40.0, immutable commit e27ee608; 48 commits
1191
+ // past 0.39.1). Scoped diffs vs 0.39.1: permission, hooks, and wire/session
1192
+ // all 0 bytes; CLI prompt mode is --yolo/--auto help text plus new
1193
+ // top-level `fork`/`session` subcommands (off the -p path — the plugin
1194
+ // passes the prompt as the VALUE of -p, never a bare positional);
1195
+ // bootstrap/config is one additive line (ModelAliasBaseSchema.protocol
1196
+ // widens to 'anthropic' | 'openai_responses'); v1 tools/SDK is additive
1197
+ // telemetry/session-list/tower plumbing with tool schemas (Write/Edit
1198
+ // `path`, Bash `command`), kaos, and the v1 createKimiHarness entry point
1199
+ // unchanged (the KimiHarness class gains one optional telemetry field that
1200
+ // entry point does not wire). The
1201
+ // whole packages/agent-core source tree changed by that one schema line.
1202
+ // KIMI_CODE_LEGACY_FLAG=1 still forces v1 for fresh and resumed -p at the
1203
+ // top of runPrompt(); engine selection reads only that env var and never
1204
+ // config, so no config.toml key (incl. [experimental] tables, which can
1205
+ // enable registered v1 flags without the env master switch — v1 registry
1206
+ // holds only tool-select/secondary-model) can defeat the pin. #3427's
1207
+ // config-beats-env flag precedence and #3434's legacy acp-adapter removal are
1208
+ // v2-only / off the -p transport.
1209
+ //
1210
+ // Native v2 stays fail-closed: plan feature (index.ts:330) still registers
1211
+ // before externalHooks (:338); planService.ts:112 is still the sole
1212
+ // event.allow(); toolExecutor/ is a 0-byte diff; MoonshotAI/kimi-code#3431
1213
+ // is open with no maintainer response. 0.40.0 ADDS a v2-only reason to keep
1214
+ // refusing: #3444 removed the RuntimeWorkspaceView.resolve() root assertion,
1215
+ // so v2 Bash can run with an out-of-workspace cwd (zero shared code with v1
1216
+ // or kaos). The new v2 dangerous-command ask policy sits before the first
1217
+ // approve but is skipped under nonInteractive (v2 print sets it) — inert
1218
+ // and not an ordering fix. The 2026-09-01 live repro, re-run 2026-09-02 on the
1219
+ // 0.40.0 binary, still bypasses the hook (REPRO_0391.md Run D).
1220
+ //
1221
+ // Operator-facing, not contract: v2 config writeback (#3392) now preserves
1222
+ // config.toml formatting per domain, so managed-block markers may survive
1223
+ // login/settings writes more often — the marker-less fallback fires less,
1224
+ // never incorrectly; `kimi doctor` now validates config against the v2
1225
+ // schema, whose hook schema is field-for-field identical to v1's.
1226
+ //
1227
+ // Exact-0.40.0 temp-binary smoke was GREEN: 12 pass / 0 fail / 55
1228
+ // assertions in 383.45s (after a morning auth-expiry false alarm — 3/9 with
1229
+ // auth.login_required and records=[] — cleared once operator auth was valid
1230
+ // again; an isolated-home kimi -p probe answered OK before the re-run). It
1231
+ // denied every forced-write label, refused v2 before spawn, kept
1232
+ // fresh/resumed default-plan runs on v1, enforced the hook on every pursue
1233
+ // turn, denied a read-swarm child write, confined write-swarm
1234
+ // (patchBytes=306; user tree clean; worktree removed), and denied the
1235
+ // non-vacuous out-of-root coder write. Reports 117-120; monitor 2026-09-02.
1236
+ { major: 0, minor: 40 },
1237
+ // 0.41.0 certified 2026-09-06; exact release commit 95478e8c.
1238
+ // Compared with 0.40.0: CLI prompt mode, permission, hooks, wire/session,
1239
+ // and bootstrap/config are 0 bytes; the entire v1 core is unchanged.
1240
+ // SDK suggestFiles is additive (v1 returns undefined), plus a comment edit.
1241
+ // Shared prompt-render/goal-prompt/prompt-session are also unchanged.
1242
+ // Env-only legacy selection, the two-entry v1 flag registry, hook index 0,
1243
+ // any-block-wins aggregation, tool input keys and trusted-root confinement
1244
+ // remain load-bearing. No parser, permission or engine-routing change.
1245
+ // Native v2 is NOT certified: plan still precedes external hooks
1246
+ // (index.ts:329/341); planService.ts:110 final-allows the exact plan file.
1247
+ // staleGuard and the old Permission.md are removed; auto-mode dangerous
1248
+ // command checks are skipped. None establishes external-hook precedence.
1249
+ // Exact same-day monitor smoke: 12 pass / 0 fail / 55 assertions, 383.88s.
1250
+ // Fresh v2 reproduction: hook blocks Glob, plan Write bypasses it; v1
1251
+ // control blocks Write. Reused evidence predates only this boundary/docs
1252
+ // patch, not a behavior change. Reports 121-125; monitor 2026-09-06.
1253
+ { major: 0, minor: 41 },
1254
+ ];
1255
+ /**
1256
+ * Spawn `<kimi-bin> --version` and parse the output. Never throws;
1257
+ * failures resolve to `{kind: "failed", reason}` so callers can decide
1258
+ * the policy. The kimi binary path defaults to bare `kimi` (PATH
1259
+ * lookup); callers that need an explicit absolute path should pass it.
1260
+ *
1261
+ * Output contract: kimi-code 0.1.x and 0.2.x both write a single line
1262
+ * like `0.2.0` (sometimes with leading "v") to stdout and exit 0. We
1263
+ * tolerate either form and any trailing whitespace.
1264
+ */
1265
+ export async function probeKimiVersion(options) {
1266
+ const bin = options.kimiBin ?? "kimi";
1267
+ const args = [...(options.prefixArgs ?? []), "--version"];
1268
+ const timeoutMs = options.timeoutMs ?? KIMI_VERSION_PROBE_TIMEOUT_MS;
1269
+ return await new Promise((resolve) => {
1270
+ let settled = false;
1271
+ const settle = (result) => {
1272
+ if (settled)
1273
+ return;
1274
+ settled = true;
1275
+ resolve(result);
1276
+ };
1277
+ let child;
1278
+ try {
1279
+ child = spawn(bin, args, {
1280
+ cwd: options.cwd,
1281
+ env: options.env,
1282
+ stdio: ["ignore", "pipe", "pipe"],
1283
+ });
1284
+ }
1285
+ catch (err) {
1286
+ settle({
1287
+ kind: "failed",
1288
+ reason: `spawn failed: ${err.message}`,
1289
+ });
1290
+ return;
1291
+ }
1292
+ let stdout = "";
1293
+ let stderr = "";
1294
+ child.stdout.setEncoding("utf8");
1295
+ child.stderr.setEncoding("utf8");
1296
+ child.stdout.on("data", (chunk) => {
1297
+ stdout += chunk;
1298
+ });
1299
+ child.stderr.on("data", (chunk) => {
1300
+ stderr += chunk;
1301
+ });
1302
+ const timer = setTimeout(() => {
1303
+ try {
1304
+ child.kill("SIGTERM");
1305
+ }
1306
+ catch {
1307
+ // best effort
1308
+ }
1309
+ settle({
1310
+ kind: "failed",
1311
+ reason: `\`${[bin, ...args].join(" ")}\` timed out after ${timeoutMs}ms`,
1312
+ });
1313
+ }, timeoutMs);
1314
+ child.on("error", (err) => {
1315
+ clearTimeout(timer);
1316
+ settle({
1317
+ kind: "failed",
1318
+ reason: `spawn error: ${err.message}`,
1319
+ });
1320
+ });
1321
+ child.on("close", (code) => {
1322
+ clearTimeout(timer);
1323
+ if (code !== 0) {
1324
+ const detail = stderr.trim() !== "" ? stderr.trim() : `exit ${code}`;
1325
+ settle({
1326
+ kind: "failed",
1327
+ reason: `\`${[bin, ...args].join(" ")}\` failed: ${detail}`,
1328
+ });
1329
+ return;
1330
+ }
1331
+ const parsed = parseVersionLine(stdout);
1332
+ if (parsed === undefined) {
1333
+ settle({
1334
+ kind: "failed",
1335
+ reason: `could not parse \`${[bin, ...args].join(" ")}\` output: ${JSON.stringify(stdout.slice(0, 80))}`,
1336
+ });
1337
+ return;
1338
+ }
1339
+ settle({
1340
+ kind: "ok",
1341
+ version: parsed.raw,
1342
+ major: parsed.major,
1343
+ minor: parsed.minor,
1344
+ patch: parsed.patch,
1345
+ inTestedRange: isInTestedRange(parsed.major, parsed.minor),
1346
+ });
1347
+ });
1348
+ });
1349
+ }
1350
+ /**
1351
+ * Parse a `kimi --version` stdout into a structured version. Accepts
1352
+ * bare semver (`0.2.0`), `v`-prefixed (`v0.2.0`), and trailing
1353
+ * pre-release / build metadata (`0.2.0-beta.1`, `0.2.0+sha.abc`). The
1354
+ * major/minor/patch numbers are the leading three components only —
1355
+ * pre-release / build metadata is preserved in `raw` but doesn't
1356
+ * affect the tested-range check.
1357
+ *
1358
+ * Returns undefined when the leading line doesn't look like a version.
1359
+ */
1360
+ export function parseVersionLine(stdout) {
1361
+ const firstLine = stdout.split(/\r?\n/).find((line) => line.trim().length > 0);
1362
+ if (firstLine === undefined)
1363
+ return undefined;
1364
+ const trimmed = firstLine.trim().replace(/^v/, "");
1365
+ const match = trimmed.match(/^(\d+)\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.-]+)?$/);
1366
+ if (match === null)
1367
+ return undefined;
1368
+ return {
1369
+ raw: trimmed,
1370
+ major: Number.parseInt(match[1], 10),
1371
+ minor: Number.parseInt(match[2], 10),
1372
+ patch: Number.parseInt(match[3], 10),
1373
+ };
1374
+ }
1375
+ export function isInTestedRange(major, minor) {
1376
+ return KIMI_TESTED_MINORS.some((entry) => entry.major === major && entry.minor === minor);
1377
+ }
1378
+ /**
1379
+ * The newest `{major, minor}` in the tested set — the known-good upper bound
1380
+ * (H9). Set-membership in `isInTestedRange` already warns for anything outside
1381
+ * the tested range; this lets the warning distinguish the COMMON case (a kimi
1382
+ * release NEWER than our last compat audit — likely fine but unverified) from a
1383
+ * below/gap version, which is the more suspicious shape.
1384
+ */
1385
+ export function maxTestedMinor() {
1386
+ return KIMI_TESTED_MINORS.reduce((max, entry) => entry.major > max.major || (entry.major === max.major && entry.minor > max.minor)
1387
+ ? entry
1388
+ : max);
1389
+ }
1390
+ /**
1391
+ * Format a user-facing warning line for an out-of-range version probe.
1392
+ * Setup itself may complete, but the execution-plan gate will refuse model
1393
+ * spawns until the operator selects a certified binary or updates the plugin.
1394
+ */
1395
+ export function formatVersionOutOfRangeWarning(probe, pluginVersion) {
1396
+ const tested = KIMI_TESTED_MINORS.map((entry) => `${entry.major}.${entry.minor}.x`).join(", ");
1397
+ const max = maxTestedMinor();
1398
+ const aboveMax = probe.major > max.major || (probe.major === max.major && probe.minor > max.minor);
1399
+ const lines = [
1400
+ `WARNING: kimi-code version ${probe.version} is outside the range kimi-plugin-cc ${pluginVersion} was tested against (${tested}).`,
1401
+ ];
1402
+ if (aboveMax) {
1403
+ // H9: the known-good upper bound. Above it = a release newer than our last
1404
+ // compat audit — unverified, and exactly the case the version probe exists
1405
+ // to flag when out-of-band auto-upgrade drifts the binary.
1406
+ lines.push(` This is NEWER than the newest version we have tested (${max.major}.${max.minor}.x) and is not yet certified for model execution.`);
1407
+ }
1408
+ lines.push(` Setup can complete, but model-spawning commands will refuse before Kimi starts rather than run an unreviewed engine/version route.`, ` Update kimi-plugin-cc to a release that certifies this minor, or point KIMI_PLUGIN_CC_KIMI_BIN at a certified kimi-code binary and retry setup.`, ` KIMI_PLUGIN_CC_SKIP_VERSION_PROBE is a test/smoke seam, not a production compatibility override.`);
1409
+ return lines.join("\n");
1410
+ }