# Changelog > **Post-1.0 release history (v1.0.1 -> present) lives in [ROADMAP-TO-GA.md § Post-GA audit log](./ROADMAP-TO-GA.md#post-ga-audit-log)** and the "Version" / "Upstream compat" lines of [AGENTS.md](./AGENTS.md). Docs-only kimi-code compat checkups that don't bump the plugin version (e.g. the 0.14.2 / 0.14.3 patches) are recorded there, not here. Notable releases are summarized below; the GA entry and full pre-GA detail follow. ## 2.5.2 — 2026-11-02 - Preserve TOML multiline values, line endings, and foreign hook fields during setup; repair mixed-host orphan marker comments without altering foreign hooks. - Keep the DSH disposal grace at least 6000ms, pin a stable Node path, and expose each Kimi tool's write boundary to the model. - Treat DSH services and its tool adapter as host-provided peers so ordinary npm consumers do not install the harness. Require patched DSH host/profile dependencies and audit both installations before the seven-tool composition and Web-boot smoke. - Add an installed-consumer security gate to CI and publication; reject failed or incomplete audits as well as high/critical advisories. Upstream DSH pins remain vulnerable, so existing installations require the documented explicit overrides. - Validate exact Kimi Code 2.4.1 with 24 real-binary smoke tests (167 assertions, no skips) and the 16-test exact-source audit; certification remains unchanged. ## 2.5.1 — 2026-11-01 - Consolidate DSH distribution into the existing `kimi-plugin-cc` npm package and its established OIDC publication path. DSH users install the same root artifact with `dsh plugin --profile add kimi-plugin-cc`; no second npm package or Trusted Publishing binding is required. - Declare the root DSH bundle entry, runtime dependencies, and peer compatibility directly in `package.json`, and validate root-tarball installation, seven-tool composition, and Web boot in an isolated DSH profile. - Pin transitive `zod` and `undici` versions in the checkout lockfile, remove the unnecessary full DSH CLI development dependency, install pnpm explicitly in CI, and exclude dependency directories from installed-script fixtures. Downstream npm consumers do not inherit those overrides; see the consumer-security release gate. ## 2.5.0 — 2026-11-01 - Add DeepSeek Harness as a third host with native `kimi_ask`, `kimi_review`, `kimi_challenge`, `kimi_rescue`, `kimi_pursue`, `kimi_swarm`, and `kimi_swarm_write` providers. Reuse the existing companion and `kimi -p` transport, managed hooks, exact-version certification, SQLite jobs, budgets, artifacts, and process lifecycle; no ACP transport. - Add DSH-owned setup, model inventory, host-scoped uninstall, and job controls, plus profile-level model, thinking, budget, review-base, data-root, environment, output, and teardown settings. Preserve read-only denials, real-workspace rescue/pursue writes, and patch-only swarm-write. - Package `dsh-kimi-plugin-cc` as an independently installable npm bundle with its own pack/install/composition/Web-boot gate. Publish root and DSH tarballs together through the existing OIDC workflow, with Node 24 CI and verified composition on DSH 0.2.1-rc.5 and 0.2.2-alpha.2. - Verify live DSH delegation: `kimi_ask` returns `4`, a managed-hook write denial creates no file, rescue writes only `DSH_OK`, and a two-target swarm-write returns a valid patch without applying it or touching the real workspace. - Update installation, safety, model, registry, contributor, and multilingual README guidance. Reduce `AGENTS.md` from 32,704 to 21,291 bytes by keeping detailed mechanics in owning references, and enforce a 24 KB ceiling. ## 2.4.5 — 2026-10-31 - Certify exact kimi-code 2.4.1 for all eight native-v2 operations after exact-source review, plan and swarm controls, and candidate/production smoke. See [evidence](docs/upstream-2.4.1-certification.md). - Add only the reviewed 2.4.1 activation and hook-schema entries. Preserve no-plan enforcement, workspace confinement, concurrency, bounded cleanup, durable recovery, and the legacy-v1 0.41.x boundary. - Strengthen certification smoke to require same-call managed denials and real multi-turn journal evidence, and expand negative version coverage across every operation. Include the current certification record in the npm package. - Review Read output/token limiting and goal/plan prompt changes without changing the tool execution, session provenance, or swarm activation contracts. Update the manual smoke default and current compatibility documentation; installed hosts remain unchanged. ## 2.4.4 — 2026-10-29 - Certify exact kimi-code 2.4.0 for all eight native-v2 operations after exact-source review, revised plan and swarm controls, and candidate/production smoke. See [evidence](docs/upstream-2.4.0-certification.md). - Adapt certification to removed EnterPlanMode and fresh-print default-plan cancellation without relaxing config, hook-deny, or journal-taint closures. Add only the reviewed 2.4.0 activation and hook-schema entries. - Allow a bounded 15 seconds for graceful web shutdown after exact 2.4.0 exceeded the prior 5-second bound and exited cleanly in 6.743 seconds. Disable ambient idle-session reclamation for plugin-owned lifecycle processes. Preserve cleanup verification, process identity, durable recovery, workspace confinement, concurrency, and the legacy-v1 0.41.x boundary. - Reject ignored sync-conflict copies during package validation so local generated debris cannot silently enter the npm archive. ## 2.4.3 — 2026-10-27 - Certify exact kimi-code 2.3.3 for all eight native-v2 operations after exact-source review, plan and swarm controls, and candidate/production smoke. See [evidence](docs/upstream-2.3.3-certification.md). - Add only the reviewed 2.3.3 activation and hook-schema entries. Preserve no-plan enforcement, workspace confinement, concurrency, bounded cleanup and durable recovery; legacy-v1 remains capped at 0.41.x. - Expand the compatibility audit to cover the web activation server explicitly, and refresh current compatibility/status documentation without changing installed hosts. ## 2.4.2 — 2026-10-26 - Integrate community PR #22's structured spawn-error classification, preserving contributor history. Bound the additional diagnostic message. Known argument/resource exhaustion no longer receives reinstall advice. - Refuse oversized Windows command lines before spawn and add a credential-free compiled-runtime Windows CI lane. This improves diagnosis, not prompt transport; issue #14 remains open for native Windows/community verification and large-review support. - Add durable, preview-first `recover-swarm` for exact 2.3.2 interrupted runs, with verified process ownership, pre-mutation session identity, recovery locking, explicit uncertainty refusals and patch preservation. Stop age-based deletion of abandoned worktrees. Exact CLI certification remains unchanged through 2.3.2. - Shorten the agent contract sheet and enforce its 32 KiB limit during `check`. Thanks to **@Nitjsefnie** for PR #22. ## 2.4.1 — 2026-10-25 - Certify exact kimi-code 2.3.2 for all eight operations using the 15-test/92-assertion source scan, plan-ON/OFF controls, and the final 19-test/125-assertion production smoke. Keep the no-plan construction and legacy-v1 boundary at 0.41.x. See [evidence](docs/upstream-2.3.2-certification.md). - Preserve swarm support after upstream removed model self-activation: exact-version, authenticated loopback activation creates a same-job session with the selected model, auto permission, and plan mode off, then resumes through ordinary `kimi -p`. `runSwarm` solely owns bounded deactivation and verifies the journal; older certified versions stay on direct print. - Bind activation to exact provenance, finite budgets, process identity, and session identity (`preactivated`). Failure recovery is cancellation-aware and preserves primary print errors. Unknown late-fork or changed-PGID survivors remain unverified, never false quiescence or unproven signal targets. Cleanup failure blocks completion and retains raw output, structured diagnostics, and the write worktree. MCP uses the same implementation and existing task/job ownership. - Close a certification blind spot found by adversarial review: AgentSwarm call records, aggregate denial text, and coordinator-only patches no longer count as fan-out. Smoke requires distinct child journals and correlates each assigned Write/Edit path and toolCallId with its own denial or successful result; the final production run passed 19/19 with 125 assertions in 296.67 seconds. Contributors: **Kimi** (source audit, design, implementation, documentation, and verification), **Claude** and **Codex** (adversarial review and re-review). ## 2.4.0 — 2026-10-24 - Add one dependency-free MCP stdio server for Claude Code and Codex, with typed schemas for seven model operations plus job status, result, and cancellation. The existing slash commands, skills, safety hooks, and review gate remain intact. - Return native MCP task handles for Claude calls that negotiate the tasks extension per request. Codex receives ordinary launch handles and uses explicit job-control tools; this does not claim native task-extension support for Codex. - Supervise each operation through a fixed task/job UUID, bounded attachment, durable reconnects, and PID/PGID/start-token identity checks. Preserve recoverable launches and their public IDs after inconclusive probes, reconcile stale dead companions, and keep cancellation from signalling a changed identity. - Preserve exact CLI 2.3.1 certification, workspace containment, data-root isolation, hook verification, resume lineage, and trusted write roots. Terminal jobs retain their artifact semantics: failed jobs complete tasks with `isError:true`, and cancelled jobs map to `cancelled`. - Document the transport, lifecycle, ownership, safety, comment-hygiene, and contributor rules. Align package and marketplace descriptions and keywords with the MCP surface. Contributors: **Kimi** (design, implementation, documentation, and verification), **Claude** and **Codex** (adversarial review and re-review). ## 2.3.1 — 2026-10-23 - Certify exact kimi-code 2.3.1 for all eight native-v2 operations after the source scan, plan-ON/OFF controls and full 15-test candidate smoke. Preserve the no-plan construction and document the new session-lock, internal-`ps`/PATH and legacy-trust-migration residuals. See [evidence](docs/upstream-2.3.1-certification.md). - Give Kimi clearer operation-specific contracts: evidence-backed ask/review/challenge responses, complete rescue implementation and verification, honest pursue budgets, and a host-neutral, evidence-only review gate. Keep raw task text in job summaries and fallback titles while the full prompt drives execution and recovery. - Include untracked files in working-tree reviews, keep `--base` snapshots isolated from dirty files, and make truncated-diff coverage explicit. Pursue now uses `/goal --` and enforces the 4000-character objective budget including injected guidance; swarm prompts distinguish soft total counts, hard concurrency and prompt-only coordination. - Remove roughly 2,300 lines of stale or duplicated release archaeology from production comments while retaining current safety invariants. Capture the durable prompt, scope, comment-hygiene and release rules in `AGENTS.md`, `CONTRIBUTING.md` and the compatibility docs. - Make missing-session-ID warnings distinguish resume from replay, and fail write-swarm patch capture explicitly when intent-to-add fails instead of silently omitting new files. Capture failures now fail the job and retain the worktree for recovery; successful runs preserve the `[swarm-write]` summary prefix. ## 2.2.2 — 2026-10-22 - Certify exact kimi-code 2.3.0 for all eight native-v2 operations after its source scan, plan-ON/OFF controls and full candidate smoke; legacy support remains capped at 0.41.x. See [evidence](docs/upstream-2.3.0-certification.md). - Preserve CLI 2.3.0's stdout-only occupied-session refusal as bounded structured diagnostics, without treating it as prose, session lineage or an exit-status override. Marker-first provenance checks are unchanged. - Audit and pin the new stale-session reload path. Concurrent edits to trusted operator journals remain an explicit residual; no new hook bypass within the existing trust boundary was demonstrated. Clarify the no-plan certification gates and remove stale ordering-gate instructions. ## 2.2.1 — 2026-10-15 - Request per-run thinking effort with `--thinking ` through the upstream environment binding; persist requested effort and replay it in detached workers without changing saved defaults. The review gate requests `off` by default; provider/model no-op cases remain explicit. - Add the hook-escape monitor as detection evidence: replay the pure PreToolUse policy on every streamed tool call and record, for each policy-denied call, whether the model received the managed hook's denial (byte-exact or with upstream's repeat-breaker decoration). Findings (`mismatch`, `unresolved`) are logged, persisted on the job (`hook_escapes`), shown in `status`/`result --json`, printed as a stderr notice and carried in timeout details; the run is never stopped and the job never fails on them, because upstream's pre-hook rejections, coexisting hooks and the repeat breaker produce the same text as a drifted hook. Proven live on CLI 2.2.0 with a deliberately broken hook command (`Write` executed; finding `mismatch`, excerpt `Wrote 7 bytes to ESCAPE.txt`). - CLI 2.2.0 remains the certified maximum, unchanged; hook policy decisions, preflight closures, engine selection and teardown are unchanged. ## 2.2.0 — 2026-10-15 - Port the vendored parser to unmodified smol-toml 1.9.1 JavaScript, closing GHSA-r4xh-jqrq-34v2; adapt the config assignment walker and retain EOF-comment protection with linear-scaling and shipped-mirror regressions. - Recover native-v2 timeout session IDs only from exactly one bounded, matching session-store candidate: created between spawn and settlement in the job's cwd, and whose main journal opens with a user message carrying the job's exact prompt (`prompt_digest`), so attribution is proof, not proximity. Persist announced/recovered provenance in `kimi_session_id_source`, report recovery refusals in error details (`session_recovery`), skip recovery when no `system.version` marker was observed, and retain the existing lineage and raw journal plan-taint checks on every resume. - Expose `budget_source` in status and JSON results, and print inherited ask/rescue budgets with their parent job at launch. Historical non-null budgets remain unknown. - Allow 30 seconds for installed-state spawn-heavy tests; refresh install examples and preserve the settled result's abort flag in timeout details. - Permit deliberate plugin/CLI version-number alignment without treating the number as compatibility evidence. CLI 2.2.0 remains the certified maximum, unchanged; the certification table, hook policy, preflight closures and teardown remain unchanged. ## 2.0.8 — 2026-10-14 - Certify exact Kimi Code CLI 2.2.0 (`472192c3`) for all eight native-v2 operations under the unchanged no-plan construction: four source reviews, 15/15 tag scan (all twelve pinned files byte-identical to 2.1.1), plan-ON/OFF controls (bypass still reproduced; refusal still load-bearing) and the full 15-test candidate smoke. Accept only the reviewed exact 2.2.0 hook schema. See [certification evidence](docs/upstream-2.2.0-certification.md). - Add per-job `--budget` to ask, rescue, review, and challenge, with defaults of 30m for ask/review/challenge and 45m for rescue, with a 24h ceiling. Detached workers reload the persisted budget from SQLite; resumes inherit it unless overridden. Pursue/swarm persist their effective ceilings. Backgrounding does not extend it. - Preserve settled partial assistant output on budget timeout (and the session ID when Kimi announced it before the deadline; native v2 announces at session end). Jobs remain failed, artifacts label partial output as NOT a final answer, and cancellation does not capture partial output. - Preserve clean, non-aborted exit-0 success at the timeout boundary; retain `settled_post_abort` diagnostics for timeouts. Strip ambient workspace-trust overrides from every child to prevent project MCP bootstrap outside tool hooks. - Remove misleading timeout race wording, expose budget/count metrics, and give context-aware budget/scope advice with a pointer to the failed artifact. - Add stdout `--help`/`-h` for companion subcommands from shared flag definitions. Review and challenge remain foreground-only. - Regenerate both host distributions and document budget and partial-output behavior across commands, agents, and Codex skills. - Bump the test-only `smol-toml` dependency 1.8.0 → 1.9.1 for GHSA-r4xh-jqrq-34v2 (quadratic `parseKey`). The vendored 1.6.1 parser subset that the plugin ships shares the bounded quadratic behaviour on the operator's own `config.toml` only; measured and documented in `runtime/vendor/smol-toml/README.md`, with the 1.9.x port scheduled as its own integration review. ## 2.0.7 — 2026-09-26 - Add npm distribution as `kimi-plugin-cc`, with an explicit file allowlist and compiled runtime for both Claude Code and Codex. No install scripts or build tools run on the user's machine; the existing GitHub marketplaces still work. - Verify the actual tarball after extraction: both host setup/check probes must enforce the hook in isolated homes, and both distributions must refuse an unsupported CLI version. No credentials or model calls are used by this check. - Add tag-verified GitHub Actions publishing with npm Trusted Publishing and document the first-publish bootstrap and registry installation path. - Runtime behavior and exact upstream certification remain unchanged from 2.0.6. ## 2.0.6 — 2026-09-24 - Certify exact Kimi Code CLI 2.1.0 and 2.1.1 for all eight native-v2 operations under the no-plan construction. Previous certified versions remain supported; legacy-v1 stays capped at 0.41.x. - Review both exact hook schemas and pin their source hashes. Unreviewed versions, prereleases and build suffixes remain refused. Update the recommended CLI and manual smoke default to 2.1.1. - Verify each candidate independently with a 15-test tag scan, plan-ON/OFF controls and the complete sequential live smoke. The active-plan bypass remains, so managed sessions continue to refuse plan mode. - Document trusted repository Git configuration: internal explorer Git commands can execute helpers outside tool hooks, including read-only swarm. 2.1.1 rolls back much of 2.1.0's path/Git hardening to the certified 2.0.2 baseline. - See [certification evidence and validation](docs/upstream-2.1-certification.md). Publication does not update installed hosts or the operator CLI. ## 2.0.5 — 2026-09-20 - Fix lockfile-clean TypeScript 7.0.2 emission for `repair-sessions` by binding SQLite constructors before `new`. Preserve read-only database access and preview behavior. - Add four compiled-runtime regressions: root and Codex distributions each run under Node and Bun against a real fixture database. All four failed before the fix and passed afterward; all 14 repair-session tests pass. - Frozen-dependency full check: 902 passed, 28 opt-in skips, zero failures, 3,015 assertions. Dependency audit and both final reviews passed. - Rebuild both hosts with frozen dependencies. Require a successful CI check before tagging and publishing future releases. v2.0.4's local check used stale TypeScript 6.0.2 dependencies and missed the emitted-code failure; its published tag remains unchanged. - Exact CLI certification stays through 2.0.2. No hook, plan-mode, permission, swarm or installed-host changes. See [build-fix evidence](docs/release-2.0.5-build-fix.md). ## 2.0.4 — 2026-09-20 - Certify exact Kimi Code CLI 2.0.2 for all eight native-v2 operations under the unchanged no-plan safety construction. Previous certified versions remain supported; legacy-v1 stays capped at 0.41.x. - Accept only the reviewed exact 2.0.2 hook schema and pin its source hashes. Future versions, prereleases and build suffixes remain refused. - Verification: four source reviews, exact tag scan 15/15, plan-ON/OFF controls and sequential live smoke 15/15 (84 assertions), with no retries. The known upstream plan-file bypass persists; managed sessions still refuse plan mode. See [certification evidence and limitations](docs/upstream-2.0.2-certification.md). - Final `bun run check`: 898 passed, 28 opt-in skips, zero failures, 2,987 assertions on an identical staged-tree snapshot in a clean temporary worktree. The original checkout hit filesystem-copy timeouts; no test limits or assertions were relaxed. - Plugin 2.0.4 and upstream CLI 2.0.2 are independent version numbers. This release does not update installed hosts or re-pin their hooks. ## 2.0.3 — 2026-09-19 - Certify exact Kimi Code CLI 2.0.1 for all eight native-v2 operations. Review and pin its same-wire restore-chain API and unchanged hook schema; future patches remain fail-closed. Exact tag scan 15/15, plan-on/off controls passed, live smoke 15/15 with no retries. See [certification evidence](docs/upstream-2.0.1-certification.md). - Fix repeated pursue goal-tool denials: trusted per-spawn operation metadata permits only current-goal reads and terminal complete/blocked updates. Rescue workspace restrictions, plan refusal and wall-clock limits remain unchanged. Remove the misleading SetGoalBudget prompt hint; turn counts remain soft. - Validation: `bun run check` passed (898 passed, 28 opt-in skips, zero failures, 2,965 assertions). - Keep plugin versions independent of upstream using ordinary SemVer. Plugin 2.0.3 certifies CLI 2.0.1; published versions are never reused. - Older coexisting host hooks can still veto goal tools. Updating and re-pinning each host requires its own authorization; no installed Claude Code hook was changed in this slice. ## 2.0.2 — 2026-09-18 Plugin-only maintenance release. Kimi Code CLI certification remains unchanged through exact 2.0.0; this does not certify upstream 2.0.1 or 2.0.2. - Restore visibility of completed native-v2 plugin sessions in Kimi Code Desktop and Web by filling missing redacted prompt previews and notifying the shared session index. - Keep new fallback titles replaceable by Kimi's native generation. Preserve manual and already-generated titles. The plugin does not call the native title endpoint automatically because it resumes an agent; use Desktop's Gen Title action or continue an eligible session there. - Add `repair-sessions [--apply] [--all]`: preview existing-session repairs by default, recover prompts from bounded invocation logs with digest and provenance checks, and preserve titles, existing previews and session journals. - Redact fallback-title source text before truncation and detect changed state before atomic publication. Report index-notification failures separately so an idempotent repair can retry them. - Validation: full `bun run check` passes with 881 tests, 26 opt-in skips, and no failures. Ten local sessions were repaired and became visible after Desktop refresh. One native generated title and its transcript were verified after refresh. Separate Web browser rendering was not exercised. See [session visibility and titles](./docs/session-visibility.md). Update Codex or Claude Code independently, then run that host's setup command to re-pin its versioned hook. ## 2.0.1 — 2026-09-17 Plugin-only maintenance release. The recommended certified Kimi Code CLI remains 2.0.0; the exact certification table is unchanged. - Harden plugin data-root selection against shared host environment pollution (#13). Standard cache installs verify ownership, custom locations can use `KIMI_PLUGIN_CC_DATA`, and conflicts fail before store access. Existing state is not moved. Background workers keep the selected root; the Stop hook reports a visible skip on conflicts. - Handle first-run symlinked homes before data directories exist, and require an explicit data root for fully sanitized launches without a home instead of using a shared `/tmp` fallback. - Refresh the README with English, Chinese, French, and Japanese onboarding and screenshots from both hosts. Update safety, migration, contributor, test, and CI documentation. Correct reasoning-setting guidance and default the manual smoke workflow to CLI 2.0.0. - Validation: `bun run check` passes with 861 tests, 26 opt-in skips, and no failures. No real-provider calls are needed for this data-routing change. After updating, run the setup command from each updated host to re-pin its hook. If `PLUGIN_DATA_CONFLICT` is reported, follow its expected-directory remedy or deliberately set the absolute `KIMI_PLUGIN_CC_DATA` parent for your existing custom store. No data is migrated automatically. ## 2.0.0 — 2026-09-17 **Certifies exact kimi-code 2.0.0 for native agent-core-v2 across all eight operations.** Starting here, plugin certification releases use the same version number as the upstream release they certify. Previous exact native-v2 versions remain supported; the legacy table stays capped at 0.41.x. Setup now accepts PermissionRequest, PermissionResult and Interrupt on the reviewed exact 2.0.0 schema. Future patches/minors, prereleases and other nonzero versions remain refused for those events. Hook policy, workspace allowlist and no-plan preflight behavior are unchanged. Model selection now includes a credential-safe offline inventory through `setup --models [--json]`, native subscription/API-provider setup guidance, and model-choice instructions for both Claude and Codex. Fresh tasks use the default; named requests resolve configured aliases without a silent fallback. The review gate now follows the default unless its model override is set. See [models and provider setup](./docs/models.md). Evidence: - Exact source `1b89e4b0`: tag scan 15/15, including new hook-schema pins. The wire flush now drains the same agent journal directly; swarm eviction and rebuild retain normal lifecycle creation and eager child hooks. - Plan-ON reproduced the known bypass (769-byte plan, hook saw Glob only); plan-OFF denied both Write and EnterPlanMode without creating files. - Full candidate smoke: 12 passed, one failed its fan-out precondition (no AgentSwarm call, no escape files). After clarifying that the paths are authorized disposable negative-test fixtures, a targeted retry passed with the original assertions and a surfaced hook-denial reason. All 13 cases are covered by the full run plus that retry; this was not a clean single run. - Goal mode: five turns over the two-minute budget, zero writes. Write-swarm: 278-byte patch, user tree clean, worktree removed. Resume/taint lanes passed. - Final `bun run check` after model-selection additions: 847 pass / 26 skip / 0 fail; build, typecheck, generated surfaces and drift gate passed. Fake-credential fixtures cover secret-free inventory/errors, no writes, environment defaults, explicit aliases and resume, and default/override review-gate argv. Both compiled host entrypoints passed an offline fixture without provider calls. - An authorized live Moonshot K3 API test completed through an explicit configured alias; the saved subscription default remained unchanged. The smoke harness can select an exact audited v2 candidate before production certification, with an exact-binary mismatch refusal and a test-process-only write-swarm capability row. Temporary config/OAuth copies were explicitly authorized for this run and removed afterward. After upgrading either host, run its setup command to refresh the version-stamped hook path. ## 1.10.3 — 2026-09-15 **Certifies kimi-code 0.43.0 and 0.43.1 for native agent-core-v2 (all eight operations).** kimi-code published 0.43.0 on 2026-09-14 and 0.43.1 on 2026-09-15; the operator's binary auto-upgraded to 0.43.1 the same morning, so every model-spawning command on an auto-updating host had started refusing with `KIMI_CAPABILITY_NOT_CERTIFIED`. `NATIVE_V2_CERTIFIED_VERSIONS` is now `0.42.0, 0.43.0, 0.43.1`. No approval-policy, allowlist, hook, preflight or engine-selection change. Certification evidence (per docs/upstream-compat-audit.md, all three gates, per exact version): - **Tag scan** (`tests/audit/v2-tag-scan.test.ts`): 15/15 on the exact 0.43.0 and 0.43.1 source trees (and still 15/15 on 0.42.0). New hash rows for both versions; the seven load-bearing files are byte-identical between 0.43.0 and 0.43.1, and five of them are byte-identical to 0.42.0. The two that changed are upstream's restore refactor (`state/eventDispatcherService.ts`, `state/state.ts`): patch-history undo replaced by in-memory state snapshots, and `restore()` now folds `wire.readRestorable()` before `wire.readJournal()`. `readRestorable()` is `readStableEntries()` over the same `wire.jsonl` append-log filtered by the pure `restorableChain()` (`wire/tree/fork.ts`) — no second on-disk restore source — so the resume taint scan's premise holds. The "restore folds only the wire journal" check now also asserts that every `this.wire.read*()` call in the dispatcher is `readJournal`/`readRestorable`, that every append-log read in the wire service names `AGENT_WIRE_RECORD_KEY` (`'wire.jsonl'`), and that `restorableChain` takes only the entries it is handed. - **Live controls on both exact binaries**: plan-ON (`default_plan_mode = true`, deny-all hook) still shows the upstream bypass — one `system.version`, plan file written, the hook saw `Glob` only — so the plugin's refusal remains load-bearing (#3431 unchanged). Plan-OFF (new `repro-clean.ts`): an ordinary `Write` and an `EnterPlanMode` attempt both reached the hook and were denied; no file, no plan file. - **Real-binary smoke** (`bun run smoke:real`): 13 pass / 0 fail / 0 skip on the operator's installed **0.43.1** (312 s) and on a temp-installed exact **0.43.0** via `KIMI_PLUGIN_CC_KIMI_BIN` (285 s) — every native-v2 lane: all read-only labels hook-denied, the goal-mode run wrote zero files across the budget (0.43.1: `turnsUsed:8`, paused on the plugin abort; 0.43.0: `turnsUsed:10`), default-plan preflight and resume/taint lanes, swarm subagent write denied, and write-swarm confined to its worktree with a captured patch (0.43.1: `patchBytes=278 userTreeClean=true worktreeCleaned=true`; 0.43.0: `patchBytes=278 userTreeClean=true worktreeCleaned=true`). Also read for this release: the 0.42.0→0.43.1 diffs of `run-v2-print.ts` (prompt submission moved from `IAgentPromptService.enqueue()` to `IAgentLoopService.submit()`; no argv or provenance change), the before-execute subscriber set (unchanged eight; sole `.allow()` still `planService.ts:110`), the experimental flag set (`KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE` removed, nothing added; `tower`/`subagent_fork` refusals unchanged), and the `[secondary_model]` subagent validation added in 0.43.1 (config diagnostics only), and the 0.43.0→0.43.1 `_base/di/**` diff (`cascadeEngine`, `dependencyGraph`, `instantiationService`, `scopeUnits`): disposal-path cleanup only (`dropScope`/`removeScope`/`deleteScope`, ledger release on retract, `.sort()`→`.toSorted()`) — no change to service resolution, child-scope creation or singleton-vs-scoped wiring, so the "every `AgentSwarm` subagent has its own eager external-hooks service" claim stands (Codex release review). Upstream removed its 24-hour goal limit; the plugin's mandatory finite `--budget` is unaffected. Test fix: `tests/runtime/shell-quote-linear.test.ts` (1.10.2) asserted an empty stderr from a `node --import tsx` subprocess; Node 26.8 prints a `DEP0205` deprecation warning for tsx's `module.register()`, failing all three lanes on an unmodified checkout. The test now strips only that warning pair from stderr before asserting it is empty, so any other stderr output still trips it. Docs: `AGENTS.md` trimmed from 43.6 KB to 23.6 KB (Kimi flagged it above the 32 KB instruction-file guidance; every host loads it each turn). It is now the contract sheet — one present-tense statement per invariant plus a pointer — and the full mechanics/rationale moved verbatim to the new `docs/invariants.md`. `CLAUDE.md` stays an `@AGENTS.md` import (single source, nothing to mirror). Release reviews (Codex via its plugin; Kimi via the 1.10.3 runtime against the installed hook pin): both approve. Kimi's two low findings are closed in this release — the tag scan now (a) pins `wire/wireService.ts`, `wire/record.ts` and `wire/tree/fork.ts` so the `readRestorable` regex assertions cannot degrade silently, with an explicit body-delimiter check, and (b) asserts that no `wire/migration/*` source references the plan domain, because migrations run on each journal line BEFORE restore folds by type while the plugin's taint scan reads the raw line (no such migration exists at 0.42.0–0.43.1; this closes the vector for future tags). Operational notes: run live controls and smokes sequentially — two isolated homes refreshing a copy of the managed OAuth grant concurrently invalidated the operator's token (remedy `kimi login`). Update the plugin through its marketplace and run `/kimi:setup` (Claude Code) or `$kimi-setup` (Codex) to activate; publishing does not update existing host caches or hook pins. ## 1.10.2 — 2026-09-14 **Security patch: bounded parser work during hook validation.** Vendored TOML parsing now rejects unfinished arrays or inline tables ending in a comment without a newline, instead of looping indefinitely (GHSA-7w5x-hrqm-74c2). Vendored shell parsing finalizes tokens in linear time, including callback environments, instead of repeatedly copying growing arrays (GHSA-395f-4hp3-45gv). Both complete upstream fixes are backported into the existing parser versions and included in the Claude and Codex distributions; provenance is recorded beside each vendored parser. Development dependencies, Bun, and GitHub Actions are current. Grouped weekly Dependabot checks and CI dependency auditing cover the manifest and lockfile; vendor-specific regression tests cover the shipped source that package audits cannot inspect. A swarm test fixture now supplies its own executable stub so CI does not require an installed Kimi binary. No UI, approval-policy, engine-selection, or certification changes. Exact native-v2 certification remains kimi-code **0.42.0**. Validation: frozen install, zero dependency audit findings, generated-surface/distribution checks, and the full local suite (832 pass, 25 intentional source-audit/provider-smoke skips). Paid live-provider smoke was not run for this maintenance release. Update the plugin through its marketplace and run the appropriate host's setup command (`/kimi:setup` in Claude Code or `$kimi-setup` in Codex) to activate the new version; publishing does not update existing host caches or hook pins. ## 1.10.1 — 2026-09-09 **Patch: every plugin refusal now states its setup-retryability explicitly.** The 1.10.0 refusal-code contract (`docs/safety.md § Refusal codes`) says agents key on `details.retryable_after_setup`; three pre-1.10 refusal shapes omitted the field — `CLI_V2_HOOK_ORDER_UNSAFE`, `INVALID_ENV` (all three `KIMI_PLUGIN_CC_KIMI_PREFIX_ARGS` paths) and the legacy-v1 branch of `KIMI_CAPABILITY_NOT_CERTIFIED` (which also gains `refusal_kind: "v1-version-not-certified"`). Behaviour was already fail-safe (the retry gate retries only on literal `true`), so this is a contract-exactness fix: no policy, allowlist, engine-selection or certification change; kimi-code 0.42.0 remains the exact certified version. Found by Kimi's post-publish release review of 1.10.0. Wrappers must still treat an absent field as non-retryable. ## 1.10.0 — 2026-09-09 **Full migration to native agent-core-v2, certified at exact kimi-code 0.42.0.** kimi-code 0.42.0 deleted the legacy agent-core-v1 package and `KIMI_CODE_LEGACY_FLAG` (#3542, not in its changelog), making `kimi -p` native-v2 unconditionally and rendering the plugin's forced-v1 pin inert. All eight operations (ask, review, challenge, review_gate, rescue, pursue, swarm, swarm-write) now run on unmodified native v2. ### ⚠️ Breaking changes and upgrade notes This release changes behaviour that earlier 1.x users may depend on. Strictly by semver it is a major; it ships as 1.10.0 because the plugin is upgraded in place through the marketplace and its 1.x line has always advanced compat by minor releases. - **Certification is now per EXACT kimi-code version, not per minor.** Native v2 is certified at `0.42.0` only. When kimi-code publishes `0.42.1` (or newer), every model-spawning command refuses with `KIMI_CAPABILITY_NOT_CERTIFIED` until a plugin release certifies it — before 1.10, a patch release inside a tested minor kept working. kimi-code self-upgrades in the background, so expect this on the next upstream patch; pin `KIMI_PLUGIN_CC_KIMI_BIN` to a certified binary if you need continuity, and watch for the next plugin release. - **Sessions created before 1.10 cannot be resumed on 0.42.0.** `ask --resume`, `ask -r`, `rescue --resume` and rescue's implicit latest-session reuse refuse (`KIMI_SESSION_LINEAGE_UNKNOWN` / `KIMI_SESSION_ENGINE_MISMATCH`) — the v1 engine no longer exists in the binary, so nothing could replay those sessions. Nothing is deleted; `/kimi:status`, `/kimi:result` and `/kimi:replay` still work on the old jobs. Start fresh sessions. - **`default_plan_mode = true` (any spelling) in `~/.kimi-code/config.toml` now blocks every command** (`CLI_V2_PLAN_MODE_CONFIGURED`). On the old forced-v1 path that setting was harmless; on native v2 it would arm the one code path that bypasses the safety hook. Set it to `false` or remove it. `/kimi:setup` cannot fix this one. - **`KIMI_PLUGIN_CC_KIMI_PREFIX_ARGS` may no longer contain kimi flags** (`-r`, `-c`/`-C`, `-S`, `-p`, `-m`, `--plan`, `--yolo`, `--agent`, `--add-dir`, …) — `INVALID_ENV`. The prefix is a launcher shim only (e.g. `["--import","tsx",…]`). - **`[experimental] tower` / `subagent_fork` and `KIMI_CODE_EXPERIMENTAL_FLAG` refuse before spawn** (`CLI_V2_EXPERIMENTAL_UNSAFE` / `CLI_V2_HOOK_ORDER_UNSAFE`). Unset them for plugin-managed runs. - **Still on kimi-code ≤ 0.41.x?** Nothing changes for you: those versions route to the legacy-v1 engine exactly as before. But the plugin certifies them only for an explicitly pinned binary — kimi-code's auto-update will move you to 0.42.x, at which point the notes above apply. No action for the job store (one additive nullable column, migrated automatically) or the hook policy (unchanged allowlists). As with every release, run `/kimi:setup` (or `$kimi-setup`) after updating so the hook is re-pinned to the new install path — a `kimi login` also strips the managed-block markers, and setup restores them. None of these refusals is repaired by `/kimi:setup` (the native-v2 ones carry `retryable_after_setup: false` explicitly; a few pre-1.10 codes omit the field in 1.10.0 and an absent field must be treated as `false`). They are catalogued with remedies in [docs/safety.md § Refusal codes](./docs/safety.md#refusal-codes-of-the-native-v2-contract-v1100). - **Certification basis changed (docs/native-v2-certification-provenance.md §2).** Upstream still registers the plan feature before external hooks and provides no ordering guarantee (confirmed in the shipped 0.42.0 bundle). Native v2 is instead certified on a construction: the plan-file guard is the engine's ONLY chain-breaking final allow, it fires only while plan mode is ACTIVE, and the plugin proves plan mode is never armed in a plugin-managed session. `event.allow` count and the before-execute subscriber set are re-verified per tag by `tests/audit/v2-tag-scan.test.ts`, backed by a live plan-mode-ON control. - **New pre-spawn preflight (`runtime/native-v2-preflight.ts`).** Refuses `default_plan_mode` unless absent/`false` (`CLI_V2_PLAN_MODE_CONFIGURED`), refuses `[experimental]` tower/subagent_fork from config or per-flag env (`CLI_V2_EXPERIMENTAL_UNSAFE`), and refuses resuming a session whose wire journal holds any `plan_mode.*`/`plan.*` record (`KIMI_SESSION_PLAN_TAINTED`). Fail-closed on unreadable/oversized/symlinked inputs. Run before spawn and re-run at the cli-client spawn boundary (config and journals are mutable). - **Resume proven live on the real layout.** The real-binary smoke gains a native-v2 resume lane: a fresh run's real `agents/*/wire.jsonl` is found where the preflight scans, the `-r` resume re-emits `system.version` first with the same session id and the hook still denying writes, and a `plan_mode.enter` record appended to that journal makes the next resume refuse before any process is created. The tag scan additionally pins `features/plan/planOps.ts` and asserts the durable plan event types are exactly `plan_mode.enter|cancel|exit` + `plan.revision` (the prefixes the taint scan keys on) and that `restore()` folds by literal `record.type`; `permission.set_mode` (`manual|yolo|auto`) is verified to be a separate state. - **Second-round adversarial review (Codex) — seven findings, all closed with regression tests.** (P1) upstream's config loader camelCases every top-level TOML key before the plan section reads `defaultPlanMode`, so `defaultPlanMode = true` (or any mixed spelling) walked past a literal `default_plan_mode` check — the preflight now mirrors upstream's `snakeToCamel` verbatim (`app/config/toml.ts` is hash-pinned by the tag scan; the `[experimental]` table is verified to keep raw keys and is not normalized). (P1) the hidden `-C` alias of `--continue` resumed the latest cwd session with no journal scan — the reserved-prefix-flag set now covers every kimi root flag incl. `-C`, `-y/--yes/--auto-approve/--manual`, `-V/-h`. (P1) the Stop hook verified the hook under `/` while the child read `/<…>` — `runReviewGateStopHook` now resolves the home once against the payload cwd for verification, plan and spawn. (P2) a persisted row carrying a session id but no source job is refused (`KIMI_SESSION_LINEAGE_UNKNOWN`) instead of exempted. (P2) unknown-role and malformed stream lines before the `system.version` marker now trip the marker-first rule. (P2) the stderr resume-hint channel (kimi 0.1.x) is consulted only on legacy-v1 plans — a native-v2 plan pins a session id from the stdout meta record alone. (P2) the marker's `version` must be a single well-formed semver token; a multi-line value is no longer first-line-normalized into the certified version. - **Second-round review (Kimi) — three findings, all closed.** (1) the v2 resume path had no repeatable proof of the session-store keying → smoke lane 3b (above) plus a tag-scan pin of upstream's own layout scanner (`app/sessionExport/wire-scan.ts`) and the `session_` / `sessions/` / `agents/` builders. (2) a goal-terminal pursue exit (3/6) skipped the success assertion, so a native-v2 plan could resolve with no `system.version` marker and an empty artifact — `assertGoalRunProvenance` now refuses that (`CLI_ENGINE_PROVENANCE_MISMATCH`). (3) a readdir failure other than ENOENT/ENOTDIR (e.g. `EACCES`) during the journal scan escaped as an untyped error instead of the classified `KIMI_SESSION_JOURNAL_UNAVAILABLE`. - **Engine selection is plugin-owned (`selectIntendedEngine`).** Exact version in `NATIVE_V2_CERTIFIED` → native-v2; a minor in `KIMI_TESTED_MINORS` (≤ 0.41) → legacy-v1 with the child-only legacy pin; otherwise refuse. Certification is per exact version and per operation. `KIMI_TESTED_MINORS` is unchanged and never gains 0.42. - **Provenance.** A native-v2 plan requires the `system.version` marker as the first stream-json line and requires it to equal the probed version; a legacy plan still refuses it. Either mismatch tears down the process tree before any record reaches the caller. Jobs persist a `safety_profile` column (`native-v2-no-plan/1` for v2, null for v1); forged or unknown-profile plans refuse at the spawn boundary. Resume refuses unknown lineage (`KIMI_SESSION_LINEAGE_UNKNOWN`) and cross-engine sources. - **Bash cwd confinement (`runtime/rescue-approval.ts`).** v2's `Bash` tool accepts a separate `cwd`; the allowlist now validates `tool_input.cwd` against the trusted root (realpath, symlink, `.git`, existence) before the command-string policy. Closes the 0.40.0 out-of-workspace-cwd gap for write-capable operations. - **Hook policy.** `EnterPlanMode` and `ExitPlanMode` denied for every label. Every spawn exports `KIMI_CODE_NO_AUTO_UPDATE=1` and an absolute `KIMI_CODE_HOME`. The master `KIMI_CODE_EXPERIMENTAL_FLAG` still refuses before spawn. - **Continuation cost:** sessions created before this release (v1 or unknown provenance) are no longer resumable — the v1 engine no longer exists in the binary. `ask --resume` / `rescue --resume` on such jobs refuse with a fresh-session remedy; nothing is deleted; status/result/replay stay inspectable. - **Out of scope / refused:** native plan mode, tower mode, subagent fork, Remote Control, `--add-dir`, and the singular `Agent` tool. #3431 stays open as the preferred end state (a released ordering guarantee would let native plan mode return). ## 1.9.14 — 2026-09-06 **Certifies kimi-code 0.41.0 on forced legacy-v1.** Model jobs on 0.41.x now pass the tested-minor gate. Native v2 remains disabled for every operation. - **Source audit: COMPAT-PRESERVED.** Four independent reviewers compared exact 0.40.0 and 0.41.0. The v1 core, CLI prompt driver/shared writer, hooks, permissions, session bootstrap/config, and kaos are unchanged. The SDK adds `suggestFiles` (v1 returns `undefined`) and changes a comment. - **Runtime evidence:** the September 6 monitor's exact 0.41.0 smoke passed **12 tests / 0 failures / 55 assertions in 383.88s**. This boundary/version and documentation release reuses that same-day smoke; it changes no model execution behavior. The known-minor assertion advances to 0.41; unknown-minor refusal fixtures continue deriving the next boundary automatically. - **V2 evidence refreshed:** the exact 0.41.0 fresh-plan reproduction still bypasses the hook on plan-file Write; v1 blocks it. `staleGuard` and the old upstream `Permission.md` are removed in this release, so the docs distinguish historical design evidence from current source. Auto-mode dangerous-command checks are skipped, while their nonInteractive exclusion predates 0.41.0. The [v2 brief](docs/native-v2-status.md) separates released changes from open proposals and retains #3431 as the ordering blocker. - Claude/Codex version metadata and bundled runtime are regenerated. Release gates: independent post-edit review and `bun run check`. ## 1.9.13 — 2026-09-02 **Certifies kimi-code 0.40.0 on the forced legacy-v1 path.** Native agent-core-v2 remains fail-closed disabled; no hook, permission, concurrency, budget, confinement, or allowlist policy changed. - **Scoped source audit preserved the supported contract.** The 0.39.1→0.40.0 diffs (48 commits) are 0 bytes for v1 permission policies, v1 hooks, and wire/session. CLI prompt mode changes only `--yolo`/`--auto` help text and adds top-level `fork`/`session` subcommands, which are off the `-p` path (the plugin passes the prompt as the value of `-p`, never a bare positional). Session bootstrap/config is one additive line — `ModelAliasBaseSchema.protocol` widens to `'anthropic' | 'openai_responses'` — and that line is the entire `packages/agent-core` source change. v1 tools/SDK is additive telemetry, session-list, and tower plumbing; Write/Edit `path`, Bash `command`, kaos path guards, and the v1 `createKimiHarness` entry point are unchanged (the `KimiHarness` class gains one optional telemetry field that entry point does not wire). `KIMI_CODE_LEGACY_FLAG=1` still forces v1 for fresh and resumed `-p` at the top of `runPrompt()`; engine selection reads only that env var, so no `config.toml` key — including `[experimental]` tables, which can enable registered v1 flags (`tool-select`, `secondary-model` only) without the env master switch — can defeat the pin. #3427's config-over-env flag precedence and #3434's removal of the legacy acp-adapter package (touches `KIMI_CODE_LEGACY_FLAG` only inside the `acp` subcommand) are v2-only / off the `-p` transport; the secondary-model pool stays opt-in on v1. - **Native-v2 containment remains load-bearing, and 0.40.0 adds a reason.** The plan feature (`index.ts:330`) still registers before external hooks (`:338`), `planService.ts:112` is still the sole `event.allow()`, and `toolExecutor/` is a 0-byte diff; MoonshotAI/kimi-code#3431 is open with no maintainer response. The 2026-09-01 live repro, re-run on 2026-09-02 against the 0.40.0 binary, still bypasses the hook (v2: hook denies `Glob`, plan-file `Write` executes with zero hook payloads; v1 control blocks it). New this release: #3444 removed `RuntimeWorkspaceView.resolve()`'s root assertion, so native-v2 Bash can run with an out-of-workspace `cwd` — confined to agent-core-v2 with no shared code in v1 or kaos, unreachable on the pinned path, and one more reason the refusal stays. The new v2 dangerous-command ask policy is skipped under `nonInteractive` and is not an ordering fix. - **Operator notes, not contract.** v2 config writeback (#3392) now preserves `config.toml` formatting per domain, so managed-block markers may survive login/settings writes more often — the marker-less fallback fires less, never incorrectly. `kimi doctor` now validates config against the v2 schema, whose hook schema is field-for-field identical to v1's, so the managed block passes. The new `kimi migrate --run` is a headless entry point that can rewrite `config.toml`, but its merge mode keeps the target's `hooks` entry and writes atomically at mode 0600 — though, like any kimi-code re-serialize, it drops comments and therefore the managed-block markers, the already-documented marker-loss class the parser-based fallback covers (pre-existing logic; if it ever did alter the entry, the per-spawn byte-exact verification refuses as drift). - **Certification evidence is green.** The exact-0.40.0 temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 383.45s** (the daily monitor's earlier 3/9 red was the documented operator-auth false alarm — `auth.login_required`, `records=[]` — cleared once operator auth was valid again: an isolated-home `kimi -p` probe answered `OK` before the re-run), covering forced-write denials, v2 pre-spawn refusal, fresh/resumed default-plan v1 pinning, pursue's every-turn hook gate, real read-swarm child denial, write-swarm confinement (`patchBytes=306`, user tree clean, worktree removed), and non-vacuous out-of-root denial. `KIMI_TESTED_MINORS` gains `{0,40}`. Tags: `v1.9.13` and `compat-verified-kimi-code-0.40.0`. Reports 117-120; continuity report `.claude/kimi-code-research/daily-monitor/2026-09-02-upstream-monitor.md`. - **Release gate.** `bun run check` passed with **706 pass / 10 intentional real-binary skips / 0 fail / 2,209 assertions** across 38 files; the two untested-version test fixtures moved from 0.40.0 to 0.41.0 as the boundary advanced. ## 1.9.12 — 2026-08-29 **Makes forced-legacy engine provenance durable and certifies the exact kimi-code 0.39.1 patch.** Native agent-core-v2 remains fail-closed unavailable; no hook-verification, permission, allowlist, concurrency, budget, or worktree-confinement rule is relaxed. - **Every model job now carries an immutable execution plan.** Before a job row exists, the runtime resolves the exact executable, probes the same command/prefix/cwd tuple, checks the operation's certified legacy-v1 version range, and persists the real operation, intended/observed engine, kimi version, command tuple, certification source, and resume lineage. Detached ask/rescue workers reload that persisted tuple instead of consulting ambient PATH/config again; the final spawn boundary rejects command drift, corrupt certification, stale test-bypass rows, every native-v2 plan, and untested minors. Setup now says this plainly: it may complete on an out-of-range binary, but model commands refuse until the plugin certifies the minor or `KIMI_PLUGIN_CC_KIMI_BIN` selects a certified binary; the skip-version flag is tests/smoke only. - **Observed-engine mismatches tear down before tool output can escape.** A native-v2-only `system.version` marker under a forced-v1 plan stops record delivery, reaps the owned process tree, and raises `CLI_ENGINE_PROVENANCE_MISMATCH`. New SQLite columns are additive and nullable; old rows remain unknown unless bounded saved-log evidence proves an engine. Conflicting evidence stays unknown, historical `rescue` labels no longer guess between rescue and pursue, cross-engine resume refuses only on a proven mismatch, and forensic backfill does not reorder jobs. - **Write-capable trust roots are plugin-owned.** Rescue and pursue now export the persisted job cwd, while write-swarm exports its throwaway worktree, through `KIMI_PLUGIN_CC_WORKSPACE_ROOT`; the hook never trusts upstream payload `cwd` and denies write tools when the root is missing. Write-swarm certifies wrappers from the actual spawn worktree cwd, preventing relative prefix arguments from resolving one target during probe and another at execution. - **Independent review findings were closed before release.** The Kimi release-blocker pass confirmed no native-v2 containment hole, then caught the stale warn-only operator contract and plan-deserialization calls outside rescue/pursue/swarm cleanup. The warning/recovery policy is now consistent and corrupt/pre-slice plans transition jobs to failed rather than stranding them as running. The review also recorded two bounded costs without weakening the gate: review-gate performs its exact version probe before the 8-second model budget, and permanently unknown historical rows may re-read at most 32 MiB of saved log on inspection. - **0.39.1 patch certification is exact and v2 remains blocked.** All six 0.39.0→0.39.1 playbook scopes are 0 bytes. Exact 0.39.1 and live upstream `main` (`9d2304c`) retain the plan service's final `event.allow()` before ordinary external-hook listeners; no upstream issue/PR or released ordering contract exists yet, so `NATIVE_V2_CERTIFIED_OPERATIONS` stays empty. The exact temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 400.68s**, including fresh/resumed default-plan legacy pinning, pursue every-turn enforcement, real swarm-child denial, write-swarm confinement (`patchBytes=278`, user tree clean, worktree removed), and out-of-root denial. `KIMI_TESTED_MINORS` is unchanged at `{0,39}`. Tags: `v1.9.12` and `compat-verified-kimi-code-0.39.1`. - **Release gate.** `bun run check` passed with **706 pass / 10 intentional real-binary skips / 0 fail / 2,203 assertions** across 38 files after regenerated Claude/Codex surfaces were staged. ## 1.9.11 — 2026-08-27 **Certifies kimi-code 0.39.0 on the forced legacy-v1 path.** Native agent-core-v2 remains fail-closed disabled; no hook, permission, concurrency, budget, confinement, or allowlist policy changed. - **Scoped source audit preserved the supported contract.** The 0.38.0→0.39.0 diffs were 0 bytes for CLI prompt mode (including the engine selector and all of its call sites), v1 permission policies, v1 hooks, and the wire/session scope; the only non-empty scoped surface (9,060 bytes) is MCP-registry `cwd`/OAuth-verify plumbing that leaves create/resume session bootstrap and the `config/` dir byte-unchanged. The v1 tool-layer files outside the scoped diffs (`path-access.ts`, `bash.ts`) are a win32-only shell-path-bridge refactor, provably identity on POSIX. The audit playbook gains a `06-v1-tools-sdk.diff` scope after the adversarial reviewer showed `packages/node-sdk` (source of `createKimiHarness`) and `packages/kaos` were on the `-p` path but never scoped. - **0.39.0's experimental tower mode and subagent fork are v2-only and inert on the pinned path.** Zero v1 flag-registry presence; the v1 `AgentSwarm` schema is `.strict()` so a model-supplied `fork` argument is rejected; both flags are subsumed by the already-refused `KIMI_CODE_EXPERIMENTAL_FLAG`; `[experimental] subagent_fork = true` in the shared config.toml is inert under v1 and does not trip the plugin's hooks-scoped validation. A dedicated v2 veto-ordering re-audit over the release's agent-core-v2 churn (diffstat: 337 changed files under `packages/agent-core-v2/src`, recorded in synthesis report 116) confirmed the plan-file final-allow defect is unchanged — and upstream's own Permission.md documents the bypass as intended with listener ordering an open design question — so both features (and native v2) stay gated on a released ordering contract. - **Remote Control (experimental) is contained by existing verification.** A tunneled config patch can remove the managed hook out-of-band; the per-spawn byte-exact `verifyHookInstalled` catches that fail-closed (an altered entry refuses as drift, a removed one as not-installed — same `/kimi:setup` remedy). Operator notes on the relay's refresh-token forwarding and permissive loopback branch are recorded in the Post-GA audit log. - **Certification evidence is green.** The exact-0.39.0 temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 554.49s**, covering forced-write denials, v2 pre-spawn refusal, fresh/resumed default-plan v1 pinning, pursue's every-turn hook gate, read-swarm child denial, write-swarm confinement (`patchBytes=278`, user tree clean, worktree removed), and non-vacuous out-of-root denial. `KIMI_TESTED_MINORS` gains `{0,39}`. Tags: `v1.9.11` and `compat-verified-kimi-code-0.39.0`. Reports 111-116; continuity report `.claude/kimi-code-research/daily-monitor/2026-08-27-upstream-monitor.md`. ## 1.9.10 — 2026-08-24 **Certifies kimi-code 0.37.x and 0.38.0 on the forced legacy-v1 path.** Native agent-core-v2 remains fail-closed disabled; no hook, permission, concurrency, budget, confinement, or allowlist policy changed. - **Scoped source audit preserved the supported contract.** Intermediate 0.37.0→0.37.1 and 0.37.1→0.37.2 diffs were 0 bytes across all five audit surfaces. The cumulative 0.36.1→0.38.0 audit found 1,805 bytes in CLI prompt mode (only the off-path hidden `__update_download` command), 0 bytes in permission, 0 bytes in hooks, 8,525 bytes in wire/session (MCP OAuth/session plumbing plus a 0.38 background-write drain), and 47,360 bytes in session bootstrap/config (MCP registry/OAuth plus create/resume wiring). Hook merge, cwd, policy order, matching, tool-input keys, and standard swarm-child permission inheritance remain unchanged. The 0.38.0 `WaitFor` tool is v2-only and outside the plugin read-only allowlist. - **Native-v2 containment remains load-bearing.** Exact 0.38.0 still permits plan-file final approval before the external hook in native v2. Accepted children therefore overwrite `KIMI_CODE_LEGACY_FLAG=1`, while truthy `KIMI_CODE_EXPERIMENTAL_FLAG` values refuse before spawn. KAP indexing and MoonshotAI/kimi-code#2376 remain upstream follow-ups; v2 is not re-enabled. - **Certification evidence is green.** The exact-0.38.0 temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 381.64s**, covering forced-write denials, v2 refusal, fresh/resumed default-plan v1 pinning, pursue's every-turn hook gate, real read-swarm child denial, write-swarm confinement (`patchBytes=278`, user tree clean, worktree removed), and non-vacuous out-of-root denial. `KIMI_TESTED_MINORS` gains `{0,37}` and `{0,38}`. - **Release scope.** v1.9.10 publishes the verified compatibility boundary and regenerated Claude/Codex surfaces without changing safety defaults. Tags: `v1.9.10` and `compat-verified-kimi-code-0.38.0`. Continuity report: `.claude/kimi-code-research/daily-monitor/2026-08-24-upstream-monitor.md`. ## 1.9.9 — 2026-08-13 **Certifies kimi-code 0.36.0 on the forced legacy-v1 path.** Native agent-core-v2 remains fail-closed disabled; no hook, permission, concurrency, budget, confinement, or allowlist policy changed. - **Scoped source audit preserved the supported contract.** The immutable 0.35.0→0.36.0 diffs for CLI prompt mode, v1 permission policies, and v1 hooks were all 0 bytes. The 5,056-byte wire/session diff adds MCP OAuth credential coordination; the 22,703-byte bootstrap/config diff adds MCP OAuth inspection/coordinator APIs and v2 secondary-model pool config round-tripping. Neither changes the `-p` stream, create/resume hook merge, permission context, cwd, or workspace-local config loading. - **Native-v2 containment remains load-bearing.** Exact 0.36.0 still permits the plan listener to final-allow exact plan-file writes before later external hooks. Accepted children therefore overwrite `KIMI_CODE_LEGACY_FLAG=1`, while truthy `KIMI_CODE_EXPERIMENTAL_FLAG` values still refuse before spawn. The new v2 secondary-model keys are excluded from the v1 derived-model patch recipe. - **Certification evidence is green.** The exact-0.36.0 temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 534.57s**, including forced-write denials, v2 pre-spawn refusal, fresh/resumed default-plan v1 pinning, pursue's every-turn hook gate, real read-swarm child denial, write-swarm confinement/cleanup, and out-of-root denial. `KIMI_TESTED_MINORS` gains `{0,36}`. Tags: `v1.9.9` and `compat-verified-kimi-code-0.36.0`. ## 1.9.8 — 2026-08-12 **Certifies kimi-code 0.35.0 on the forced legacy-v1 path.** Native agent-core-v2 remains fail-closed disabled; no hook, permission, concurrency, budget, confinement, or allowlist policy changed. - **Scoped source audit preserved the supported contract.** The immutable 0.34.0→0.35.0 diffs for CLI prompt mode, v1 permission policies, v1 hooks, and consumed wire/session records were all 0 bytes. The only canonical bootstrap diff (3,347 bytes) adds global MCP OAuth-status RPC/helper code and does not change `-p` session construction, hook merging, permission context, cwd, or workspace-local config loading. - **Adjacent upstream changes narrow, rather than widen, child capability.** The builtin `coder` profile no longer exposes nested `Agent`/`AgentSwarm` by default, and builtin profiles are cloned per session. The coordinator `AgentSwarm` path remains available and hook-gated. - **Native-v2 containment remains load-bearing.** Exact 0.35.0 still permits the plan listener to final-allow exact plan-file writes before later external hooks. Accepted children therefore overwrite `KIMI_CODE_LEGACY_FLAG=1`, while truthy `KIMI_CODE_EXPERIMENTAL_FLAG` values still refuse before spawn. - **Certification evidence is green.** The exact-0.35.0 temporary binary passed `bun run smoke:real` with **12 pass / 0 fail / 55 assertions in 525.01s**, including fresh/resumed default-plan v1 pinning, forced-write denials, pursue's finite budget, real read-swarm child denial, write-swarm confinement/cleanup, and out-of-root denial. `KIMI_TESTED_MINORS` gains `{0,35}`. Tags: `v1.9.8` and `compat-verified-kimi-code-0.35.0`. ## 1.9.7 — 2026-08-08 **Makes hook refusals self-healing for every caller and startup failures self-diagnosing.** No safety-policy, permission, concurrency, budget, allowlist, or `KIMI_TESTED_MINORS` change; experimental-v2 remains fail-closed refused. - **The re-pin protocol rides the refusal message.** Every `*_HOOK_NOT_INSTALLED` refusal now appends a single-source caller protocol (`hookRefusalRetryProtocol`, `runtime/hooks/install.ts`, consumed at all five model-spawning refusal sites): on `retryable_after_setup: true`, run the embedded resolved `companion.sh setup` and retry the refused command once only on exit 0; anything else — or a second refusal — surfaces. Slash-command callers now self-heal after a plugin update exactly like the agents (whose `agents/*.md` contract is unchanged), completing step 3 of the hook-pin durability spec's recommended path for all surfaces with zero duplication in the 13 surface files — an earlier draft that pasted the paragraph into each command was reverted for exactly that bloat. - **`auth.login_required` is classified as auth, not startup.** kimi-code's logged-out OAuth store (`auth.login_required: OAuth provider "managed:kimi-code" requires login…`) reaches the classifier inside the `CLI_NONZERO_EXIT` message (cli-helpers embeds the stderr tail); a new branch ahead of the generic nonzero-exit case maps it to `*_KIMI_AUTH_UNAVAILABLE` with a "Run `kimi login`… `/kimi:setup` does not repair auth" remedy. Trigger incident: 2026-08-08, an out-of-band kimi background auto-upgrade (0.31.1→0.34.0) invalidated the token and the plugin's startup-failed advice misdirected to setup. - **Wrapped startup failures keep their cause.** `classifyManagedCommandFailure` threads `availability`, `cause_code`, and a tail-truncated (2 KB) `cause_message` into `RuntimeError.details`, so the underlying stderr survives on the foreground `details:` JSON line and in the SQLite job row. Previously the cause lived only on the unserialized `cause` chain — invisible to LLM callers on every channel (LLM-caller discipline). - Tests: login classification, details threading, tail truncation, and the review-gate warning path; full `bun run check` green (692 pass / 0 fail). ## 1.9.6 — 2026-08-08 - **Fix-first engine pin.** kimi-code 0.33.0 inverted unflagged `kimi -p` from v1 to native v2 (unchanged in 0.34.0), while v1.9.5's refusal still recognized only the old `KIMI_CODE_EXPERIMENTAL_FLAG` selector. Every accepted child spawn now overwrites `KIMI_CODE_LEGACY_FLAG=1`, including resumed sessions and ambient false-value cases; older binaries ignore the unknown flag. Truthy experimental values remain an independent pre-spawn `CLI_V2_HOOK_ORDER_UNSAFE` refusal. - **Why the pin is load-bearing.** Exact 0.34.0 source still lets the plan service final-allow its exact KIMI_CODE_HOME plan-file Write/Edit before the later external PreToolUse listener. The path is outside the user worktree but violates the every-tool managed-hook contract. Native v2 remains uncertified; this candidate does not relax hook, permission, concurrency, budget, confinement, or allowlist policy. - **Certification evidence is green.** Unit tests prove the forced legacy flag reaches fresh and resumed children even when ambient state says `0`/`false`; the exact-0.34.0 temp binary passed `bun run smoke:real` with **11 pass / 0 fail / 54 assertions in 460.09s**. The non-vacuous `default_plan_mode=true` fresh+resume lane stayed on v1 (no `system.version`) and both writes reached the managed hook and were denied. `KIMI_TESTED_MINORS` gains `{0,32}`, `{0,33}`, and `{0,34}`. Release tags: `v1.9.6` and `compat-verified-kimi-code-0.34.0`. ## 1.9.5 — 2026-08-01 **Publishes the already-verified kimi-code 0.31.1 patch boundary as an installable plugin release.** There is no runtime safety-policy, permission, concurrency, budget, allowlist, or `KIMI_TESTED_MINORS` change; experimental-v2 remains fail-closed refused. - **Default-v1 compatibility remains intact.** The scoped 0.31.0→0.31.1 audit found 0-byte CLI, permission, hook, and bootstrap/config diffs. The only canonical wire/session delta removes the disabled no-op `model` parameter from Agent/AgentSwarm schemas; the AgentSwarm tool name/executor and all load-bearing hook invariants are unchanged. - **Exact released-binary evidence is green.** A temp-installed `@moonshot-ai/kimi-code@0.31.1` binary passed the final release-candidate `bun run smoke:real` with **10 pass / 0 fail / 42 assertions in 305.60s**, covering forced-write denials, pre-spawn v2 refusal, pursue's finite budget, read-swarm child denial, write-swarm confinement/cleanup, and out-of-root denial. - **Release scope is distribution-only.** The prior `compat-verified-kimi-code-0.31.1` marker already recorded the audit at immutable upstream commit `6b56c11697771fe596099b38bafae539820309a4`. v1.9.5 refreshes plugin/cache version metadata and generated mirrors without changing executable policy. ## 1.9.4 — 2026-07-31 **Certifies kimi-code 0.31.0 for the default-v1 engine and fail-closes experimental-v2 after correcting an inherited hook-order overclaim.** `KIMI_TESTED_MINORS` gains `{0,31}`; the setup warning stops firing for 0.31.x. This is a patch release because the safe outcome requires runtime refusal, not only documentation. - **The v2 issue is an actual managed-hook bypass, confined outside the worktree.** Production v2 listener order is permission gate → plan → swarm → external hooks. With plan mode active, `AgentPlanService` final-allows a `Write`/`Edit` targeting only the exact plan file under `KIMI_CODE_HOME`; final allow stops later listeners, so PreToolUse never runs. Fresh sessions can reach it through user `default_plan_mode=true`, and resumes restore plan state. The path cannot write the user tree, but "every model tool reaches the managed hook" is load-bearing and cannot tolerate the exception. - **Fail-closed mitigation.** `cli-client.ts` now refuses before spawn when `KIMI_CODE_EXPERIMENTAL_FLAG` matches upstream's truthy values (`1|true|yes|on`, trimmed/case-insensitive), returning `CLI_V2_HOOK_ORDER_UNSAFE` with `refusal_kind:"v2-hook-order-unsafe"`. It does not silently force v1 and `/kimi:setup` is not the remedy; unset the flag. False/unset values preserve default-v1 fresh and resume behavior. `EnterPlanMode` is explicitly denied for every managed label as defense in depth. - **Correction, not a 0.31 regression.** The ordering is byte-identical in 0.30.0 and 0.31.0. Earlier audits correctly proved ordinary v2 hook vetoes but overgeneralized them into "before plan approval." v2 stays disabled until an exact release guarantees external-hook veto before every final allow and both fresh-default-plan and restored-plan tests pass. - **0.31 custom-agent boundary documented.** Default-v1 now discovers project/user/plugin agent profiles and plugin system-prompt contributions. `override: true` can replace builtin `agent`/`coder` instructions and tool availability, and the chosen profile persists with the session. Profile fields and system-prompt text can redirect task intent but cannot themselves set hooks/permission/cwd, widen the local allowlist, or escape swarm-write confinement; enabled plugins are a separate source of hooks, still governed by any-block-wins aggregation. - **Source/wire and smoke evidence.** V1 permission and hook trees are 0-byte diffs; consumed argv, hook aggregation, tool-input keys, swarm inheritance, PromptJsonWriter/session/goal shapes remain compatible. Parser/client verification passed 98/0/247. Exact-0.31.0 pre-mitigation smoke passed 11/0/49 in 944.47s across the forced-write labels, pursue budget, read swarm, write-swarm confinement, out-of-root denial, populated-home KAP observation, and an ordinary fresh-v2 denial. It proves confinement for that matrix, not fidelity under a hostile custom profile/prompt; the v2 lane is explicitly not certification because it did not cover `default_plan_mode`. The post-mitigation smoke lane asserts pre-spawn v2 refusal. - **KAP caveat retained as released-source history.** 0.31.0 still contains experimental-v2 eager cross-session indexing and upstream PR #2376 remains unmerged, but the side effect is unreachable from plugin flows while v2 is refused. ## 1.9.3 — 2026-07-29 **Certifies kimi-code 0.30.0, and fixes the smoke test that would otherwise have certified it for the wrong reason.** `KIMI_TESTED_MINORS` gains `{0,30}`; the H9 out-of-range warning stops firing. The substantive change is not the certification — it is the discovery that the evidence backing it was vacuous. - **The smoke was green because it never ran the code it was believed to cover.** An exact-0.30.0 `smoke:real` had already passed `10 / 0 / 43`. It was worthless for the one behaviour in question: every isolated `KIMI_CODE_HOME` is created empty, kimi-code's cross-session indexer short-circuits when it finds zero sessions, so the path exited before doing anything. Nothing in the harness checked that its own premise held. **A green test whose precondition never held is worse than a red one — it reads as evidence.** The new populated-home case asserts its precondition (`wire.jsonl` count > 0) and fails loudly rather than passing quietly. This is now a standing rule in AGENTS.md, because the failure mode is generic: any smoke whose behaviour depends on host state can pass for the wrong reason. - **What the test asserts, and deliberately does not.** It pins the INVARIANT — writes stay denied under a populated home, agent-core-v2 genuinely served the run (`systemVersion` defined), and no search index ever appears in the WORKSPACE — while only RECORDING whether `/search-index` materialized. Asserting its absence would encode an upstream bug as a plugin failure; asserting its presence would break the day the upstream fix ships. Recording keeps the test correct on both sides of that release. - **Exact-0.30.0 `smoke:real` GREEN: 11 pass / 0 fail, 49 assertions in 348.05s** — and non-vacuous this time (`index PRESENT, wire files=1`). Read-only forced writes denied across all four labels; the asserted `KIMI_CODE_EXPERIMENTAL_FLAG=1` lane denied and emitted the v2 signal; pursue reached its finite budget with zero writes; read swarm denied a spawned subagent write; write-swarm stayed confined (`patchBytes=334`, `userTreeClean=true`, `worktreeCleaned=true`); the out-of-root absolute write was denied. - **Source audit re-verified every load-bearing contract against 0.30.0** rather than inheriting the daily monitor's verdict (monitor reports are continuity-only and do not certify a version). Policy queue keeps the hook at index 0 with indices 1-4 all pure denies before the first approve at 5; hook engine keeps first-block-wins, empty-matcher-means-all, exit-2 denial, fail-open on internal error; `Bash`/`command` and `Write`/`Edit`/`path` unchanged with no new write-shaped builtin; `-p` still defaults to v1 with `permission: 'auto'`; goal mode still triggers on the `/goal` prefix alone; `HookDefSchema` still `.strict()`. The deepest check: `agent.hooks` is OPTIONAL, so an unwired subagent would silently fail open through index 0 — it is wired unconditionally by `createAgent`'s `config.hookEngine ?? this.hookEngine` fallback, and no production call site supplies `config.hookEngine`. - **Scope correction worth recording.** The audit clone's `package.json` reads `0.30.0`, but `origin/main` is **eight commits ahead of the released tag** — v1 custom agent files, plugin-contributed agents, plugin `systemPrompt`, and the `secondary-model` flag are all queued for 0.31.0 and are NOT in the shipped binary. Auditing the wrong tree would have certified behaviour users do not have. Contracts were verified at both states and hold in both. - **The 0.30.0 caveat, characterized rather than waved through.** Experimental-v2 App bootstraps eagerly activate the KAP global-search service, so a `kimi -p` run under `KIMI_CODE_EXPERIMENTAL_FLAG` performs an unasked-for cross-session index pass and creates `/search-index`. It is engine-internal (never a tool call), confined to KIMI_CODE_HOME, and the DEFAULT v1 engine is unaffected — not a hook bypass, not a user-worktree write, not a credential read. Root-caused with an upstream fix proposed in still-unmerged **MoonshotAI/kimi-code#2376**, which flips the registration to App-scope `OnDemand` and includes a behavioral DI regression test. - **Residual, stated rather than buried.** Write-swarm still runs against a session-less home, so "an un-awaited index sync cannot race the patch capture" is COMPOSED from two tests (index confined to KIMI_CODE_HOME; patch capture reads the ephemeral worktree) rather than observed end to end in one. - **Before certifying 0.31.0.** v1 custom agent files will auto-scan project roots (`/.kimi-code/agents`, `/.agents/agents`) with NO flag gating, and an `override: true` file can replace the default `agent` profile. `AgentFileDefinition` carries no permission/hook/cwd field, so it reshapes the system prompt and tool list only — every call still hits policy index 0 and our label allowlist fails closed on an unknown tool. It is a prompt-injection surface for repo-scoped rescue/swarm-write, not a hook bypass, and it needs a `docs/safety.md` paragraph before 0.31 lands. ## 1.9.2 — 2026-07-25 **Agent-facing docs release. No runtime change.** Detaching the caller's shell call is now the documented default for the two write-capable surfaces, the cancel path is corrected to the form that can actually execute, and the harness interrupt contract is measured rather than assumed. - **The bug this fixes is a doc bug with real consequences.** A dispatching agent refused `/kimi:swarm --write` outright, reasoning that the agent doc forbade `run_in_background: true`, `--budget` defaults to 30m, and Claude Code caps a foreground Bash call at 10 minutes. Every premise was true; the conclusion was not. The docs had conflated the runtime's rejection of `--background`/`--wait`/`--fresh`/`--resume` (real, unchanged) with a doc-level rule against the *caller* detaching its own shell call — a rule motivated by watchability, not enforced by anything. `swarm-write` and `pursue` now document caller-level detaching as the default. Read-only swarm's foreground default is unchanged and deliberate. - **What actually bounds these surfaces** is the index-0 PreToolUse hook, the workspace allowlist, no-git-mutation, patch-only worktree confinement (swarm-write), and the mandatory finite `--budget` — all runtime-enforced, none dependent on a human watching. A blocked foreground call is *worse* oversight: it freezes the dispatching agent for the whole run, so it cannot report progress or cancel on request. - **The first draft of the cancel path was falsified by review, and is corrected.** It told agents to "keep the `job_id` from the launch output and run `companion.sh cancel `". That flow cannot execute: `pursue.ts`/`swarm.ts` mint the id with `randomUUID()` and emit nothing at launch, so a detached caller holds a host task id and the plugin id first appears in the final report. The working path is the **no-id** form — `companion.sh cancel` resolves `findLatestJob({runningOnly:true})` for the repo — which also removes the UUID from the human path entirely. Documented limit: with several runs in flight it takes the most recent, so a multi-run session confirms first. - **Interrupt signal contract measured** (macOS, Claude Code): foreground Esc and `TaskStop` on a detached call both deliver a trappable SIGTERM **process-group-wide**, then SIGKILL after **~1.35s** (samples 1.34s / 1.36s). Two consequences. Group delivery reaps detached Kimi descendants along with the companion, so the "surviving child keeps writing to the real tree" risk raised against backgrounding `pursue` does not exist. But ~1.35s is shorter than `cli-client.ts`'s 1500ms child escalation *alone*, before quiescence and `git diff --binary` capture begin — so a hard interrupt can kill the companion mid-teardown and **lose the write-swarm patch**. `companion.sh cancel` signals from a separate process not racing that deadline and is the work-preserving stop. The margin is thin; re-measure on harness changes. - **`pursue` is not `swarm-write`.** An adversarial review caught the first pass flattening a real asymmetry: swarm-write's edits are worktree-confined and return as a discardable patch, while pursue's land in the user's real tree and a cancel stops further work **without rolling back** what is already done. Both now default to detached callers; only pursue carries the non-rollback warning. - **Seven surfaces, one contract — and they had already drifted.** The cancel correction initially landed in AGENTS.md and both Claude agent files but missed `scripts/surface-registry.ts`, so the repo told Codex to do the thing the same commit called impossible. Also fixed: `agents/kimi-pursue.md` contradicting itself four lines apart, `commands/{pursue,swarm}.md` routing a stop through an unobtainable id, `commands/cancel.md` documenting only the id-shaped form, `commands/swarm.md` flattening read and write swarm into one detach rule, and `docs/safety.md` claiming unqualified patch-capture-on-cancel that does not hold under a harness interrupt. - **Doc hygiene: version archaeology moved out of the reference docs.** `AGENTS.md` § Releasing requires one current headline with per-version history in CHANGELOG/ROADMAP; the reference docs had drifted from that, and this session's own edits made it worse. Audited by three parallel read-only agents, applied by hand, with the rule that no fragment could be dropped until it was proven recorded elsewhere. One was not — pre-1.0 `v0.2.3` — and was added to "Older releases" below before the trim. Regression-preventing rationale was kept and sharpened into prohibitions ("never re-merge the two flags", "never collapse back to one shared block", "never regress this to a line scanner"). Also drops a stale "verified byte-identical through 0.12.0" that under-reported the tested range by 17 minors. - **The Releasing instruction itself was ambiguous** about what a headline is, which is how the accretion kept happening. It now says the Version headline states a present-tense contract an agent must not regress — not what the release did — with an example of each. The 1.9.1 hook-pin durability contract is retained as the headline deliberately: it is still standing, and it is the only place that contract is written down. - **No upstream-compat change.** `KIMI_TESTED_MINORS` unchanged through `{0,29}`; no kimi-code re-certification, no runtime code touched. ## 1.9.1 — 2026-07-25 **Closes the background hook-enforcement test gap that let the v1.9.0 regression reach pre-release review, and adds a narrow verification-time probe that the pinned Node interpreter is still executable. Deliberately scoped: this is NOT a fix for a silent bypass — the wider rationale it was first written with was refuted by review and is recorded here so it is not revived.** - **Test gap closed (the substantive change).** Every background test set `KIMI_PLUGIN_CC_SKIP_HOOK_CHECK=1`, and the one worker-refusal test drove `executeAskJob` **in-process** — so no test had ever run a real detached worker with enforcement on. That is precisely why v1.9.0's `spawn(process.execPath)` regression, which would have made every background rescue/ask refuse forever, was caught by a model review instead of by CI. New `tests/runtime/background-hook-enforcement.test.ts` runs the companion CLI as a real node subprocess invoked **through a symlink**, with **no** `KIMI_PLUGIN_CC_NODE_BIN` override, and asserts the spawned worker's own hook check agrees with the parent's pin. Confirmed to catch the original bug by reverting it: the job fails with `drift_axis: "node-bin"`, expected `…/Cellar/node/26.5.0/bin/node` vs. installed stable symlink. This could not live in the existing suite — with an override, spawner and verifier agree *by construction* (the buggy code honored the override too), and reproducing the no-override path needs a real node parent, impossible under `bun test` where `process.execPath` is bun. - **The argv0 premise is now measured, not assumed.** v1.9.0's regression test fed the expected value in as the child's `argv0` rather than observing one, so it assumed the OS behavior the whole fix rests on. A real child now reports its own `argv0`/`execPath` (via `tests/helpers/print-node-pin.mjs`, which imports the **compiled** `dist/` a worker actually loads) and proves `spawn()` passes argv[0] verbatim without resolving symlinks. - **Interpreter executability probe (`access(nodeBin, X_OK)`), honestly scoped.** `verifyHookInstalled` already confirmed the hook *script* was readable; it never confirmed the *interpreter* was runnable. The predicate it covers is narrow and exact: **config and expected command still match byte-for-byte, yet the Node token embedded in that command fails `X_OK` at verification time.** Reachable three ways — an absolute `KIMI_PLUGIN_CC_NODE_BIN` naming an already-dead binary that is not the running interpreter (e.g. an `nvm uninstall`ed version, via a direct `node dist/companion.js` that bypasses `companion.sh`'s exec+version gate); or **post-launch mutation on the default path**, where the interpreter is valid at launch and is then `chmod -x`'d (`realpath` still resolves, argv0 is retained, bytes unchanged) or removed (fallback to `execPath`, identical spelling in `argv0 === execPath` layouts). In each, the old behavior was `installed: true` → `/bin/sh -c` exits 127 → kimi-code reads any non-2 exit as ALLOW. Setup's stronger *execution* probe is not a substitute: it runs at install/`--check`, whereas this reruns before every model spawn and so catches degradation since the last probe. - **What it explicitly does NOT do** (recorded because the first draft claimed otherwise, and a wrong comment about the threat model is worse here than wrong code). It does **not** catch a dangling Homebrew symlink: a dangling symlink cannot be exec'd and `command -v node` skips it, so `companion.sh` resolves a *different* node, the expected command is recomputed from the live process and changes, and plain byte-exact equality refuses first — with a **recoverable** drift that `/kimi:setup` converges. It likewise does not catch the 2026-07-25 dead-node zombie (a config pinning `~/.hermes/node`), which is a byte mismatch. And it proves the exec bit only — not a working Node, not the right arch, not >= 22.5. The bypass is **narrowed, not closed**. - **`nodeBin` is derived by parsing the built command back, never by re-resolving.** `tryBuildExpectedHookCommand` now returns the interpreter token, obtained via `parseHookShellCommand(command)` — the exact inverse of how it was built — so it is byte-identical to what the config is compared against **by construction**. Re-calling `resolveNodeBinary` would have been a latent reintroduction of the very bypass being fixed: its no-override path runs `preferStableNodePath`, which does `realpath` I/O and is therefore **not** a pure function of `env`. Had the pinned symlink been unlinked between the two calls (what `brew upgrade node` does), the command would pin the symlink while the probe checked the stale realpath — which may still exist — blessing a hook whose real interpreter was gone. Caught in review before shipping; `tryBuildExpectedHookCommand`, previously untested, now pins this identity. - **Machine-readable refusal discriminator.** This is the one refusal whose remedy is *not* "run /kimi:setup" — setup cannot repair a broken Node — yet it emitted a `{config_path}` payload byte-identical to four other refusals. It now carries `refusal_kind: "node-bin-not-executable"` plus `node_bin`, per LLM-caller discipline. It can never co-occur with `drift`: drift requires the equality check to **fail**, this requires it to **pass**, so the new refusal cannot displace a recoverable path. Fail-closed on **any** errno, deliberately diverging from `background-spawn.ts` (which ignores errnos outside `ENOENT`/`EACCES`/`EPERM`) — spawning can afford to try and see; a security verifier cannot. - **Review round (Opus code-review + independent Opus skeptic + Codex, three passes).** The skeptic **refuted the change's original premise** and I confirmed it empirically before acting. The code-review pass found the re-resolve defect above, plus three test comments that claimed guarantees the tests did not provide: an assertion captioned "the regression assertion" that read `stderr` (the worker is spawned `stdio: "ignore"`, so it can never fail) and an exit-code assertion that is equally inert (`runAsk` *returns* the failure artifact rather than throwing); and two negative tests captioned as covering the **worker's** re-verify when `runAsk` refuses at the entry gate before any child is spawned. All corrected. The same pass cleared every false-refusal path: root (`X_OK` requires a real exec bit), Windows (`X_OK` degrades to `F_OK`, and win32 is already excluded), NFS/`noexec`/containers (false negatives, never false refusals). Codex supplied the post-launch-mutation cases the other two passes missed. - **Real-binary smoke GREEN** (run 2026-07-25 against kimi-code **0.29.1** once the managed OAuth session was restored): `bun run smoke:real` passed **10 / 0 / 43 in 401.36s** — read-only forced writes denied, goal mode reached its finite budget with zero writes (`aborted=true`, the expected steady state), read swarm denied a subagent write, and write swarm stayed confined (`patchBytes=278`, `userTreeClean=true`, `worktreeCleaned=true`). An earlier attempt during the release itself was **auth-blocked** (`auth.login_required`, `records: []` on all 10 cases before any prompt reached the model) and was published as NOT-RUN rather than as a pass; that note is superseded by this run. Both hosts re-pinned to 1.9.1 and verified enforcing (direct + shell probe, deny reason captured, interpreter `/opt/homebrew/bin/node` — the stable symlink v1.9.0 introduced). - **No upstream-compat change.** `KIMI_TESTED_MINORS` unchanged; no kimi-code re-certification. ## 1.9.0 — 2026-07-25 **Stops the recurring "run /kimi:setup" nag at its source: the canonical hook command no longer embeds the Node *version*, and a refusal caused by a moved hook path now carries a machine-readable drift axis so an agent caller can re-pin and retry once. No self-writing verifier — that design was proposed, adversarially reviewed twice, and rejected.** - **Root cause.** "Installed" is byte-exact equality between the config's `command` and a freshly rebuilt canonical command — the strictness that killed the old `true # …approval-hook.js` substring bypass, and it is not negotiable. But that command embedded **two independently version-stamped paths**: the Node binary (`process.execPath` resolves the Homebrew symlink to `…/Cellar/node//bin/node`) and the version-stamped plugin install dir. `brew upgrade node` invalidated **both hosts at once**; a plugin update invalidated one. Routine maintenance therefore read as "the plugin keeps breaking." Diagnosed live 2026-07-25: Codex auto-updated 1.8.7→1.8.8 and deleted the old dir while the config still named 1.8.7. A June config backup holding `node/26.0.0` and `node/26.3.0` side by side shows the Node axis had already fired before. - **Node axis fixed at the source (`preferStableNodePath`).** `resolveNodeBinary` now prefers `process.argv0` — the path the interpreter was actually invoked with, which `companion.sh` resolves through the stable `/opt/homebrew/bin/node` symlink — but **only when it is absolute AND `realpath`-identical to `process.execPath`**. That guard is the whole safety argument: the substitution provably cannot select a *different* binary, only a more stable *name* for the one already running. Any doubt (relative argv0, `realpath` throw, different target) falls back to `execPath`. Byte-exactness, absoluteness, and the shell probe are untouched. Side benefit: hook and companion now ride the same interpreter by construction — previously the companion could run a new Node while the hook stayed pinned to a Cellar path `brew` had already deleted, which spawns nothing and (exit 127) **reads as ALLOW**. nvm/asdf/mise expose version-stamped paths directly, so `argv0 === execPath` there and behavior is unchanged, not worse. - **Structured drift signal.** `InstalledCheck.drift` / `HookInstallStatus.drift` (`{axis: "hook-script" | "node-bin" | "both", installedCommand, expectedCommand}`) is populated **only** when a structurally sound block's command names different paths, and is forwarded into every refusal's `RuntimeError.details` via the shared `hookRefusalDetails`. Strictly advisory: derived *after* byte-exact equality has already failed, it can never influence `installed` — the same contract `nodeExists` classification has always had. Refusals that are *not* re-pin-recoverable (unresolvable command, unreadable config, invalid hook set, duplicate/orphan markers, missing script) carry **no** drift, so a caller cannot mistake them for retryable. The `absent` + stale-bare-table case is classified too — that is the **common** real-world shape, since kimi-code strips markers on every login write and a plugin update then moves the path (both at once is exactly the 2026-07-25 incident). - **The caller heals it, not the callee.** All seven model-spawning agents now read `drift_axis`: on `"hook-script"` (`retryable_after_setup: true`) they run `/kimi:setup` for that host and retry **once**; on anything else they surface the refusal and stop. Repair stays a **visible, permission-gated action in the transcript**, taken by the host model — not a silent mutation of a security surface. `"node-bin"`/`"both"` are deliberately never auto-retried: a moved interpreter may be *gone*, and that is a real enforcement gap, not a moved file. - **Auto-repin REJECTED (recorded so it is not re-proposed).** An in-verifier self-repair was fully specified, then rejected by two independent adversarial reviews. Four defects were mechanically confirmed: (1) **self-deadlock** — the repin path takes `withKimiConfigLock`, then the install transaction takes it again, and the lock has no reentrancy check (staleness is `!isProcessAlive(owner.pid)`, and the owner is us), so every attempt spins 10s and throws; (2) the "target cannot be steered" premise is **false** — `KIMI_PLUGIN_CC_HOOK_SCRIPT`/`NODE_BIN`/`HOST_ID` override resolution, and every gate reads the same env, so they are self-consistent by construction and supply no independent evidence; (3) **no version-monotonicity bound**, so a surviving old session could pin the *global* block to a pre-1.0.3 hook carrying the CRITICAL exec-delegation bypass — the exact outcome that argument was built to prevent; (4) a **write→spawn TOCTOU** in which a stale session repins to a deleted path inside another session's spawn window, yielding exit 127 → ALLOW → an unenforced `rescue` run. The v1.8.0-lock rebuttal was also rationalization: v1.2.1's objection was *authorization* + *detection*; a lock provides *atomicity*, making an unauthorized write correctly serialized. Full analysis, including why **content/hash verification also fails** (the proposal hashes `approval-hook.js` — 4,325 of 55,661 bytes, 7.8% of enforcement code — while the v1.0.3 CRITICAL fix lives in `rescue-approval.ts`; and hook/companion are two halves of one wire protocol a global version floor cannot express) is preserved in `.claude/hook-pin-durability-spec-2026-07-25.md`. - **Migration.** The canonical command changes, so **every existing install drifts once** on upgrade and needs one `/kimi:setup` per host. Enforcement is not lost meanwhile — the old block keeps firing; the plugin refuses to *spawn* until re-pinned. The drift is classified as the benign case (see below) and the agents self-repair it. - **Migration message is honest about the cause.** `describeHookCommandDrift` now recognizes when two node paths name the **same file** (`realpath`-compared) and says so — *"Node path spelling changed … these are the SAME interpreter reached by different paths … your Node did not move"* — instead of the pre-existing wording that blamed "a Node version-manager switch between runs", which would have misled every upgrading user. A **gone** interpreter still takes precedence and still reports "no longer exists": that is the unambiguous danger signal and must never be softened into a benign re-pin. - **Pre-release review round (Kimi + Opus, converging independently).** Three defects were found and fixed before tagging: - **CRITICAL — background rescue/ask would have refused permanently.** `startBackgroundJob` spawned the worker with `process.execPath`, so the child's `argv0` was the fully symlink-resolved (version-stamped) path, while setup — running through `companion.sh`, which execs `$(command -v node)` — pinned the stable symlink. The worker re-verifies the hook (deliberately, so a background job cannot outlive or bypass the check), rebuilt a *different* expected command, and `/kimi:setup` could never converge the two sides. Foreground commands were unaffected, which is exactly why it would have shipped. Now uses `preferStableNodePath` for the no-override default — deliberately **not** `resolveNodeBinary`, whose absolute-path requirement is the *hook-pin* contract, not the *spawn* contract (spawn resolves a bare name via PATH). Regression test added. - **The signal never reached the caller.** Agents were told to branch on `drift_axis`, but `formatError` dropped `details` entirely and the failure artifact rendered only code/stage/message — so the field existed only in the SQLite row, reachable via `result --json` for background jobs and *lost outright* for foreground ones. `formatError` now serializes details as one deterministic JSON line (non-serializable values can never suppress the error itself), and the artifact renders a sorted `### Details` section. - **The retry could walk past a proven-dead hook.** `/kimi:setup` **install** exited 0 even when its probe *failed*, and only `check` exited nonzero. Since an agent now keys its retry on that exit code, a hook that is byte-exact and readable but cannot deny — a truncated `approval-hook.js` (iCloud sync has done this in this repo), or a half-extracted plugin cache — would pass `verifyHookInstalled` and the command would run unenforced. Any failed probe now exits nonzero, and the agents retry only on a clean exit. `probe: "skipped"` (uninstall) is untouched. - Also fixed: agents were told to run `/kimi:setup`, a slash command a `tools: Bash` subagent cannot invoke — they now call `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh setup`, the same surface the command wrappers use; and `retryable_after_setup` contradicted the new same-file finding (prose said "benign, expected" while the field said "do not retry") for the single most common refusal this release creates. Retryability is now "every differing token is benign": a moved script, or a node token whose spelling changed but still names the same file. A node token naming a **different** file is still never retryable. - **No upstream-compat change.** `KIMI_TESTED_MINORS` and all kimi-code surface reasoning are unchanged; this is a plugin-side durability fix, not a kimi-code certification. ## 1.8.8 — 2026-07-25 **Certifies kimi-code 0.29.0 + 0.29.1.** Verdict **COMPAT-PRESERVED**; `KIMI_TESTED_MINORS` extended with `{0,29}`. - **V1 safety chain unchanged.** Across 0.28.1→0.29.1, `02-permission` and `03-hooks` are 0-byte diffs. The index-0 hook, first-approve ordering, any-block-wins aggregation, exit-2 denial, empty-matcher behavior, `Bash.command` / `Write.path` / `Edit.path`, `-p` auto/headless behavior, configured+plugin hook merge, swarm subagent stack, and hard concurrency gate remain intact. - **Scoped non-empty changes are compatible.** 0.29.0 adds opt-in v2 custom-agent flags the plugin does not pass plus session/provider/model-capability and replay plumbing. 0.29.1 adds MCP timeout defaults and web endpoint/env configuration. None changes PromptJsonWriter output, `session.resume_hint`, permission-context construction, or workspace-write policy. - **Experimental v2 refactor preserved the ordinary deny seam, but the original order claim was later corrected.** 0.29.1 replaces ordered pre-execution hook slots with an awaited veto event; ordinary external PreToolUse blocks and the exact smoke below were real. A 2026-07-31 production-registration trace found plan service actually precedes external hooks and can final-allow its exact plan-file write first. v1.9.4 therefore disables experimental-v2 across the tested range; see its entry for the inherited gap and mitigation. - **Exact-binary smoke GREEN on latest.** The temp-installed exact-0.29.1 `bun run smoke:real` passed **10 / 0 / 43 in 339.80s**: all read-only forced writes denied, asserted-v2 denial passed through the new veto path, pursue reached its finite budget with zero writes, read swarm denied a subagent write, write swarm stayed confined (`patchBytes=306`, `userTreeClean=true`, `worktreeCleaned=true`), and the non-vacuous out-of-root absolute write was denied. Exact 0.29.0 had already passed the same 10/0/43 matrix. - **Headless pursue resume remains upstream-blocked.** Both print drivers still use create-only goal parsing; `resumeGoal()` remains TUI/RPC-only. - Edits: `runtime/kimi-version-probe.ts` (`{0,29}` + audit proof), `runtime/stream-json.ts` (verified-through range), version/docs/tests, re-pinned Claude hashes, and regenerated `dist/` + `plugins/kimi-codex/`. Tags: `v1.8.8` and `compat-verified-kimi-code-0.29.1`. Evidence: daily-monitor reports 2026-07-23 and 2026-07-24. ## 1.8.7 — 2026-07-21 **Certifies kimi-code 0.27.0 + 0.28.1** — a chained two-minor catch-up (the minors shipped since the v1.8.4-certified 0.26.0). Verdict **COMPAT-PRESERVED** on both; `KIMI_TESTED_MINORS` extended with `{0,27}` and `{0,28}`. - **The two load-bearing safety surfaces are 0-byte diffs across the whole span.** `02-permission` and `03-hooks` are byte-identical 0.26.0→0.28.1 — policy queue (PreToolCallHook index 0, AgentSwarmExclusiveDeny index 1, AutoModeApprove first approve at index 5, only denies between), the hook engine (exit-2 deny, empty matcher = all tools, any-block-wins aggregation), and the full invariant set (Bash.command / Write.path / Edit.path, `-p` auto + headless handlers + resume-hint emission) reconfirmed by direct checks on the released tags. - **`01-cli-prompt-mode` (1.7 KB) is commands.ts-only**: the top-level `server` registration is replaced by `web` and the YOLO-vs-Auto help text is corrected; `run-prompt.ts`/`options.ts` are byte-identical and the plugin passes its prompt as the VALUE of `-p`, so consumed argv and `-p` routing are unchanged. - **`04-wire-records` is entirely the 0.27.0 session-storage work** (workspace-id registry reuse with safe-id fallback; timestamped debug-export filenames) — session-directory bookkeeping, not `-p` stdout shapes; **0-byte past it**. - **`05-session-bootstrap`**: 0.27.0 wires an optional `resolveWorkspaceId` callback into SessionStore; 0.28.1 adds a one-shot `thinking.effort "max"→"high"` migration that strictly re-parses + reserializes `config.toml` — validated `hooks[]` entries survive as data but **all comments are stripped**, exactly the markerless-hook condition the plugin has handled since v1.8.2. A new marker-strip regression simulates that parse→mutate→stringify shape and asserts the host still verifies installed. - **The 0.28.1 v2 change** (broadcasting session-level permission-mode switches to already-running subagents) is a propagation fix, not a hook bypass — the v2 external-hook runner is byte-identical across the delta. - **Exact-binary smokes GREEN on both releases** (temp-installed exact binaries via `KIMI_PLUGIN_CC_KIMI_BIN`; `bun run smoke:real`): 0.27.0 — 10 pass / 0 fail / 43 assertions; 0.28.1 — 10 / 0 / 43. Full matrix on each: read-only forced-write denials, the `KIMI_CODE_EXPERIMENTAL_FLAG=1` v2 denial lane, pursue budget-abort with zero writes, read-swarm subagent denial, write-swarm confinement (`patchBytes=278`, `userTreeClean=true`, `worktreeCleaned=true`), and the out-of-root absolute-write denial. - **Test-only fix:** a Node ≥25 environment failure — the tsx loader's DEP0205 `module.register()` deprecation warning leaked into a spawned companion's stderr assertion in `tests/runtime/setup-command.test.ts`; the assertion now strips Node deprecation warnings before comparing. - Edits: `runtime/kimi-version-probe.ts` (`{0,27}`/`{0,28}` + chained audit comments), `runtime/stream-json.ts` (verified-through range), AGENTS.md, CHANGELOG.md, ROADMAP audit log, `tests/runtime/{kimi-version-probe,marker-strip,setup-command}.test.ts`, 4-file version bump 1.8.6 → 1.8.7 + re-pinned surface hashes, regenerated `dist/` + `plugins/kimi-codex/`. Tags: `v1.8.7`, `compat-verified-kimi-code-0.27.0`, `compat-verified-kimi-code-0.28.1`. Evidence: daily-monitor reports 2026-07-18 (0.27.0) and 2026-07-21 (0.28.1). ## 1.8.6 — 2026-07-17 **Rescue write-allowlist + verifier hardening, from a k3 (kimi-code 0.26.0) whole-repo self-audit.** A parallel kimi swarm on the new k3 model, cross-checked against the code, surfaced a confirmed parser-divergence write-allowlist bypass, two RCE-class exec-delegating gaps, a batch of per-tool write-flag holes, and two verifier fail-open paths. Every CRITICAL/HIGH was re-verified against the source before fixing; each fix ships with regression tests. No compat change — `KIMI_TESTED_MINORS` still `{…,0,26}`. - **Keystone syntax gate (`hasUnsafeShellSyntax`) — now quote-aware.** The vendored `shell-quote` parser diverges from bash, and a smuggled single-word flag rides that gap past every per-flag check. First cut used word-boundary regexes; a Fable adversarial review then found those both **under-** and **over-**matched, so the gate was rebuilt on two quote-aware passes: - a **throwing-env parse** (`parse(cmd, k => { throw on non-empty key })`) that rejects any real `$VAR`/`${…}` reference — including the CONFIRMED CRITICAL **`$IFS`-gluing** (`rg x$IFS--pre$IFS'sh'` → bash splits into `rg x --pre sh`, an RCE, while the parser glues it into one token so the regex — anchored to a word boundary — missed the letter-preceded `$`), the double-quoted `"$VAR"` form, and `${VAR:-flag}`. It leverages the parser's own quote tracking, so it fires only where bash actually expands. - a **quote-aware scanner** for the constructs the parser doesn't surface as an expansion: backticks, command/process substitution, the `$'…'`/`$"…"` quoting openers (bash decodes `\xNN` into flag bytes), and **brace expansion** (`find . {-delete,}` → `find . -delete`; `sort {-o,}/tmp/x` → a write — both smuggled a token past the flag checks). This also REMOVES the false positives the first-cut regexes introduced: single-quoted literals bash never expands — `grep 'foo $'`, `grep '$(x)'`, `find -name '*.{js,ts}'`, `awk '{print $NF}'` — are now allowed. Verified against a bypass + false-positive battery. - **argparse-abbreviation-proof mypy/pytest report flags.** mypy/pytest parse argv with argparse `allow_abbrev`, so `--jun`→`--junit-xml`, `--html-rep`→`--html-report`, `--cache-di`→`--cache-dir`, `--junitx`→`--junitxml` all resolved past the old exact-and-`=` matching (mypy runs no repo code but writes reports/cache to arbitrary paths and can pip-install). Both now match abbreviation-aware (any unambiguous prefix of a dangerous flag), while legit read flags that merely share a prefix region (`--ignore-missing-imports`, `--incremental`, `-rA`) stay allowed. - **Second review round (Fable + Opus over the *fixes*) — a CRITICAL, a HIGH, and five MEDIUMs closed.** **(CRITICAL)** the quote-aware keystone rebuild treated a DOUBLE-quoted span as inert, but bash keeps command substitution ACTIVE inside double quotes — `grep "$(id)" file`, `` ls "`whoami`" `` executed (RCE in every write-capable mode; `$VAR` was still caught, only `$(…)`/backtick leaked). The double-quote scan now looks for non-escaped `$(`/backtick while `"\$(x)"`/`` "\`x`" `` stay literal. Then: **(HIGH)** `evaluateInstalled` now runs a whole-file smol-toml parse (`foundHookEntryIsClean`) on the marked-block success path — a `matcher = "*"` (or stray key) placed AFTER the `# === END … ===` comment is still part of the same `[[hooks]]` TOML table, so kimi-code loaded it and disabled the hook while the line-scanned *body* looked clean (fail-open `installed:true`); **(MED)** `sort` bundled short-flag clusters (`sort -rT /tmp`, `-ro file`) that the plain `-o` check missed, now scanned with getopt semantics; **(MED)** `tsc` option names are case-insensitive, so `--outdir`/`--tsbuildinfofile` are matched lowercased (`--outdir` == `--outDir`); **(MED)** `eslint --parser`/`--rulesdir`/`--resolve-plugins-relative-to` load+execute a module from an arbitrary path (code-exec escape); **(MED)** `mypy --config-file` (a config can set `plugins=` → imports Python); **(MED)** `ruff --config` (inline `fix=true` override flips write mode). All verified live against on-disk code before and after. (The same round confirmed the quote-aware keystone already closes `$IFS`-glue, `$'…'` mid-word, and brace `{,}` — a fresh adversarial pass reproduced those only against the pre-rewrite regex version.) - **Exec-delegating flags (RCE) rejected for every tool.** `rg --pre ` (per-file preprocessor), `rg --hostname-bin `, and `sort --compress-program ` (GNU sort spill (de)compressor) all run their VALUE as a command; added to `EXEC_DELEGATING_FLAGS_EXACT`/`_PREFIXES` alongside the existing `--open-files-in-pager`/`-vettool`/`-toolexec`/`-exec` set. - **Per-tool write-flag gaps closed.** New per-tool checks reject writes that survive a tool's read/check mode: `tsc --generateCpuProfile/--generateTrace/--tsBuildInfoFile/--outFile/--outDir/--out/--declarationDir` (survive `--noEmit`); `biome check --apply*/--write*/--fix*` (the `-unsafe`/`-only` suffixes dodged the global exact/prefix set); `ruff check --add-noqa/--fix-only/--cache-dir/--output-file` (`--fix-only` dodged the global `--fix`); `cargo --target-dir/--out-dir`; `go test -coverprofile/-cpuprofile/-memprofile/-blockprofile/-mutexprofile/-trace/-outputdir`; joined `eslint -o` + `--cache-location`; `mypy --junit*`/`--*-report`/`--cache-dir`/`--install-types` (argparse `allow_abbrev`-proof by prefix); and pipeline `sort -T`/`--temporary-directory`. - **HIGH — `verifyHookInstalled` script-existence check.** A byte-exact `command` match no longer blesses an install on its own: the verifier now confirms the hook SCRIPT file exists and is readable (`access(…, R_OK)`, fail-closed). A pruned versioned-dist directory left the config matching while kimi-code's `/bin/sh -c '' '