Skip to content

Commit f7b0031

Browse files
auxesisclaude
andcommitted
build(mise): move the cargo tools into mise.test.toml, pinned
mise merges config down the directory tree, so every tool in the root mise.toml is also part of the toolset in packages/eql and in languages/typescript/packages/protect-ffi. Their CI jobs run `mise install` (and `mise run`) in those folders, so each one now built cargo-nextest, cargo-llvm-cov, cargo-crap, cargo-mutants, cargo-fuzz and cargo-udeps from source, none of which they use. mise's cargo backend compiles a `cargo:` tool with the runner's default rustc (1.92 on the Ubuntu images), not the root's pinned 1.94.1. So a `latest` that raises its minimum Rust fails the install: cargo-udeps 0.1.61 needs cargo@0.96, which needs rustc 1.93. That broke the protect-ffi integration suite on #1001 and the new udeps job on #1003. The cargo tools move to mise.test.toml, which mise loads only for the `test` environment (`mise x --env test`, or MISE_ENV=test). Nested workspaces no longer inherit them. Each is pinned to an exact version that builds on the runners' rustc; cargo-udeps goes back to 0.1.60. The tasks that call them (crap:*, mutants:*, fuzz:*, and nextest in wasm:guest:test and wasm:auth-guest:test) now run them through `mise x --env test --`, as test:doc and the crap coverage step already did, so `mise run <task>` keeps working locally without MISE_ENV. Rust, Go, golangci-lint and wasm-pack stay in the root mise.toml. They are prebuilt downloads, and plan section 3.5 has protect-ffi inherit the Rust pin. That section's intent holds: the repository pins one version of each cargo tool, reached through mise. The pins now sit in the test environment rather than the default one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
1 parent 1c52c8f commit f7b0031

7 files changed

Lines changed: 58 additions & 36 deletions

File tree

‎AGENTS.md‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,14 @@ The stack-* crates came from `cipherstash/cipherstash-suite`, which still owns
632632
three fuzz crates and the two Go guests are detached workspaces too, each
633633
with its own `Cargo.lock`.
634634
- **The toolchain is pinned in the root `mise.toml`:** Rust 1.94.1 (the
635-
`stack-encrypt` `tests/ui` trybuild snapshots record its diagnostics), the
636-
cargo tools, and Go 1.26. EQL's `mise.toml` overrides the Rust pin in its
637-
folder. protect-ffi's does not pin Rust, so the root pin applies there.
635+
`stack-encrypt` `tests/ui` trybuild snapshots record its diagnostics) and
636+
Go 1.26. EQL's `mise.toml` overrides the Rust pin in its folder.
637+
protect-ffi's does not pin Rust, so the root pin applies there.
638+
- **The cargo tools are pinned in `mise.test.toml`, not `mise.toml`:**
639+
nextest, llvm-cov, crap, mutants, fuzz and udeps. EQL and protect-ffi
640+
inherit the root `mise.toml`, so a cargo tool there would be built in their
641+
jobs too. Reach them with `mise x --env test -- …`, as the tasks do; CI jobs
642+
that use them set `MISE_ENV: test`.
638643
- **Run the tests with nextest, under the test env:** `mise x --env test --
639644
cargo nextest run --workspace --all-features`. Doc examples are `mise run
640645
test:doc`; rustdoc with warnings as errors is `mise run doc`.

‎docs/fuzzing.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ the scheduled campaign grows the corpus from there.
7575
## Running locally
7676

7777
cargo-fuzz needs the **nightly** toolchain and the `cargo-fuzz` binary;
78-
`mise` provides the latter (`cargo:cargo-fuzz` in `mise.toml`). Install
78+
`mise` provides the latter (`cargo:cargo-fuzz` in `mise.test.toml`,
79+
which the `fuzz:*` tasks load with `mise x --env test`). Install
7980
nightly once with `rustup toolchain install nightly`.
8081

8182
Run a target via its `mise` task (60s by default):

