Repository navigation
fix(kimi): proven-empty manifest selection and read-only native projection - #462
Conversation
…projection read-only A skills-only Kimi package projects a manifest that declares "mcpServers" only when servers were selected, so the managed selection reader treated a verified projection as unrecognizable shape and refused every no-change update. The same update path also required a read-only native projection that the Kimi adapter never implemented, and the group flow persisted the empty outcome of that early failure, which the state store then refused as an unknown lifecycle state. - selection documents that declare "mcpServers" conditionally record a verified document without the member as a proven empty selection; dedicated selection documents keep failing closed - Kimi implements the read-only native projection by revalidating the committed manifest identity; everything it owns lives inside the digest-verified managed package directory - a projection failure before activation preserves the recorded lifecycle so the report carries the projection error instead of a state refusal
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #462 +/- ##
=======================================
Coverage 62.76% 62.77%
=======================================
Files 1595 1595
Lines 91851 91874 +23
=======================================
+ Hits 57654 57676 +22
- Misses 25961 25962 +1
Partials 8236 8236 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ation A projection failure happens before the adapter can run: keep the recorded lifecycle and acknowledged objects with NativeEffectUnchanged instead of persisting an empty outcome, and only mark a no-change target mutated when an incomplete projection actually re-activated successfully.
… lint Split ManagedMCPNames into focused helpers to stay under the complexity gate, wrap JSON errors with %w (errorlint), and keep the nil-map reset so nested unmarshal replaces rather than merges server keys.
Summary
A skills-only Kimi package projects
.kimi-plugin/plugin.jsonthat declares "mcpServers" only when servers were selected. The managed MCP selection reader treated a verified document without that member as unrecognizable shape and refused every no-change update with "refusing silent update before previous MCP selection can be verified". Two more gaps on the same path surfaced once that gate passed:Changes:
clients.SelectionLayout.ServersMemberOptional: a selection document that declares "mcpServers" conditionally records a verified document without the member as a proven empty selection; dedicated selection documents keep failing closed on a missing member.clients/kimi: implementsclients.ActiveNativeProjector. Everything Kimi owns — the projected manifest included — lives inside the digest-verified managed package directory, so the read-only projection revalidates the committed manifest identity and rebuilds no external ownership.usecase/group_activate.go: a projection failure before activation preserves the recorded lifecycle and acknowledged objects (NativeEffectUnchanged, matching the refused-prepared-activation precedent) instead of persisting an empty outcome, so the report carries the projection error and remaining targets are not stopped by a bogus persist failure. A failed attempt no longer claims a mutation: only a successful re-activation of an incomplete projection marks the target changed.Verification
Discriminating pairs — each test fails on pristine 37682cf for the exact bug and passes on this branch:
TestManifestSelectionWithoutServersMemberIsProvenEmpty(providers) — pre-fix fails with "managed MCP selection lacks mcpServers"; post-fix the kimi skills-only manifest is accepted as a proven empty selection.TestProjectActiveNativeRevalidatesManifestIdentityWithoutWriting(clients/kimi) — does not compile before the adapter gained the capability; identity drift fails the read-only projection.TestGroupedKimiNoChangeUpdateRunsReadOnlyNativeProjection(usecase) — pre-fix fails with "managed MCP selection lacks mcpServers"; post-fix the no-change update completes withno_change, zero receipts, no claimed mutation and byte-identical state.TestGroupedProjectionFailurePreservesRecordedLifecycle(usecase) — pre-fix fails with the masked "refuse invalid state: ... unknown lifecycle state" and a falsemutated=trueon a path that wrote nothing; post-fix the projection error surfaces, the stage is not "persist", and the recorded lifecycle is preserved.Complement guards (pass before and after; they pin the fix against over-broadening):
TestDedicatedSelectionStillFailsClosedWithoutServersMember(a dedicated selection document without its member is still unrecognizable shape),TestManagedMCPSelectionRequiresExactArtifactincluding the kimi layout.End-to-end on macOS with a clean
agentplugins 0.1.88build over a 13-client lifecycle cycle (codex, cursor, copilot, vscode, kiro, claude, gemini, opencode, cline, windsurf, grok, kimi, qoder):external_completed, grok/kimi/qoder activationactive;no_change=true mutated=false receipts=0 failure=null, including kimi and qoder, with before/after filesystem snapshotsIDENTICAL— the direct counterpart of the pre-fix failure "refuse invalid state" that also stopped qoder ("not attempted");doctorsuccess.Full Go suite: failure set identical to the pristine baseline (35 pre-existing darwin-local failures, no new ones). The three review findings (refused-prepared-activation NativeEffect precedent, contradictory Mutated/NoChange flags on a failed no-change projection, missing ctx check in the new projector) are addressed in the follow-up commit; a second follow-up splits the managed MCP selection parsing into focused helpers to satisfy the CI complexity gate and wraps its JSON errors with %w (verified behavior-preserving: selection tests and full providers failure set match the baseline).
Release Impact
Adapter and usecase only; no public JSON capabilities contract changes (
SelectionLayoutis installer policy and is not serialized). Released as agentplugins 0.1.88; registry CLI pin and binary digest bump follow in the registry PR.Summary by CodeRabbit
New Features
Bug Fixes