Skip to content

fix(cli): run's cache key includes the compiler's version - #121

Merged
codetalcott merged 1 commit into
mainfrom
claude/stoic-volta-z29i0t
Sep 26, 2026
Merged

codetalcott merged 1 commit into
mainfrom
claude/stoic-volta-z29i0t

Conversation

@codetalcott

Copy link
Copy Markdown
Owner

Closes the gap CLAUDE.md recorded in #120: napi-mojo run kept its cached binary across a toolchain upgrade.

What was wrong

The cache key held the compiler command (pixi run mojo), and a pixi.lock or MAX bump leaves the command unchanged. After an upgrade, the next run therefore:

  • skipped the compile, so the new compiler never saw the code;
  • loaded the old binary against the new runtime. The binary finds libKGENCompilerRTShared through its RUNPATH, the pixi environment's lib/, and pixi upgrades that directory in place. Checked with readelf -d on a built host.node.

The fix

  • The key now includes what <command> --version prints, e.g. Mojo 1.1.0 (8189361e). The build hash is part of that output, so moving from one nightly to the next also triggers a rebuild.
  • If the compiler runs but reports no version, the cache is off for that run, with a warning, rather than keying on nothing.
  • If the compiler can't run at all, there's no warning, because the compile itself then fails with the usual advice.

Cost is one probe per run. Measured locally, cached runs went from 155–192 ms to 212–252 ms: about 55 ms through pixi run, 17 ms calling the binary directly.

Tests

  • Two new stub-compiler tests in tests/cli.test.js; the stub now answers --version from a file:
    • a changed version recompiles;
    • a compiler that can't report its version is never served from the cache.
  • Each of the three new rules was reverted once and its test failed.
  • Real toolchain, with a --mojo wrapper that changes only the reported version:
    • unchanged version: 212 ms, binary untouched;
    • changed version: 2.2 s, binary rewritten.
  • The CI "Host-mode program with library include roots" step passes locally with the probe in place.
  • npm test: 837 passed, 12 skipped. check-doc-samples, generate-rules-extract --check and sync-versions --check pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_013tXV7MkRfP97g5hPfNNXHC


Generated by Claude Code

The key held the compiler COMMAND, which a pixi.lock or MAX bump leaves
unchanged, so after a toolchain upgrade `napi-mojo run` kept its cached
binary: the new compiler never saw the code, and the old binary loaded the
new runtime, since it finds libKGENCompilerRTShared through its RUNPATH
(the environment's lib/) and pixi upgrades that directory in place.

The key now includes what `<command> --version` prints, e.g.
"Mojo 1.1.0 (8189361e)", build hash included, so one nightly to the next
counts as a change. One probe per run, measured here: cached runs went
from 155-192 ms to 212-252 ms (~55 ms through `pixi run`, ~17 ms calling
the binary directly). A compiler that runs but reports no version turns
the cache off for that run, with a warning, rather than keying on
nothing; one that cannot run at all stays silent, because the compile
then fails with the full advice.

Two stub-compiler tests (the stub now answers --version from a file):
a changed version recompiles, and a compiler that cannot report one is
never served from the cache. Each of the three rules was reverted once
and caught. With the real toolchain and a wrapper that only changes the
reported version: unchanged, 212 ms and the binary untouched; changed,
2.2 s and rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013tXV7MkRfP97g5hPfNNXHC
@codetalcott
codetalcott marked this pull request as ready for review September 26, 2026 16:27
@codetalcott
codetalcott merged commit 0f3b873 into main Sep 26, 2026
11 checks passed
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.

2 participants