## Problem
The default cache key was `mise-v1-{os}-{arch}-{file_hash}` — no
runner-image discriminator. Any repo whose CI runs on multiple runner
providers with the same os/arch shares one cache slot:
- github-hosted `macos-latest`
- namespace.so `nscloud-macos-sequoia-arm64-*` /
`namespace-profile-*-macos-arm64`
- self-hosted M-series macs
- BuildJet, blacksmith, etc.
When a repo migrates from one provider to another, the new run restores
the previous provider's tool installs (~200 MB of
`~/.local/share/mise/installs/*`), and tools that loaded fine in the
original image break in the new one.
### Concrete failures observed
Discovered while migrating [jdx/hk](https://github.com/jdx/hk/pull/891)
from github-hosted to namespace.so. Same `mise-v1-macos-arm64-<hash>`
cache hit on namespace; tool resolution fails everywhere:
```
mise ERROR Tool 'ubi:koalaman/shellcheck' does not have an executable named 'shellcheck'
mise ERROR Tool 'gem:asciidoctor' does not have an executable named 'asciidoctor'
mise ERROR Tool 'aqua:betterleaks/betterleaks' does not have an executable named 'betterleaks'
mise ERROR Tool 'biome' does not have an executable named 'biome'
mise ERROR Tool 'buf' does not have an executable named 'buf'
mise ERROR Tool 'github:google/google-java-format' does not have an executable named 'google-java-format'
```
— installs are present (cache restored 185 MB) but the executable layout
from the github-hosted macOS-15 image doesn't match what mise expects on
namespace's macOS arm64 image.
On Linux, cached binaries built against the github-hosted ubuntu
glibc/CPU featureset SIGILL on namespace's image (e.g. `swiftlint` exit
code 132).
## Fix
Append the GitHub Actions hosted-runner `ImageOS` env var (e.g.
`macos15`, `ubuntu24`) to the platform segment of the default cache key.
Other runners pool under `self-hosted`.
```ts
const imageOS = process.env.ImageOS || 'self-hosted'
return `${base}-${imageOS}`
```
After this change:
- `mise-v1-macos-arm64-macos15-<hash>` (github-hosted)
- `mise-v1-macos-arm64-self-hosted-<hash>` (namespace, self-hosted,
etc.)
Users with multiple self-hosted profiles that need finer scoping can set
`cache_key_prefix` per workflow. The README's docs for `{{platform}}`
are updated to reflect the new format.
## Trade-offs
- One-time cache miss for everyone on the next run after upgrade. Cache
rebuilds and stays scoped per-image after that.
- Hosted-runner image rolls (e.g. `macos15` → `macos16`) will invalidate
cache, which is desirable — that's exactly when stale binaries cause
problems.
- Self-hosted users with mixed runner pools all share one `self-hosted`
slot. They'd need `cache_key_prefix` per pool, same as before. This PR
doesn't make that worse.
## Test plan
- [ ] Verify `dist/index.js` rebuilt cleanly (yes, `npm run package`
succeeded with the change visible at `getTarget()` callsite).
- [ ] Run on a github-hosted runner — confirm `ImageOS` is read from env
(e.g. `macos15`) and shows up in the `mise cache restored from key:` log
line.
- [ ] Run on a non-hosted runner — confirm fallback to `-self-hosted`.
- [ ] Verify a workflow that switched providers no longer pulls a
poisoned cache.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes cache-key generation and will cause a one-time cache miss plus
different cache partitioning, which can affect build times and cache
reuse across runners.
>
> **Overview**
> Updates the default cache-key `{{platform}}` value to append a runner
image discriminator (`process.env.ImageOS` on GitHub-hosted runners,
otherwise `self-hosted`), reducing cross-provider/image cache collisions
that can restore incompatible tool installs.
>
> Implements this via a new `getRunnerImageId()` helper used during
cache-key template processing, and documents the new `{{platform}}`
format in the README; `dist/index.js` is rebuilt accordingly.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ef1bd0e351. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->