‎mise.test.toml‎

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
1-
# The `test` environment, for `mise x --env test -- …` in the root and
2-
# stack-* tasks (test:doc, crap:*). Carried from cipherstash-suite, keeping
3-
# only what the stack crates read; the suite's CTS, ZeroKMS and database
4-
# settings serve services this repository does not run.
1+
# The `test` environment: `mise x --env test -- …` in the root and stack-*
2+
# tasks, and MISE_ENV=test in the CI jobs that run them. Carried from
3+
# cipherstash-suite, keeping only what the stack crates read; the suite's CTS,
4+
# ZeroKMS and database settings serve services this repository does not run.
5+
#
6+
# The cargo tools live here rather than in mise.toml so that packages/eql and
7+
# protect-ffi, which inherit the root mise.toml, do not install them (see the
8+
# note in mise.toml). Each is pinned: mise compiles a `cargo:` tool with the
9+
# runner's default rustc, not the root's 1.94.1, so a `latest` that raises its
10+
# minimum Rust fails the install. cargo-udeps 0.1.61 did exactly that
11+
# (cargo@0.96 needs rustc 1.93; the Ubuntu runners ship 1.92). Bump a pin
12+
# deliberately, after checking it still builds with the runners' rustc.
513
[tools]
6-
"cargo:cargo-nextest" = "latest"
14+
"cargo:cargo-nextest" = "0.9.146"
15+
# Coverage → CRAP (Change Risk Anti-Patterns) metric tooling. `cargo llvm-cov`
16+
# produces an LCOV file that `cargo crap` scores; see `mise run crap:stack-auth`.
17+
# cargo-llvm-cov needs the root rust's `llvm-tools-preview` component.
18+
"cargo:cargo-llvm-cov" = "0.9.1"
19+
"cargo:cargo-crap" = "0.6.1"
20+
# Mutation testing for the stack crates; config in .cargo/mutants.toml, run
21+
# via `mutants:<crate>`.
22+
"cargo:cargo-mutants" = "27.1.0"
23+
# Fuzzing (libFuzzer) for the pure-`&str` parsers. The `cargo-fuzz` binary
24+
# installs on stable, but running a target needs the nightly toolchain
25+
# (`cargo +nightly fuzz run …`); see the `fuzz:*` tasks.
26+
"cargo:cargo-fuzz" = "0.13.2"
27+
# Runs on nightly-2026-07-10: `cargo +nightly-2026-07-10 udeps`. 0.1.60, not
28+
# 0.1.61: see above.
29+
"cargo:cargo-udeps" = "0.1.60"
730

831
[env]
932
# Annoyingly if you pass --env test to mise it doesn't set this automatically

