LearnNewsExamplesServices
Frontmatter
id15612
titleSeat-config generator: Kimi Code harness target (registry + launch contract + emission)
stateClosed
labels
enhancementai
assigneesneo-kimi-iris
createdAtJul 20, 2026, 7:04 PM
updatedAtJul 20, 2026, 8:31 PM
githubUrlhttps://github.com/neomjs/neo/issues/15612
authorneo-kimi-iris
commentsCount0
parentIssue15586
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 20, 2026, 8:31 PM

Seat-config generator: Kimi Code harness target (registry + launch contract + emission)

Closed Backlog/active-chunk-8 enhancementai
neo-kimi-iris
neo-kimi-iris commented on Jul 20, 2026, 7:04 PM

Context

Leaf of Epic #15586 (Full Kimi Code support in the Neo Agent Harness / Fleet Manager), decomposed at the epic's own precondition — both harness adapters are now production-proven (wake: fire/no-fire + #15596/PR #15600 merged; presence: #15580 → PR #15587 at ready-flip). Two kimi seats exist, and both were hand-built: Phoebe's OpenCode seat (2026-07-18, productized as generateOpenCodeSeatConfig.mjs) and the Iris seat (2026-07-19, hand-provisioned — its config.toml + hook wiring is the living reference). A third kimi seat today means hand-building again. The generator needs a Kimi Code target, and the launch-template registry needs the harness type it hangs on.

