Skip to content

refactor(gate): split mise.lock completeness from currency - #99

Merged
wenzowski merged 1 commit into
mainfrom
claude/linear-connector-approval-loop-yobwnc
Aug 7, 2026
Merged

wenzowski merged 1 commit into
mainfrom
claude/linear-connector-approval-loop-yobwnc

Conversation

@wenzowski

Copy link
Copy Markdown
Contributor

lock-check ran mise lock — a remote round trip per tool — and rewrote the tracked lockfile, then diffed it. It was a gate whose verdict came from a remote API with a write side effect, and it did not test what it was named for.

What it was actually testing

Whether upstream changed since the last commit. Not completeness. Three things establish that, each verified rather than reasoned about:

  1. Its premise was false. The comment and error string both assert "CI installs with mise install --locked". --locked appears nowhere in .github/workflows/ — only inside lock-check's own prose. Every job installs live via install_args.

  2. It could not detect incompleteness. Regenerate-and-diff sees drift only: mise lock never removes or repairs an existing entry, so a stably wrong lockfile passes forever. Verified by deleting a block and re-locking — it stayed deleted.

  3. A partial entry was in the file and passing. ubi:rust-cross/cargo-zigbuild carried one platform key, linux-x64-cargo-zigbuild, with a checksum and no url — precisely the "mise install writes only a partial entry" defect its own comment cites as motivation. mise run lock-check printed complete and current over it on every run.

And the side effects it paid for that: a network dependency on the landing path (observed timing out for 30s and retrying mid-verify), and a write to a tracked file that a git add -A can sweep into an unrelated commit. tests/context-budget.bats already carries the rule this breaks — "A test may not mutate tracked working state" — written after a test ate an in-progress edit.

The split

Sorted by which question is a property of the commit:

lock-complete (new) Pure function of the committed bytes. No network, no write. Wired into the shared hk gate, globbed on mise.lock/mise.toml.
lock-check (kept) Currency only. Off the landing path — removed from verify's depends, moved to a weekly lock-currency.yml.

lock-complete's predicates:

  • unknown-platform-key — a platform key outside the set mise emits, i.e. install-time residue rather than a lock. This is what catches the cargo-zigbuild entry, which this PR removes.
  • required-not-installable — a required platform with no block, or a block with no url. Required defaults to linux-x64 linux-arm64 macos-arm64 (CI runners, agent sandboxes, contributor machines), overridable via BATTEN_LOCK_PLATFORMS.

A tool with no platform block at all is exempt, not a failure — the npm, pipx and core:rust backends lock no URLs, so partiality is not meaningful for them.

A near-miss worth recording

The first version failed on every url-less platform block, which flagged zizmor's two musl entries. Applying the same delete-and-re-lock test showed mise lock regenerates those — they are how mise records "upstream ships no artifact here." Failing on them would have failed this repo for a decision upstream made, which is the identical defect one level down.

The url check is therefore scoped to required platforms, and that case is a test rather than a comment.

Verification

mise run verify green on 3bee7d2. 163 bats cases, 11 of them new. actionlint and zizmor clean on the new workflow.

Also worth noting: this branch's previous verify run exercised the fail-closed fix from #97 for real — main moved mid-run, linear-check failed, and verify stopped without writing a receipt where it would previously have printed fast-forward-green.


Generated by Claude Code

lock-check ran `mise lock` — a remote round trip per tool — and rewrote the
tracked lockfile, then diffed it. Three things follow, and none of them is what
the gate was named for:

Its verdict was a property of the world, not of the commit: an upstream release
failed whichever branch was in flight, and the rewrite stayed in the working
tree for the next `git add -A` to sweep into an unrelated commit.

It could not detect incompleteness at all. Regenerate-and-diff sees drift only —
`mise lock` never removes or repairs an existing entry, so a stably wrong
lockfile passes forever. One did: `ubi:rust-cross/cargo-zigbuild` carried a
single platform key `linux-x64-cargo-zigbuild` with a checksum and no url, the
exact partial entry lock-check's own comment cited as its motivation, and
lock-check reported "complete and current" over it on every run. Verified
residue rather than mise output: deleted, `mise lock` does not restore it.

Its premise was false. "CI installs with `mise install --locked`" appears only
in lock-check's own comment and error text; no workflow passes --locked.

Split: `lock-complete` is a pure gate over the committed bytes (no network, no
write) wired into hk, and lock-check keeps currency alone, off the landing path
on a weekly schedule. Removes the cargo-zigbuild residue.

The url check is scoped to required platforms on purpose. mise emits a
provenance-only stub where upstream ships no artifact — zizmor's musl entries —
and regenerates them, so failing on every url-less block would fail this repo
for a decision upstream made: the same defect one level down. Covered by a test.

11 bats cases.
@wenzowski
wenzowski marked this pull request as ready for review August 7, 2026 15:53
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit 3bee7d2 into main Aug 7, 2026
11 checks passed
@wenzowski
wenzowski deleted the claude/linear-connector-approval-loop-yobwnc branch August 7, 2026 15:55
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