LearnNewsExamplesServices
Frontmatter
id15618
titlekimi seat generator: permission-rule pattern must match Kimi''s hyphenated tool ids (+ L3 boot home)
stateClosed
labels
bugai
assigneesneo-kimi-iris
createdAtJul 20, 2026, 8:33 PM
updatedAtJul 20, 2026, 9:01 PM
githubUrlhttps://github.com/neomjs/neo/issues/15618
authorneo-kimi-iris
commentsCount0
parentIssue15586
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 20, 2026, 9:01 PM

kimi seat generator: permission-rule pattern must match Kimi's hyphenated tool ids (+ L3 boot home)

neo-kimi-iris
neo-kimi-iris commented on Jul 20, 2026, 8:33 PM

Context

Vega's Approve+Follow-Up review on PR #15613 (merged as the #15612 leaf) named two non-blocking items that need a durable home now that Resolves #15612 closed the leaf ticket (post-review-followup-surfacing rule). One of them is a real latent defect his review isolated precisely: the emitted [[permission.rules]] pattern uses underscores (mcp__neo_mjs_memory_core__*), but Kimi's actual MCP tool ids keep the server names verbatim with hyphens (mcp__neo-mjs-memory-core__list_messages) — proven by the Iris seat's living-reference config.toml (Phoebe-provisioned, daily-driven since 2026-07-19) and by the live tool namespace every kimi session loads. The emitted rules would be dead on arrival; only default_permission_mode = "auto" would be load-bearing. The shipped spec asserted the same wrong transform as the generator, so the tautology passed CI — exactly the "false coverage confidence on the single unverified runtime contract" the review flagged (EXECUTION_QUALITY −12).

The Problem

  1. Generator defect (latent): generateKimiSeatConfig.mjs renderConfigToml() emits mcp__${server.name.replaceAll('-', '_')}__* — a transform borrowed from MCP hosts that canonicalize dashes, which Kimi does NOT do. Zero generated seats exist yet (no consumer; prepareManagedAgentWorkspace fails closed for kimi-code), so the blast radius is bounded to the emission + spec.
  2. Spec tautology: generateKimiSeatConfig.spec.mjs computes the expected pattern with the same replaceAll, so the test proves the code equals itself, not that the pattern matches the harness's real tool ids.
  3. L3 boot homeless: the #15612 post-merge AC (generate a throwaway seat, boot it through a wake fire/no-fire cycle) lost its tracker when the leaf closed; per the follow-up rule it must live on Epic #15586 — and per the review it must be sharpened to exercise the permission-rule pattern (a wake-fired MCP call with no approval freeze) and to state whether default_permission_mode = "auto" or the rules are load-bearing.

The Architectural Reality

  • ai/services/fleet/generateKimiSeatConfig.mjsrenderConfigToml() (~L131): the replaceAll('-', '_') transform to remove; Kimi matches permission patterns against the literal mcp__<server-name>__<tool> ids.
  • Living reference: the Iris seat's hand-built ~/.kimi-code/config.toml L4-22 (pattern = "mcp__neo-mjs-memory-core__*" — hyphens, daily-proven through hundreds of MCP calls at default_permission_mode = "auto" + rules).
  • test/playwright/unit/ai/services/fleet/generateKimiSeatConfig.spec.mjs — the golden-shape permission case to re-anchor on the harness fact (assert the verbatim-hyphen form with a comment naming the living-reference evidence, so the tautology cannot regrow).

The Fix

  1. Generator: emit mcp__${server.name}__* (verbatim server name, hyphens preserved).
  2. Spec: assert the exact hyphenated patterns for all four canonical servers, with a comment citing the living-reference config.toml as the authority (asserting a harness FACT, not a transform).
  3. Run the fleet family; PR with the review linkage.
  4. Post-merge (the L3 boot, operator-gated): generate one throwaway kimi seat from the emission, boot it, and drive a wake-fired MCP call through the emitted rules — record whether auto mode or the rules were load-bearing, then re-run the fire/no-fire cycle (the #15596 contract) as the boot's closing proof.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
[[permission.rules]] pattern Kimi live tool ids (mcp__neo-mjs-*__* verbatim) Hyphenated verbatim pattern default_permission_mode = "auto" covers if rules mismatch (but then rules are dead weight) living-reference config.toml unit: hyphen-form assertion; L3: wake-fired MCP call (post-merge)
Spec golden-shape case generateKimiSeatConfig.spec.mjs Asserts the harness fact, not the transform n/a spec comment this ticket

Decision Record impact: none — defect fix inside the shipped leaf; no ADR conflict. Parent: Epic #15586.

Acceptance Criteria

  • Emitted patterns match the living-reference hyphen form for all four servers (unit-verified)
  • Spec asserts the harness fact with the living-reference citation (tautology killed)
  • Fleet spec family green in the custom unit config
  • Post-merge (flagged, operator-gated): throwaway-seat boot drives a wake-fired MCP call through the emitted rules with no approval freeze + records whether auto mode or the rules were load-bearing + fire/no-fire cycle green

Out of Scope

  • The cockpit UI leaf (Epic #15586 sibling — unfiled, declared in the steward note).
  • Presence-hook emission (#15580/PR #15587 owns the contract).

Avoided Traps

  • Transform conventions from other MCP hosts — Kimi is its own naming authority; assert against the living reference, not host folklore.
  • Deleting the rules instead of fixing them — auto mode alone would work, but the rules are the defense-in-depth layer the seat design wants; fix the pattern, keep the layer.

Related

  • PR #15613 + Vega's review (pullrequestreview-4737802255) · #15612 (shipped leaf) · Epic #15586 (parent) · #15596 (wake coordinate contract the boot re-proves) · #15580/PR #15587 (presence contract)

Origin Session ID: session_e86fa9f0-866e-45e8-a6df-d7bb6dd4d8b5 (kimi-code session, Iris seat)

Handoff Retrieval Hints: query_raw_memories("kimi permission rule hyphen underscore pattern review follow-up"); living reference = the Iris seat's ~/.kimi-code/config.toml L4-22.