Live latest-open sweep: checked latest 20 open issues at 2026-07-20 ~15:55Z — no equivalent (#15392 is the seat-config generator surface this leaf extends, not a duplicate; #15592 per-seat evidence records is adjacent-not-duplicate). A2A in-flight sweep (last 30, all read-states): no competing claim on this scope.

The Problem

  1. Registry gap: src/ai/fleet/harnessTypes.mjs (HARNESS_TYPES) has no 'kimi-code' entry — and deriveHarnessLaunchSpec.mjs's import-time lockstep guard enforces that a launch contract can only exist for a registered type, so every Kimi launch/steer surface is blocked at the registry.
  2. Launch-contract gap: the per-family launch template (isolation home, supervisable mode, version probe, auth mode) is undefined for Kimi Code. The contract facts are knowable but unprobed: KIMI_CODE_HOME is the harness's config/state home env var (official docs), kimi web is the resident server mode (v0.28; --port, bearer auth, /api/v1/sessions/* REST surface verified live 2026-07-20), auth rides the seat env (flatrate API key) or OAuth file storage. Which mode is supervisable (EOF-stdin tolerance, SIGTERM cleanliness, port auto-assign) needs the same empirical probe evidence the sibling contracts carry.
  3. Generator gap: generateOpenCodeSeatConfig.mjs emits the OpenCode seat (opencode.jsonc + memory-layer scaffold + wake boot hook) as a pure params→files emission. No Kimi sibling exists: the seat's config.toml (permission rules per MCP server, provider/model blocks, hooks array), the SessionStart wake-envelope hook, and the always-loaded memory-layer wiring are all hand-authored per seat today.

The Architectural Reality

  • ai/services/fleet/generateOpenCodeSeatConfig.mjs — the sibling precedent: pure emission (no config imports/env/fs), island guard (server code resolves inside the canonical checkout), seat-personal --env-file binding, memory-layer scaffold with story-sovereignty (identity.md near-empty by construction).
  • ai/services/fleet/deriveHarnessLaunchSpec.mjs — contract map + lockstep guard; the 'opencode' entry (serve mode, XDG two-var isolation, env-key auth, --version probe) is the shape the Kimi entry mirrors.
  • src/ai/fleet/harnessTypes.mjs — the shared registry authority the Body's pickers/cards also derive from (one registration feeds both hemispheres).
  • The Iris seat's hand-built reference (verified 2026-07-20): ~/.kimi-code/config.toml (permission rules per mcp__neo-mjs-* server; managed:kimi-code provider + OAuth file storage; K3 model block; [[hooks]] SessionStart → .kimi-code/hooks/wakeEnvelopeHook.mjs + the presence-hook family once #15580 lands); the MCP server set is the same four canonical servers (OPENCODE_SEAT_SERVERS shape — kimi wiring path to be pinned at implementation: project-level .kimi-code/ vs home-level config).
  • Kimi has no OpenCode-style instructions slot — the day-two reload lesson (identity.md present but not auto-loaded) proves the always-loaded layer needs a deliberate wiring decision for this harness (candidate surfaces: seat-checkout AGENTS.md pointer, harness memory config if shipped). This is a named design question, not an afterthought — a generated seat that forgets its identity layer is worse than none.
  • Runner-shape seam (epic steward note, 2026-07-20): seats exist as TUI-hosted vs server-hosted runners with different wake-addressability; the generated config must produce the wake-addressable shape by default (resident server + envelope hook), with the TUI shape as the documented interactive alternative.

The Fix

  1. Register the type: add {type: 'kimi-code', label: 'Kimi Code'} to HARNESS_TYPES (lockstep guard then passes; Body pickers inherit).
  2. Launch contract in HARNESS_LAUNCH_CONTRACTS: homeEnvVar: 'KIMI_CODE_HOME', authMode: 'env-key' (flatrate API key rides seat env; OAuth file storage documented as the interactive alternative), versionProbeArgs: ['--version'], supervisable modeArgs determined by probe (kimi web --no-open --port … resident server vs documented alternative) — with the probe evidence recorded in the JSDoc exactly as the sibling contracts do (EOF/held-pipe liveness, SIGTERM-clean stop, port assignment, isolation census under a fresh KIMI_CODE_HOME).
  3. generateKimiSeatConfig.mjs (sibling, pure emission): emits config.toml (canonical four-server MCP wiring + permission allow rules + provider/model defaults + hooks array), the SessionStart wake-envelope hook script (standalone node, C1-clean, mode 0600 envelope — the #15596 coordinate contract by construction), and the memory-layer scaffold with the always-loaded wiring decided per the design question above. Island guard + seat-personal --env-file discipline mirrored.
  4. Unit specs in the existing fleet/generator spec family: registry/lockstep, contract derivation (isolation env, probe args, password-free emission), emission content (TOML parses, hook script parses, island guard rejects escapes, identity.md stays near-empty).

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
HARNESS_TYPES registry src/ai/fleet/harnessTypes.mjs 'kimi-code' registered lockstep guard throws on drift module JSDoc unit: registry subset
Launch contract deriveHarnessLaunchSpec.mjs kimi-code entry per above unknown type throws (existing) fn JSDoc probe record unit: derivation
KIMI_CODE_HOME Kimi Code official docs (config-files/data-locations) Isolation home env var n/a launch contract JSDoc live: doctor/config reads
kimi web resident mode v0.28.0 observed behavior Supervisable server shape (probed) documented alternative if probe fails launch contract JSDoc probe: liveness/SIGTERM/port
generateKimiSeatConfig.mjs new sibling module Pure params→files emission n/a module JSDoc unit: emission specs

Decision Record impact: aligned-with ADR 0020 (agent harness seat architecture — this leaf is the Kimi target of its seat-config/launch surfaces, not a new shape). Also consumes (does not amend) the ADR 0019 SSOT discipline: the generator stays a pure emission with zero config imports.

Acceptance Criteria

  • 'kimi-code' registered in HARNESS_TYPES; lockstep guard green; Body pickers derive the type from the same entry
  • Launch contract derivation green with probe evidence recorded (isolation census, liveness on held pipe AND EOF'd stdin, SIGTERM-clean, version probe answers without full boot)
  • generateKimiSeatConfig.mjs emits config.toml + wake hook + memory scaffold; TOML/hook parse checks green; island guard rejects canonicalRoot escapes
  • The always-loaded memory-layer wiring decision is made + documented (no silent repeat of the day-two reload lesson)
  • Unit specs green in the custom unit config (never default npx playwright test)
  • Post-merge (flagged): regenerate one throwaway kimi seat from the emission and boot it through a wake fire/no-fire cycle (the #15596 contract held by construction)

Out of Scope

  • The cockpit driver/registry UI surface (Epic #15586's sibling leaf — roster/definitions/rails).
  • Presence-hook emission beyond the wiring seam (owned by #15580/PR #15587's contract; this leaf wires the hook array, it does not redefine presence semantics).
  • Wake-policy / heartbeat floors (#15405 owns).

Avoided Traps

  • Kimi-specific branches in generic FM surfaces — one registry entry + one contract + one sibling generator; nothing kimi leaks into shared paths (the epic's core anti-trap).
  • Hand-copying the Iris seat's config.toml as the template — the hand-built seat carries liveproof/personal residue; the emission derives from the canonical pattern (like the OpenCode generator), with the seat's file as evidence, not as the source.
  • Emitting credentials — tokens/OAuth material never enter emitted files; auth stays seat-env/OAuth-store at call time (the opencode envelope discipline, mirrored).

Related

  • Epic #15586 (parent) · #15579/PR #15588 + #15596/PR #15600 (wake adapter, proven) · #15580/PR #15587 (presence hooks) · #15392 (seat-config generator surface) · #15390 × #15581 (harness-diff pair-zero) · ADR 0020 · D#15595 OQ11 (harness-server residency — the runner-shape seam's design home)

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

Handoff Retrieval Hints: query_raw_memories("kimi seat config generator harness launch contract KIMI_CODE_HOME"); living reference = the Iris seat's hand-built ~/.kimi-code/config.toml + .kimi-code/hooks/wakeEnvelopeHook.mjs; sibling pattern = ai/services/fleet/generateOpenCodeSeatConfig.mjs + its spec family.