Skip to content

fix(kimi): install Kimi turn-end hook without stdlib tomllib - #15

Merged
Aviator-Coding merged 1 commit into
mainfrom
fm/fm-kimi-harness-test-red
Aug 15, 2026
Merged

Aviator-Coding merged 1 commit into
mainfrom
fm/fm-kimi-harness-test-red

Conversation

@Aviator-Coding

Copy link
Copy Markdown
Owner

Intent

fm-kimi-harness test 'Kimi hook install refused a realistic config' fails on base. This is a pre-existing base-branch failure, not caused by a recent change. Reproduce that exact test first and capture the real failure. The title names a realistic-config hook-install refusal; find out whether Kimi's actual behaviour changed, the test's fixture is stale, or the assertion was always wrong. If Kimi's own behaviour moved, verify against the currently installed Kimi rather than assuming the test is right. Reproduce the defect in the way an operator hits it before writing the fix. That reproduction is the regression test: it must FAIL before the change and PASS after. If it passes before, stop rather than shipping a fix that proves nothing. Verify against the real tool where possible, not only a hand-written fixture, and record what was verified against.

Accepted findings from reproduction: the named test failed because stock macOS /usr/bin/python3 is 3.9.6 and has no stdlib tomllib, so fm-kimi-turnend-hook.sh install refused before parsing. The realistic fixture is valid TOML (parses on CPython 3.12.13; install succeeds when that interpreter is python3). Installed kimi 1.49.0 is Moonshot kimi-cli (default ~/.kimi/config.toml) and is not the kimi-code ~/.kimi-code/config.toml surface this installer edits, so Kimi's own hook schema was not the refusal cause. The accepted fix is: keep validating without serializing captain TOML; use stdlib tomllib when present and otherwise the bundled tomli 2.2.1 reader in bin/fm_toml so stock python3 3.9 can install. Do not skip the test, and do not change the realistic fixture to paper over the refusal.

What Changed

  • bin/fm-kimi-turnend-hook.sh now falls back to a bundled pure-Python TOML reader (bin/fm_toml) for config validation when the active python3 lacks stdlib tomllib, instead of refusing to install; it resolves the hook's own directory and adds it to sys.path for the fallback import.
  • Adds bin/fm_toml (__init__.py, _parser.py, _re.py, _types.py), a vendored TOML parser used only for validation - the installer still never serializes the captain's TOML.
  • Updates docs/configuration.md and docs/turnend-guard.md to describe the tomllib-or-fm_toml validation path, and updates tests/fm-kimi-harness.test.sh (including a new test_kimi_hook_install_works_without_stdlib_tomllib case) to cover installing with stdlib tomllib hidden.

Risk Assessment

✅ Low: The change is a well-scoped fallback-import fix (stdlib tomllib -> vendored fm_toml/tomli 2.2.1) with a HOOK_DIR resolved via the script's own invocation path (always invoked as $FM_ROOT/bin/fm-kimi-turnend-hook.sh, never symlinked), a deterministic regression test that hides tomllib via PYTHONPATH shadowing to reproduce the failure independent of the CI interpreter's version, no changes to the realistic fixture or any skipped tests, and no unsafe code in the vendored parser.

Testing

Reproduced the named test's exact pre-existing base-branch failure in this environment (real stock python3 3.9.6, no tomllib), confirmed it fails on base and passes on target both via the automated test suite and via manual operator-level install runs against the realistic fixture, and cross-checked against the actually installed Kimi CLI to confirm the refusal was a TOML-parsing gap rather than a Kimi behavior change; all evidence supports the accepted fix and no issues were found.

