Skip to content

Nothing reports on or pins the mise version itself, so the tool that verifies every other pin drifts while everything it verifies stays current #129

Description

@jakewan

Context

Surfaced during the pre-PR audit of #130, the toolchain-pin refresh that moved the Go pin from 1.26.5 to 1.27.0. That change moved all four pins the currency report named; the audit found that the one pin no report can name went unexamined at the exact moment a maintainer was reviewing pins.

Problem

mise is the component that verifies every other tool: jdx/mise-action runs mise install --locked, checking each downloaded tool against the checksums recorded in mise.lock. Its own version is the one part of the toolchain the repository does not govern, in two independent ways.

In CI it is pinned by hand and covered by nothing. Dependabot's github-actions ecosystem updates the jdx/mise-action@v4 tag but never reads an action's version: input. mise outdated reads mise.toml, where mise does not appear — so the Toolchain currency workflow's own coverage guard, which compares mise ls --local against mise outdated --bump --local, has mise in neither its numerator nor its denominator. The guard is sound; mise is simply outside the set it can reason about.

Locally it is not pinned at all. mise.toml has no mise entry, so whichever mise a contributor happens to have installed is the one that writes mise.lock — the file CI then verifies against.

.claude/rules/toolchain-ci-parity.md records the first of these accurately and assigns it a manual review posture, which SECURITY.md repeats. The gap is that the posture has no trigger. The occasion on which anyone reviews toolchain pins is a currency-report-driven refresh, and that report is structurally incapable of naming mise. So "it moves only when a human moves it" degenerates in practice to "it does not move" — the verifier ages indefinitely while everything it verifies is kept current by the very process that cannot see it.

The second half is recorded nowhere, and is the sharper of the two: the writer of mise.lock and its verifier are different, mutually unconstrained versions of the same tool. A lockfile-format change between them is a CI failure with no local reproduction — or, worse, a silent difference in what "verified" means on each side.

Evidence

Suggested approaches

Options, not a prescription:

  1. Bring mise inside the report it currently sits outside — a mise entry in mise.toml would put it in mise outdated --bump --local and in the coverage guard's count. Whether a mise-managed mise is the right way to run it in CI is the open part.
  2. Give the manual posture a trigger instead — make the mise pin an explicit item of any pin-refresh change, so the occasion that already exists carries it rather than a new mechanism.
  3. Constrain the writer as well as the verifier — pin a local mise, or assert at mise lock time that the writing version matches the CI pin, so the lockfile is produced and checked by the same version.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildBuild, CI, and release tooling (e.g. goreleaser, release workflows).securityCross-cutting security / supply-chain concern

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions