Skip to content

Support Kimi Code CLI as a builder (PIR #1201)#1203

Open
mohidmakhdoomi wants to merge 28 commits into
cluesmith:mainfrom
mohidmakhdoomi:builder/pir-1201
Open

Support Kimi Code CLI as a builder (PIR #1201)#1203
mohidmakhdoomi wants to merge 28 commits into
cluesmith:mainfrom
mohidmakhdoomi:builder/pir-1201

Conversation

@mohidmakhdoomi

@mohidmakhdoomi mohidmakhdoomi commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

PIR Review: Support Kimi Code CLI as a builder

Fixes #1201

Summary

Adds the Kimi Code CLI (kimi, ≥ 0.27.0) as a supported builder harness — shell.builder: "kimi" / builderHarness: "kimi" / --builder-cmd kimi now produce a working builder instead of the #1062 false-Claude fallthrough (which appended --append-system-prompt and a positional prompt, both rejected by kimi, and could route a stale Claude --resume <uuid> into it). Because Kimi documents no system-prompt flag and no positional prompt, the launch shape is provider-owned: a seed-session bootstrap (validated by spike task-Iptx) delivers role + task via a one-shot kimi -p whose captured session id pins a kimi -S <id> --yolo TUI loop, with a Tower-side readiness barrier (sentinel-gated, store-verified BEGIN kick) and a per-harness delayed-Enter pacing knob so afx send actually submits. Kimi as an architect is explicitly out of scope (stage 2).

Files Changed

git diff --stat $(git merge-base main HEAD) (excluding porch state commits):

  • packages/codev/src/agent-farm/utils/harness.ts (+263) — KIMI_HARNESS, detection, buildBuilderLaunchScript / seedDelivery / messagePacing interface capabilities, buildResume
  • packages/codev/src/agent-farm/utils/kimi-session-discovery.ts (+197, new) — store scan / ownership verify / state reader (fail-soft; KIMI_CODE_HOME-aware)
  • packages/codev/src/agent-farm/commands/spawn-worktree.ts (+111/−9) — provider-owned script branch, .builder-seed.txt, seedKick pass-through
  • packages/codev/src/agent-farm/servers/seed-kick.ts (+194, new) — sentinel watcher + grace + store-verified kick retry ladder
  • packages/codev/src/agent-farm/servers/message-pacing.ts (+55, new) — per-target pacing resolution (worktree-marker probe first, config-resolved harness fallback)
  • packages/codev/src/agent-farm/servers/message-write.ts (+16/−2) — optional pacing.enterDelayMs override
  • packages/codev/src/agent-farm/servers/tower-routes.ts (+20/−2) — seedKick on terminal create; pacing at both send paths
  • packages/codev/src/agent-farm/servers/tower-cron.ts (+6/−2) — pacing at cron delivery
  • packages/core/src/tower-client.ts (+24) — SeedKickRequest wire type on createTerminal
  • packages/codev/src/agent-farm/lib/tower-client.ts (+1) — re-export
  • packages/codev/src/commands/doctor.ts (+110/−2) — kimi presence/minVersion, auth heuristic, kimi doctor config check, store smoke probe, architect-kimi warning
  • Tests (+~900 across 8 files): new kimi-session-discovery.test.ts, seed-kick.test.ts, message-pacing.test.ts; extended harness.test.ts, spawn-worktree.test.ts, config.test.ts, discover-resume-session.test.ts, bugfix-584-send-multiline-pacing.test.ts
  • Docs: codev/resources/arch.md (+16/−2, dedicated Kimi subsection), codev/resources/commands/agent-farm.md + codev-skeleton/resources/commands/agent-farm.md (builder-harness config examples — skeleton mirrored)
  • codev/spikes/pir-1201-kimi-builder-demo.mjs (+193, new) — runnable live-demo driver (real kimi, real dist modules)
  • codev/plans/1201-…md, codev/state/pir-1201_thread.md

Total: 27 files, +2378/−23.

Commits

Test Results

  • pnpm build: ✓ pass (types → core → codev, incl. dashboard + skeleton copy)
  • pnpm test (vitest): ✓ pass — 3592 passed, 48 skipped (~75 new tests). Porch's build/tests checks green at both the dev-approval and review transitions.
  • Support codex as an architect #929-class regression covered from four angles: kimi + a stale Claude .jsonl can never yield --resume <claude-uuid> or --append-system-prompt (harness buildResume, discoverResumeSession, config/override resolution, generated-script assertions).
  • Live validation on real kimi 0.27.0:
    • Enter-delay bisect (POC probe-10 method): 80ms and 100ms swallowed; 120/250/500/1000ms submit → threshold ≈ 100–120ms; shipped KIMI_ENTER_DELAY_MS = 1000 (~9x margin; latency-only cost).
    • Demo driver (node codev/spikes/pir-1201-kimi-builder-demo.mjs): 5/5 PASS — seed bootstrap + id capture; sentinel-gated store-verified BEGIN (lastPrompt="BEGIN"); multiline delivery at pinned delay; inner-restart context retention (role token + task recalled verbatim after killing the TUI); buildResume returns the pinned id. The spike addendum's open question — does ack-and-wait hold with a task attached? — held; the pre-planned role-only-seed fallback was not needed.
    • Human full-path verification at the dev-approval gate: real afx spawn through Tower (branch build via local-install); all 4 checklist items passed live.

Architecture Updates

Routed to the COLD tier (codev/resources/arch.md, updated in commit f0754430): a dedicated "Kimi Builder Harness (Issue #1201)" subsection under Agent Farm Internals — builder-only status, the seed-session bootstrap, the sentinel + store-verified BEGIN barrier, per-harness pacing with the marker-probe resolution order, explicit-ID resume, and the caveats (undocumented store surfaces + 0.27.0 pin + doctor smoke probe; no write-guard parity — Kimi has no documented hook seam; in-memory kick lost on Tower restart during the seed window). The harness enumeration lines in the same section were extended.

No HOT tier (arch-critical.md) change: kimi support is subsystem detail, not a top-10 always-on system-shape fact; the existing hot facts (runtime resolution, dual-tree mirroring, porch/state invariants) already cover the decision surface this touches.

Lessons Learned Updates

Routed to the COLD tier (codev/resources/lessons-learned.md, Architecture section, this commit):

  1. Advisory decorators on critical paths must be failure-total — the pacing resolver's narrow try/catch let a mocked-out dependency 500 every /api/send in the test env; the whole body now degrades to defaults.
  2. Per-instance runtime facts that config cannot know are best carried by a self-describing on-disk marker in the instance's own directory.builder-kimi-session makes pacing correct for --builder-cmd override spawns across Tower restarts with zero schema migration.

No HOT tier (lessons-critical.md) change: both lessons are architecture-pattern reference material, not behavior-changing cross-cutting rules of the always-on caliber (the cap is full of broader rules that would each beat these on displacement).

Things to Look At During PR Review

  • PR-consultation finding (codex, REQUEST_CHANGES — FIXED): the original delivery confirmation used lastPrompt.includes(kickMessage). Real defect: on a fresh spawn lastPrompt initially holds the seed prompt, whose ack-and-wait wrapper itself says "wait for BEGIN" — so the substring check reported success before the kick ever submitted, silently defeating the swallowed-Enter recovery (the live demo's happy path masked it: the kick genuinely landed, so the false-positive window was never observed). Fixed in seed-kick.ts by requiring whitespace-normalized equality (submitted messages land in lastPrompt with newlines flattened to spaces — observed), with two pinning regression tests (seed-prompt-containing-BEGIN must NOT confirm and must escalate to the Enter re-send; a multi-line kick payload must still confirm through the flattening). Gemini and Claude both returned APPROVE; PIR's consultation is single-pass, so this fix was not independently re-reviewed — please eyeball confirmed() in seed-kick.ts at the pr gate. The live demo was re-run after the fix: still 5/5 PASS (no false negative).
  • seed-kick.ts retry ladder semantics: updatedAt movement is deliberately NOT trusted as confirmation (the TUI touches the store on open, which would false-positive and suppress the Enter re-send). A false negative only costs a duplicate BEGIN + loud warn.
  • message-pacing.ts resolution order: marker probe before config, by design (override robustness — see plan-review note). The probe stats one file per message send; sends are rare, so no perf concern.
  • Undocumented-surface reliance is deliberately narrow: discovery scans only sessions/*/*/state.json (not session_index.jsonl — one undocumented surface instead of two); every reader is fail-soft to the fresh-with-role path; doctor carries the drift probe.
  • kimiTuiCmd appends --yolo unless the user already passed it; --auto is deliberately never used (documented conflict with --yolo; suppresses agent→user questions the gate workflow needs).
  • Kimi builders have NO write-guard (Builder worktree write-guard: prevent writes anchored at the main checkout root #1018 parity impossible — no documented hook seam). Documented in arch.md and the config docs; the "static deny rules" hint in Kimi's -p docs is flagged as follow-up investigation, not a claimed guarantee.
  • Doctor's kimi lane follows the existing print-flow style (no dedicated unit tests, matching the opencode/gemini architect-warning precedent); its logic-bearing pieces (kimiStoreLayoutLooksDrifted, discovery readers) are unit-tested in the discovery suite.

How to Test Locally

  • View diff: VSCode sidebar → right-click builder pir-1201View Diff (or gh pr diff).
  • Standalone demo (no Tower changes needed): from the branch checkout, pnpm build then node codev/spikes/pir-1201-kimi-builder-demo.mjs — requires an authenticated kimi ≥ 0.27.0; prints PASS/FAIL for all five checklist steps.
  • Full Tower path: pnpm -w run local-install (restarts Tower), then from the main workspace root: afx spawn --task "any small task" --builder-cmd kimi → watch seed → __CODEV_KIMI_SEED_DONE__ → BEGIN in the builder pane; afx send <builder-id> with a >3-line message → submits as one message; kill the TUI (Ctrl+C once) → restart resumes with context; afx spawn --resume after killing the terminal.
  • codev doctor with kimi installed → presence + version gate, heuristic auth line, smoke probe; with shell.architect: "kimi" → builder-only warning.

Maintainer note: please add the area/tower label to issue #1201 (we can't set labels cross-fork).

mohidmakhdoomi and others added 26 commits July 18, 2026 18:59
…ilder and architect

Seed-session bootstrap (kimi -p role seed -> capture session id from
stream-json -> TUI resume via -S) validated end-to-end; solves role
injection, initial prompt delivery, and the stored-ID session contract.
Includes reproducible POC script and full impact map / test matrix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cluesmith#1149 parity requirement

Two new observations: Kimi TUI never enters the alternate screen (no
escape-based readiness signal), and PTY input during the seed window has
no defined consumer (silently lost). Barrier design: sentinel + grace +
store-verified delivery with retry; seed carries role+task, kick is a
single BEGIN line. Architect parity correction: stored-ID resume without
an async-buildable CrashLoopFallback is cap-exhaustion outage, not cluesmith#1149
safety — ship Codex-like (stage 1) or stored-ID + async fallback (stage
2), no middle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ipt, builder resume

- KIMI_HARNESS in harness.ts + detectHarnessFromCommand('kimi') — kills the
  cluesmith#1062 false-Claude fallthrough; buildRoleInjection throws (builder-only)
- New optional HarnessProvider.buildBuilderLaunchScript capability; Kimi
  generates the seed-session bootstrap script (idempotent seed via kimi -p
  stream-json, session.resume_hint capture, sentinel, pinned -S --yolo loop)
- kimi-session-discovery.ts: store scan / ownership verify / state reader
  (undocumented store layout, observed on kimi 0.27.0; fail-soft)
- buildResume: .builder-kimi-session precedence (ownership-verified) → store
  scan → null → fresh-with-role fallback
- spawn-worktree branches on the capability; writes .builder-seed.txt and
  passes the seedKick request through createPtySession
- Tests incl. the cluesmith#929-class regression: kimi + stale Claude jsonl never
  yields --resume <claude-uuid> or --append-system-prompt

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ss Enter pacing

- seed-kick.ts: readiness barrier — waits for the launch script's
  __CODEV_KIMI_SEED_DONE__ sentinel (writes during the seed window are
  silently lost), grace, then a store-verified BEGIN kick with an
  Enter-resend → kick-resend → loud-warn retry ladder
- createTerminal grows an optional seedKick field (core SeedKickRequest);
  handleTerminalCreate validates and arms it (malformed → ignored)
- message-write.ts: optional pacing.enterDelayMs overriding both default
  Enter delays (Kimi swallows an 80ms Enter; defaults unchanged otherwise)
- message-pacing.ts: resolves pacing per target — worktree marker probe
  first (override-proof for --builder-cmd spawns, survives Tower restarts),
  then config-resolved harness by terminal role
- Wired at all delivery paths: send direct + buffered, cron

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…store smoke probe

- Kimi in AI_DEPENDENCIES: kimi --version presence with minVersion 0.27.0
  (pins the version the undocumented surfaces were observed against)
- verifyKimi(): credential-artifact heuristic (no billed probe — Kimi
  documents no auth status command), kimi login guidance; supplementary
  'kimi doctor' config check (documented exit codes, not an auth check)
- Session-store layout smoke probe warns loudly on drift
- Architect-shell branch: kimi configured as architect → builder-only warning

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mples, skeleton mirror)

- arch.md: dedicated Kimi subsection (builder-only, seed-session bootstrap,
  sentinel-gated store-verified BEGIN, per-harness pacing, explicit-ID
  resume, undocumented-surface caveats + 0.27.0 pin, NO write-guard parity)
- agent-farm.md (instance + skeleton): builder-harness config examples

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on session type

- resolvePacingForSession wraps its whole body in try/catch: pacing is
  advisory and must never break message delivery (a missing DB in the
  tower-routes test env surfaced this as 500s on /api/send)
- CronDeps session shape carries id/cwd (the real PtySession provides both)
- tower-routes test mock gains getTerminalSessionById

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bisected on kimi 0.27.0: 80ms and 100ms swallowed; 120/250/500/1000ms
submit. Threshold ~100-120ms; shipped value stays 1000ms (~9x margin).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s pass)

codev/spikes/pir-1201-kimi-builder-demo.mjs runs the real dist modules
(script generator, armSeedKick, writeMessageToSession, buildResume)
against a real kimi PTY: seed bootstrap, sentinel-gated store-verified
BEGIN, multiline delivery at the pinned Enter delay, inner-restart
context retention, and -S resume. Executed against kimi 0.27.0 — 5/5
PASS; the ack-and-wait-with-task seed discipline held (no fallback
needed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ier)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… consultation finding)

The delivery check used lastPrompt.includes(kickMessage) — but on a fresh
spawn lastPrompt initially holds the SEED prompt, whose ack-and-wait
wrapper itself mentions BEGIN, so the verifier reported success before the
kick ever submitted (silently defeating the swallowed-Enter recovery; the
live demo's happy path masked it). Confirmation now requires
whitespace-normalized EQUALITY (submitted messages land in lastPrompt with
newlines flattened to spaces — observed on kimi 0.27.0). Two pinning
regression tests added; live demo re-run post-fix: 5/5 PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mohidmakhdoomi

Copy link
Copy Markdown
Contributor Author

Architect Integration Review

Contributor-side review summary for maintainers (this PR was developed under the PIR protocol on our fork; we do not merge — that call is yours).

Process: Plan and dev-approval were human-gated pre-PR. The dev-approval gate included a full-path live demo through a locally installed build — a real afx spawn of a Kimi builder through Tower showing (1) seed-session bootstrap with session-id capture, (2) sentinel-gated, store-verified BEGIN delivery, (3) multiline afx send at the pinned Enter delay, and (4) inner-restart context retention via kimi -S — plus codev doctor's new kimi checks.

Consultation (CMAP, single advisory pass): gemini APPROVE, claude APPROVE, codex REQUEST_CHANGES. The codex finding was real and was accepted + fixed in 732f04b: seed-kick delivery confirmation was a substring match on lastPrompt, and the fresh-spawn seed prompt itself contains "BEGIN", so verification false-positived before the kick submitted — defeating the swallowed-Enter recovery. Fix is whitespace-normalized equality, with two pinning regression tests (both fail pre-fix), seed-kick suite 14/14, and a post-fix live demo re-run (5/5).

Architect verification of the post-CMAP fix (since PIR's single-pass consultation does not re-review fixes): I reviewed confirmed() in seed-kick.ts and the pinning tests directly — the equality predicate is correct, preserves the multiline-payload fallback (kimi flattens submitted newlines; normalization covers it), and the retry ladder (Enter re-send → one re-kick → loud warn) is intact. Known benign edge: a message raced into the session during the ~10s verify window causes one bounded re-kick, then a warning.

Scope: verified against issue #1201's builder-MVI checklist — no architect-parity changes (tower-utils/tower-instances/tower-terminals/session-manager/architect.ts untouched), no ACP adapter; kimi-as-architect fails loudly. Undocumented Kimi surfaces are labeled as observed, pinned to kimi >= 0.27.0 with a doctor smoke probe.


Architect integration review

mohidmakhdoomi and others added 2 commits July 18, 2026 20:55
… for maintainers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cepted+fixed)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Kimi Code CLI as a builder

1 participant