Evidence: Base commit (f991512) reproduction: test fails with stock python3.9, no tomllib
=== base commit f991512 (before fix) ===
$ python3 --version
Python 3.9.6
$ bash tests/fm-kimi-harness.test.sh
fm-kimi-turnend-hook: refused: python3 with tomllib is required to validate config.toml.
not ok - Kimi hook install refused a realistic config
Evidence: Target commit (45cfa0d) full kimi-harness suite passing with same stock python3.9
=== target commit 45cfa0d (after fix) ===
$ python3 --version
Python 3.9.6
$ bash tests/fm-kimi-harness.test.sh
ok - Kimi hook install is idempotent and removal restores every foreign config byte
ok - Kimi hook removal preserves owned newline boundaries and pristine bytes
ok - Kimi hook install refuses missing, malformed, and surprising config without writing
ok - Kimi hook install validates TOML without stdlib tomllib
ok - Kimi hook install refuses without jq before any config write
ok - fm-spawn: kimi launches, delivers its brief, and registers a guarded turn-end token
ok - Kimi hook stays silent and inert without a Firstmate registry token
ok - fm-spawn: unsafe Kimi global config refuses before pane creation
ok - fm-teardown: Kimi task pointer and registry token are removed
ok - fm-spawn: Kimi fallback expands the active HOME
ok - fm-spawn: missing Kimi executable refuses before pane creation
ok - fm-spawn: kimi treats a silent pointer drop as a failed spawn
ok - fm-spawn: kimi never sends the brief pointer before an observable ready signal
ok - fm-harness: markerless kimi is detected by ancestry after env-marker precedence
lock acquired: harness pid 54330
ok - fm-lock recognizes Kimi ancestry and live lock holders
ok - busy detection: real Kimi moon-plus-middot captures require its harness while idle labels stay idle
ok - fm-watch classifies Kimi as unknown rather than from its spinner, and Grok's fallback stays isolated
ok - composer classifier: kimi's existing bordered > shape is already safe without an override
Evidence: Manual operator repro on base: install refused with realistic config + stock python3
=== manual operator repro: base commit, realistic config, stock python3.9 ===
fm-kimi-turnend-hook: refused: python3 with tomllib is required to validate config.toml.
exit=1
Evidence: Manual operator repro on target: install succeeds, shows resulting config.toml with Firstmate hook region installed and captain bytes preserved
=== manual operator repro: target commit, realistic config, stock python3.9 ===
exit=0

--- resulting config.toml (Firstmate region installed) ---
# Captain's leading comment stays exactly here.

[ui]
theme = "night" # inline comment
show_usage = true

# Foreign hook with intentionally unusual key ordering.
[[hooks]]
timeout=17
command = "printf foreign"
matcher=""
event = "Stop"

[providers.example]
model = "some/model"
# Final comment and blank line follow.

# BEGIN FIRSTMATE KIMI TURN-END HOOK
[[hooks]]
event = "Stop"
matcher = "^$"
command = "bash \"$HOME/.kimi-code/fm-turn-end.sh\" >/dev/null 2>&1 || true"
timeout = 1
# END FIRSTMATE KIMI TURN-END HOOK

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • bash tests/fm-kimi-harness.test.sh (base commit f991512d865f73f10c78bb934f166f83aa27b1f7, isolated worktree) — reproduced failure: 'not ok - Kimi hook install refused a realistic config'
  • bash tests/fm-kimi-harness.test.sh (target commit 45cfa0d7f2e4d774503a8e4325b6521075f852b0, this worktree) — full suite passes, including new test_kimi_hook_install_works_without_stdlib_tomllib
  • Manual: HOME=<tmp> bin/fm-kimi-turnend-hook.sh install against the realistic fixture config with stock /usr/bin/python3 3.9.6 on base commit — refused, no config write
  • Manual: HOME=<tmp> bin/fm-kimi-turnend-hook.sh install against the same fixture with the same stock python3 on target commit — succeeded, wrote guarded Firstmate hook region, captain config bytes untouched
  • which -a python3 / python3 --version / python3 -c 'import tomllib' — confirmed environment's python3 is stock 3.9.6 without tomllib, matching the intent's accepted findings
  • kimi --version / ls ~/.kimi ~/.kimi-code — confirmed installed Kimi is Moonshot kimi-cli 1.49.0 using ~/.kimi, distinct from the ~/.kimi-code surface this installer edits
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Stock macOS python3 3.9 lacks stdlib tomllib, so hook install
refused a valid config.toml. Prefer tomllib and fall back to a
bundled tomli 2.2.1 reader so the installer can still validate
without serializing captain config.
@Aviator-Coding
Aviator-Coding merged commit 00ef0b6 into main Aug 15, 2026
13 checks passed
@Aviator-Coding
Aviator-Coding deleted the fm/fm-kimi-harness-test-red branch August 15, 2026 18:36
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.

1 participant