‎mise.toml‎

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,13 @@ includes = [
2020
# this compiler's diagnostics. `llvm-tools-preview` is required by
2121
# cargo-llvm-cov to produce coverage data.
2222
rust = { version = "1.94.1", components = "rustc,cargo,rustfmt,rust-std,clippy,rust-docs,llvm-tools-preview", targets = "wasm32-unknown-unknown,wasm32-wasip1" }
23-
"cargo:cargo-nextest" = "latest"
24-
# Coverage → CRAP (Change Risk Anti-Patterns) metric tooling. `cargo llvm-cov`
25-
# produces an LCOV file that `cargo crap` scores; see `mise run crap:stack-auth`.
26-
"cargo:cargo-llvm-cov" = "latest"
27-
"cargo:cargo-crap" = "latest"
28-
# Mutation testing for the stack crates; config in .cargo/mutants.toml, run
29-
# via `mutants:<crate>`.
30-
"cargo:cargo-mutants" = "latest"
31-
# Fuzzing (libFuzzer) for the pure-`&str` parsers. The `cargo-fuzz` binary
32-
# installs on stable, but running a target needs the nightly toolchain
33-
# (`cargo +nightly fuzz run …`); see the `fuzz:*` tasks.
34-
"cargo:cargo-fuzz" = "latest"
35-
# Runs on nightly-2026-07-10: `cargo +nightly-2026-07-10 udeps`.
36-
"cargo:cargo-udeps" = "latest"
23+
# No `cargo:` tools here. mise merges config down the tree, so every tool in
24+
# this file is also installed for packages/eql and protect-ffi, whose CI runs
25+
# `mise install` and `mise run` in their own folders. mise compiles a `cargo:`
26+
# tool with the runner's default rustc rather than the pinned one, so one
27+
# `latest` that outgrows that compiler breaks jobs that never use the tool.
28+
# The cargo tools (nextest, llvm-cov, crap, mutants, fuzz, udeps) live in
29+
# mise.test.toml, pinned, and load only with `--env test` / MISE_ENV=test.
3730
# The Go module (languages/golang) — the wazero host of the WASI guests.
3831
# CGO_ENABLED=0 throughout; see `go:test`.
3932
go = "1.26"
@@ -211,8 +204,8 @@ cargo clippy --target wasm32-wasip1 -- -D warnings
211204
# and exits 0, so without -D warnings a stale link ships silently.
212205
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --target wasm32-wasip1
213206
# nextest, as everywhere else; this crate is a detached workspace, so it
214-
# runs from here rather than a root `-p`.
215-
cargo nextest run
207+
# runs from here rather than a root `-p`. nextest is in mise.test.toml.
208+
mise x --env test -- cargo nextest run
216209
"""
217210

218211
[tasks."wasm:auth-guest:build"]
@@ -255,7 +248,7 @@ cargo fmt --check
255248
cargo clippy --all-targets -- -D warnings
256249
cargo clippy --target wasm32-wasip1 -- -D warnings
257250
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --target wasm32-wasip1
258-
cargo nextest run
251+
mise x --env test -- cargo nextest run
259252
"""
260253

261254
[tasks."go:test"]

‎packages/stack-auth/tasks.toml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ run = [
3737
# NOTE: this must stay the LAST command — the crap-stack-auth.yml CI workflow runs
3838
# this task and relies on mise appending its trailing args (e.g. --format github)
3939
# to this `cargo crap` invocation.
40-
"cargo crap --path packages/stack-auth --lcov {{config_root}}/target/stack-auth-lcov.info --exclude 'node/**' --exclude 'wasm/**' --exclude 'examples/**' --exclude '**/tests.rs' --exclude '**/tests/**' --fail-above",
40+
"mise x --env test -- cargo crap --path packages/stack-auth --lcov {{config_root}}/target/stack-auth-lcov.info --exclude 'node/**' --exclude 'wasm/**' --exclude 'examples/**' --exclude '**/tests.rs' --exclude '**/tests/**' --fail-above",
4141
]
4242

4343
# Fuzz stack-auth's public AccessKey string parser (libFuzzer via cargo-fuzz).
@@ -51,15 +51,15 @@ run = [
5151
["fuzz:access-key"]
5252
description = "Fuzz stack-auth's AccessKey string parser (libFuzzer, nightly, 60s default)"
5353
dir = "{{config_root}}/packages/stack-auth"
54-
run = "cargo +nightly fuzz run access_key_parse --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
54+
run = "mise x --env test -- cargo +nightly fuzz run access_key_parse --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
5555

5656
# Fuzz the JWT claims decode path (Token::fuzz_decode_claims, behind the `fuzz`
5757
# feature). On native this is the jsonwebtoken-based decode with signature
5858
# validation disabled. Same flags/rationale as fuzz:access-key.
5959
["fuzz:jwt-decode"]
6060
description = "Fuzz stack-auth's JWT claims decode path (libFuzzer, nightly, 60s default)"
6161
dir = "{{config_root}}/packages/stack-auth"
62-
run = "cargo +nightly fuzz run jwt_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
62+
run = "mise x --env test -- cargo +nightly fuzz run jwt_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
6363

6464
# Mutation testing (cargo-mutants) over the whole crate: what the per-PR
6565
# `--in-diff` gate (.github/workflows/mutants.yml) does for changed lines only.
@@ -68,4 +68,4 @@ run = "cargo +nightly fuzz run jwt_decode --sanitizer none --target $(rustc -vV
6868
# stress tests are filtered out of the per-mutant run by the shared config.
6969
["mutants:stack-auth"]
7070
description = "Full mutation-testing sweep of stack-auth (cargo-mutants; ~15 min)"
71-
run = "cargo mutants -p stack-auth --jobs 4"
71+
run = "mise x --env test -- cargo mutants -p stack-auth --jobs 4"

‎packages/stack-encrypt/tasks.toml‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ run = [
1616
# NOTE: this must stay the LAST command — the crap-stack-encrypt.yml CI
1717
# workflow runs this task and relies on mise appending its trailing args
1818
# (e.g. --format github) to this `cargo crap` invocation.
19-
"cargo crap --path packages/stack-encrypt --lcov {{config_root}}/target/stack-encrypt-lcov.info --exclude 'examples/**' --exclude 'fuzz/**' --exclude '**/tests/**' --fail-above",
19+
"mise x --env test -- cargo crap --path packages/stack-encrypt --lcov {{config_root}}/target/stack-encrypt-lcov.info --exclude 'examples/**' --exclude 'fuzz/**' --exclude '**/tests/**' --fail-above",
2020
]
2121

2222
# Fuzz the frozen v1 leaf byte decoder (`SealedValue::from_bytes`, also
@@ -30,7 +30,7 @@ run = [
3030
["fuzz:sealed-value"]
3131
description = "Fuzz stack-encrypt's frozen leaf byte decoder, SealedValue::from_bytes (libFuzzer, nightly, 60s default)"
3232
dir = "{{config_root}}/packages/stack-encrypt"
33-
run = "cargo +nightly fuzz run sealed_value_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
33+
run = "mise x --env test -- cargo +nightly fuzz run sealed_value_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
3434

3535
# Fuzz the SEM index-term byte decoders — every `from_bytes` / `TryFrom<&[u8]>`
3636
# a stored term comes back through (equality, match, ORE and OPE). One target
@@ -39,7 +39,7 @@ run = "cargo +nightly fuzz run sealed_value_decode --sanitizer none --target $(r
3939
["fuzz:term-decode"]
4040
description = "Fuzz stack-encrypt's SEM index-term byte decoders (libFuzzer, nightly, 60s default)"
4141
dir = "{{config_root}}/packages/stack-encrypt"
42-
run = "cargo +nightly fuzz run term_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
42+
run = "mise x --env test -- cargo +nightly fuzz run term_decode --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
4343

4444
# Fuzz the stored-record preflight (`dynamic::record::check_record`) with
4545
# structure-aware inputs: an `Arbitrary`-derived mirror of a plan value and
@@ -49,7 +49,7 @@ run = "cargo +nightly fuzz run term_decode --sanitizer none --target $(rustc -vV
4949
["fuzz:check-record"]
5050
description = "Fuzz stack-encrypt's stored-record preflight against a model of its rules (structure-aware, libFuzzer, nightly, 60s default)"
5151
dir = "{{config_root}}/packages/stack-encrypt"
52-
run = "cargo +nightly fuzz run check_record --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
52+
run = "mise x --env test -- cargo +nightly fuzz run check_record --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
5353

5454
# Rustdoc with warnings as errors: a broken intra-doc link or a rustdoc
5555
# warning fails the build. Doc *examples* are `test:doc:stack-encrypt`. Both run
@@ -71,4 +71,4 @@ run = "mise x --env test -- cargo test -p stack-encrypt --doc --all-features"
7171
# trybuild UI suite is filtered out of the per-mutant run by the shared config.
7272
["mutants:stack-encrypt"]
7373
description = "Full mutation-testing sweep of stack-encrypt (cargo-mutants; ~60 min)"
74-
run = "cargo mutants -p stack-encrypt --jobs 4"
74+
run = "mise x --env test -- cargo mutants -p stack-encrypt --jobs 4"

‎packages/stack-kms/tasks.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
["fuzz:client-key"]
1212
description = "Fuzz stack-kms's client-key material decoder (libFuzzer, nightly, 60s default)"
1313
dir = "{{config_root}}/packages/stack-kms"
14-
run = "cargo +nightly fuzz run client_key_encoded --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
14+
run = "mise x --env test -- cargo +nightly fuzz run client_key_encoded --sanitizer none --target $(rustc -vV | sed -n 's/^host: //p') -- -max_total_time=60"
1515

1616
# Rustdoc with warnings as errors: a broken intra-doc link or a rustdoc
1717
# warning fails the build. Doc *examples* are `test:doc:stack-kms`. Both run

0 commit comments

Comments
 (0)