Mitts Build releases

31 releases from 2026-10-18 to 2026-11-05, 3,216 downloads of release files.

v0.3.28latest

· Mitts v0.3.28

Mitts v0.3.28

Source commit: a770c7dbf688072a9f8b3c2a79393f6ad42ce7f1.

<!-- Release notes generated using configuration in .github/release.yml at a770c7dbf688072a9f8b3c2a79393f6ad42ce7f1 -->

What's Changed

Fixes

Features

Contributors

@alex09x

<details> <summary>Commits (11 of 11)</summary>

  • c59f4fc chore(release): drop the source-install check that runs after publication
  • a331492 Merge pull request #58 from alex09x/chore/drop-source-install-check
  • 4087465 feat: run every test in a process of its own, in parallel, with `mitts test -c`
  • 737870d docs: dangers and best practices of running tests with -c
  • 6128f33 Merge pull request #59 from alex09x/feat/test-concurrency
  • 6945838 ci: run the tests of this repository with -c, coverage included
  • 711eb46 Merge pull request #60 from alex09x/feat/concurrent-ci
  • c818f81 feat: -c without a number uses all the cores
  • 323b159 Merge pull request #61 from alex09x/feat/concurrency-all-cores
  • 6f36ae4 chore(release): prepare 0.3.28
  • a770c7d Merge pull request #62 from alex09x/release/0.3.28

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.27...a770c7dbf688072a9f8b3c2a79393f6ad42ce7f1

<!-- mitts-release-source:a770c7dbf688072a9f8b3c2a79393f6ad42ce7f1 -->

v0.3.27

· Mitts v0.3.27

Mitts v0.3.27

Source commit: d4ffecb74d26c1f4d0c52af66b103c715b80d767.

<!-- Release notes generated using configuration in .github/release.yml at d4ffecb74d26c1f4d0c52af66b103c715b80d767 -->

What's Changed

Fixes

Contributors

@alex09x

<details> <summary>Commits (12 of 12)</summary>

  • 2912f5c fix: write a lock a [patch] on a workspace member and multi-version dependencies can be read back
  • 180b84a fix: keep the outputs of an uncached build out of the shared store
  • 54ce22a Merge pull request #55 from alex09x/fix/lockless-self-patch
  • a768020 feat: do not let sccache switch the Mitts cache off
  • f2de134 feat: keep the shared cache under a size limit without running gc by hand
  • bfc272c chore(release): prepare 0.3.27
  • db9c29b fix: a cache check marker dated in the future counts as old
  • 1eb4ab2 Merge branch 'main' into fix/wrapper-uncached-warning
  • 80a8e3f Merge pull request #56 from alex09x/fix/wrapper-uncached-warning
  • 58fa4a6 fix(release): strip the debug map of the macOS binary with Apple strip before signing
  • 1131fe4 test(release): cover the Apple strip step of the packaging script
  • d4ffecb Merge pull request #57 from alex09x/fix/release-strip-debug-map

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.26...d4ffecb74d26c1f4d0c52af66b103c715b80d767

<!-- mitts-release-source:d4ffecb74d26c1f4d0c52af66b103c715b80d767 -->

v0.3.26

· Mitts v0.3.26

Mitts v0.3.26

Source commit: faaf63d8eb66565fedc978016f288f904f68812d.

<!-- Release notes generated using configuration in .github/release.yml at faaf63d8eb66565fedc978016f288f904f68812d -->

What's Changed

Fixes

Contributors

@alex09x

<details> <summary>Commits (4 of 4)</summary>

  • dae1cb0 fix: keep discovering src/bin binaries when [[bin]] tables exist
  • 1ca223e feat: add `mitts bench`
  • 4a9e97b chore(release): prepare 0.3.26
  • faaf63d Merge pull request #51 from alex09x/fix/auto-bins-with-explicit-bin

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.25...faaf63d8eb66565fedc978016f288f904f68812d

<!-- mitts-release-source:faaf63d8eb66565fedc978016f288f904f68812d -->

v0.3.25

· Mitts v0.3.25

Mitts v0.3.25

Source commit: e72f4e25ee406aa01ab425d3f85ec9891e896ec3.

<!-- Release notes generated using configuration in .github/release.yml at e72f4e25ee406aa01ab425d3f85ec9891e896ec3 -->

What's Changed

Fixes

Contributors

@alex09x

<details> <summary>Commits (5 of 5)</summary>

  • 0355de5 fix: place a workspace library's dylib and rlib in the profile directory like Cargo
  • a4a3c8b chore(release): prepare 0.3.25
  • 428c645 Merge pull request #48 from alex09x/fix/library-outputs-uplift
  • 67c5186 fix: key a library unit on the crate types rustc gets
  • e72f4e2 Merge pull request #50 from alex09x/fix/crate-types-in-key

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.24...e72f4e25ee406aa01ab425d3f85ec9891e896ec3

<!-- mitts-release-source:e72f4e25ee406aa01ab425d3f85ec9891e896ec3 -->

v0.3.24

· Mitts v0.3.24

Mitts v0.3.24

Source commit: 47c37368e83bf221a2bb2f892b6f0049e43307eb.

<!-- Release notes generated using configuration in .github/release.yml at 47c37368e83bf221a2bb2f892b6f0049e43307eb -->

What's Changed

Other changes

Contributors

@alex09x

<details> <summary>Commits (6 of 6)</summary>

  • aff3e2b fix: treat a crate at the root of a Mitts git checkout as an immutable dependency
  • 06bba91 chore(release): prepare 0.3.24
  • a7fa89c fix: keep stdout of llvm-cov --json for the report alone
  • 38f3430 fix: build a `lib` crate-type next to cdylib and staticlib as an rlib
  • 3e6081e fix: exclude the cache from coverage under the path spelling a profile records
  • 47c3736 Merge pull request #45 from alex09x/fix/coverage-git-deps

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.23...47c37368e83bf221a2bb2f892b6f0049e43307eb

<!-- mitts-release-source:47c37368e83bf221a2bb2f892b6f0049e43307eb -->

v0.3.23

· Mitts v0.3.23

Mitts v0.3.23

Source commit: ee57634c0e3c9c1bbe572a829f6699cdcfe7dbbb.

<!-- Release notes generated using configuration in .github/release.yml at ee57634c0e3c9c1bbe572a829f6699cdcfe7dbbb -->

What's Changed

Other changes

Contributors

@alex09x

<details> <summary>Commits (18 of 18)</summary>

  • acedd29 fix(release): clean source-install CAS cache safely
  • 749d8c0 test(gc): make last-used age assertion deterministic
  • 2a4db08 test(ci): preserve primary isolation probe failures
  • 0564702 Merge pull request #35 from alex09x/fix/source-install-cleanup
  • afe7d6b ci: remove Cargo-aware rust cache action
  • beba92d Merge pull request #37 from alex09x/ci/remove-cargo-rust-cache
  • a4a64c7 ci: shard the isolation probe, drop debug info from dev, cancel superseded PR runs
  • 000c17f Merge pull request #39 from alex09x/ci/parallel-isolation-probe
  • b2815ee fix(resolver): skip inactive optional dependencies absent from the lockfile
  • a38160e feat(ci): setup and save GitHub Actions for Mitts
  • 1fd64ee style: rustfmt the inactive optional dependency test
  • 0d2c9f9 fix(rust): do not pass -C lto to a library that also emits an rlib
  • 268113f feat(cli): --message-format=json for check and clippy, and -j/--jobs
  • 6fecd18 fix(coverage): unique report paths, standard-library exclusion and --output-path
  • d0072a2 fix(resolver): keep optional dependencies named by weak features in the lock
  • 4a2f3c2 chore(release): prepare 0.3.23
  • 4370ace test: read the whole request in the registry upload test servers
  • ee57634 Merge pull request #40 from alex09x/fix/issues-batch

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.22...ee57634c0e3c9c1bbe572a829f6699cdcfe7dbbb

<!-- mitts-release-source:ee57634c0e3c9c1bbe572a829f6699cdcfe7dbbb -->

v0.3.22

· Mitts v0.3.22

Mitts v0.3.22

Source commit: 8c29d828d68be2bca9745b8864194097a0508c26.

<!-- Release notes generated using configuration in .github/release.yml at 8c29d828d68be2bca9745b8864194097a0508c26 -->

What's Changed

Fixes

Contributors

@alex09x

<details> <summary>Commits (14 of 14)</summary>

  • 01297d4 fix(rust): link mixed crate-type library outputs
  • 22d5453 Merge pull request #19 from alex09x/fix/issue-17-linkable-artifacts
  • 4cc74df chore(release): prepare 0.3.22
  • 602f345 feat: self-host release packaging and Rust workflows
  • 9081568 style: format extracted modules
  • 1bb1f5b ci: verify integration isolation with candidate driver
  • df41482 test: guard isolated workflows against Cargo CLI
  • 15e3c7b fix: reject malformed manifests in resolver
  • a83f4f7 perf: reuse isolated probe controller cache
  • aa16123 test: reject incomplete integration target discovery
  • 5799826 test: expect malformed resolver input to fail
  • 7d46edb test: bypass proxies for loopback registry tests
  • a754caa test: isolate package fixtures from global store
  • 8c29d82 Merge pull request #20 from alex09x/release/0.3.22

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.21...8c29d828d68be2bca9745b8864194097a0508c26

<!-- mitts-release-source:8c29d828d68be2bca9745b8864194097a0508c26 -->

v0.3.21

· Mitts v0.3.21

Mitts v0.3.21

Source commit: 646e32a7675fe062e7cdce8260b65e279557742b.

<!-- Release notes generated using configuration in .github/release.yml at 646e32a7675fe062e7cdce8260b65e279557742b -->

Highlights

  • Cargo-compatible lock modes: --locked, --offline, and --frozen for native build/check/test/clippy/coverage/metadata and fetch workflows.
  • Cargo metadata: mitts metadata --format-version 1 reports workspace packages, dependency resolution, and selected features.
  • Cross-target builds: --target <triple> drives target selection, linker/rustflags, build-script environment, and Cargo-style target output paths.
  • Examples and execution: repeatable --example selection and unchanged forwarding of arguments after --.
  • Static libraries: mitts rustc --lib --crate-type staticlib -- --print native-static-libs emits native link requirements.
  • Quiet mode: -q / --quiet suppresses Mitts progress while preserving diagnostics and program output, including mitts run --quiet.

What's Changed

Build, CI and releases

Contributors

@alex09x

<details> <summary>Commits (8 of 8)</summary>

  • 84d2e76 feat(cli): honor locked and offline resolver modes
  • 0344cc3 fix(cli): preserve Cargo offline resolution semantics
  • c6cf152 feat(cli): add target-aware native metadata and targets
  • 0b2219f refactor(rust): keep target selection out of compiler API
  • d2f6730 chore(release): prepare 0.3.21
  • a9a2812 test: isolate offline resolver fixtures from default cache
  • 301484a test: capture nested CLI output in command checks
  • 646e32a Merge pull request #16 from alex09x/fix/locked-offline-build

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.20...646e32a7675fe062e7cdce8260b65e279557742b

<!-- mitts-release-source:646e32a7675fe062e7cdce8260b65e279557742b -->

v0.3.20

· Mitts v0.3.20

Mitts v0.3.20

Source commit: 14d7872d2e281c4396c74c986d9a66784994097a.

  • Rust build outputs now use Cargo's standard target/debug/ and target/release/ paths by default. CARGO_TARGET_DIR is used directly and explicit --target-dir overrides remain supported. Cleanup preserves unrelated Cargo files in a shared output directory.
  • Distribution binaries omit native dependency debug information that can retain build-machine paths; strict path and signature checks remain enabled.
  • Runners install the latest stable Mitts and use it for native builds, Clippy, formatting and the main test suite.
  • The test run emits LLVM coverage with a first-party line-coverage summary and downloadable LCOV data; documentation tests are checked separately.
  • Release descriptions include human highlights, automatically generated PR categories, contributors, commit links and the complete comparison.
  • After the owner starts Release in publish mode, signing and crates.io publication proceed automatically without separate Environment approvals.
  • The supported native matrix is macOS Apple Silicon and Linux ARM64/x86-64. The last macOS Intel prebuilt release is 0.3.19; its existing assets remain.

The source-package compiler, exact-source checks, Apple notarization, checksums and installation acceptance remain release gates. Cargo continues to supply registry packaging/publication and to test the Cargo installation methods. No new performance benchmark result is claimed by this release.

<!-- Release notes generated using configuration in .github/release.yml at 14d7872d2e281c4396c74c986d9a66784994097a -->

What's Changed

Fixes

Build, CI and releases

Contributors

@alex09x

<details> <summary>Commits (11 of 11)</summary>

  • 8885f71 release: self-host 0.3.20 with latest Mitts, coverage and native notes
  • 66114ca Merge pull request #7 from alex09x/release/0.3.20
  • 0e04e09 fix(release): omit native debug paths from distribution binaries
  • 5b9903b ci: use the standard target release directory for packaged binaries
  • aef17b0 prod: task 4629 Use Cargo-compatible default Rust build output paths
  • 80b1fc8 fix(rust): preserve Cargo artifacts when cleaning shared target outputs
  • 0e6f6f8 style: satisfy the native formatting gate for changed Rust files
  • 994ed37 fix: preserve distinct Cargo executable names
  • 81960a4 fix(rust): coordinate shared-target cleanup with Cargo
  • 31325b7 test: create workspace copies explicitly after removing executable aliases
  • 14d7872 Merge pull request #8 from alex09x/fix/release-native-debug-paths

</details>

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.19...14d7872d2e281c4396c74c986d9a66784994097a

<!-- mitts-release-source:14d7872d2e281c4396c74c986d9a66784994097a -->

v0.3.19

· Mitts v0.3.19

Highlights

  • Ready binaries for Linux ARM64/x86-64 and macOS Apple Silicon/Intel, with complete SHA256SUMS.
  • Developer ID signatures and Apple Accepted notarization for both Mac binaries.
  • Automated crates.io publication using GitHub Trusted Publishing.
  • Exact-source package verification and native install checks for the binary installer, registry Cargo, Git-tag Cargo and clone/path Cargo on all four platforms.
  • CI, isolated test stores, source provenance and installer fixes since0.3.18.

Install

cargo install mitts --version 0.3.19 --locked

Prebuilt archives are available below in Assets. This is the last release containing a macOS Intel prebuilt binary; later releases target Apple Silicon on macOS.

What's Changed

Full Changelog: https://github.com/alex09x/mitts/compare/v0.3.18...v0.3.19

Contributors

@alex09x

<details> <summary>Commits (24)</summary>

  • 36ef6bad corpus: insta replaces tonic; one harness per results file
  • 741288b8 corpus: similar replaces pulldown-cmark
  • edf9cbc6 fix(install): download verified native binaries from GitHub Releases
  • 7a61fb8c test(install): verify the deployed installer on all native targets
  • b337d09c ci(release): keep binary packaging scoped to tags and manual runs
  • 03fd45ee fix(install): avoid API limits and executable temporary directories
  • 21477fa1 style(install): satisfy focused Python lint checks
  • 545a6000 Merge pull request #2 from alex09x/fix/release-binary-installer
  • 7d72a51e ci: gate native release workflows on tests and immutable artifacts
  • 4df48216 ci(release): discover owned drafts through the authenticated listing
  • f6f532ef ci: preserve released formatting and fix safe release retry ordering
  • 0063a286 ci: verify main candidates and normalize Darwin linker path aliases
  • 764f25d9 ci: isolate per-target probe runs via Cargo host runner without recompiling
  • 6b77c75a ci: reuse exact main verification and wire compile-once store probes
  • 0be7e225 ci: avoid provenance rebuild loops and isolate the remaining planner test
  • b1b7c3ff Merge pull request #3 from alex09x/ci/release-workflows
  • 322ca9e3 ci: add fail-closed notarized Darwin release asset validator
  • ac3ee994 ci: sign and notarize Mac artifacts only during releases
  • b75bc2e8 fix(ci): pass literal codesign policy and separate ticket checks
  • 4357b88a Merge pull request #4 from alex09x/ci/apple-notarization
  • f6ba8cfa release: prepare 0.3.19 with automated registry publication
  • ce325a21 Merge pull request #5 from alex09x/release/0.3.19
  • e016d7ed fix(ci): register temporary signing keychain for codesign
  • 54a1813d Merge pull request #6 from alex09x/fix/release-keychain-search

</details>

Source: 54a1813.

<!-- mitts-release-source:54a1813dcf8d049970a3daf4fa9667936773a2e2 -->

v0.3.18

· mitts 0.3.18

Fix found by the 100-project corpus series on 0.3.17.

  • check-cfg: the implicit feature of an optional build-dependency is a declared feature value, as under Cargo. tonic's examples package gates its build script on one (#[cfg(feature = "protoc-gen-rust-grpc")]); Mitts declared only the normal dependency tables, so clippy reported an unexpected cfg condition value warning that Cargo does not. One manifest method now feeds the crate, build-script and doctest compilations.

Corpus: textwrap replaces minijinja (Cargo itself cannot build minijinja's CLI on two of the three series machines).

Ready-to-install native binaries

Prebuilt archives for this existing v0.3.18 tag are available for macOS Apple Silicon/Intel and Linux ARM64/x86-64 (glibc 2.35+). Download the archive for your target and verify it against SHA256SUMS. Each archive includes both licenses and BUILD.txt with exact source/compiler provenance.

Built from unchanged source 8a6ae03cde84d7fdaede0b43fb1ba9e12f221a9d with Rust1.98.0; native packaging, path hygiene and isolated archive installation passed on all four targets in CI41612018504. The tag and software version have not changed.

v0.3.17

· mitts 0.3.17

Fixes found by the 100-project corpus series on 0.3.16.

  • Resolver: a lockless resolution writes name version for a dependency whose name two versions of one crate share (tonic: strum 0.27 and 0.28). The lock Mitts wrote was rejected by its own loader as ambiguous.
  • Build scripts: generated code that names the absolute OUT_DIR (grpc-xds writes #[path = "<OUT_DIR>/…"] into its generated modules) survives the move of the script output into the store; the saved text files carry the store path.
  • Manifests: a [workspace.package] field (version, edition, rust-version) is inherited only where the member wrote field.workspace = true, as under Cargo. A member without rust-version no longer gets the workspace's, which made clippy's incompatible_msrv fire under Mitts alone (winnow's fuzz member).
  • Features: an optional dependency declared in both [dependencies] and [build-dependencies] is activated on both sides, so target units link the target instance (minijinja-cli: E0277 on a trait implemented by the other instance).
  • Dependencies: a lock spec names a git source without its pinned commit (mio from a git source).
  • explain --manifest-path from another directory reads the project's [patch] tables from its root manifest, not the current directory's.

Benchmark harness: an excluded package and a test target with its own harness are not defect-injection roots; build-script output files key as OUT_DIR/<name> in diagnostics parity; the check and clippy swarms keep every failed worktree's output tail.

v0.3.16

· mitts 0.3.16

Mitts 0.3.16 fixes five defects the 100-project corpus series on 0.3.15 exposed, all with regression tests.

Fixes

  • [lints] flags follow Cargo's priority order. A lint group with priority = -1 (pedantic = { level = "warn", priority = -1 }) and individual allows of its members were emitted in table order, so the group's -W came last and re-enabled every member. Cargo sorts by priority, then name; Mitts now does the same. hyper's clippy swarm reported 3,889 warnings against Cargo's 3; ratatui 328 against 3.
  • A package may depend on another version of a package with its own name. rand_core 0.3 is a shim: extern crate rand_core as core4; re-exports rand_core 0.4, a dependency carrying the shim's own crate name. Extern resolution dropped every --extern whose name equalled the unit's package name, so the shim got none and rustc found two candidates (petgraph, E0464). Only the unit's own package is skipped now. For the path-package form of the same shape the planner follows path dependencies transitively and keeps every package found under a name, and the lockless resolver writes "name version" for an ambiguous dependency, as Cargo does.
  • A diagnostic repeated by another compilation is shown once and counted. A crate compiled for the host (as a proc-macro's dependency) and for the target warns twice; Cargo prints the diagnostic once and appends (N duplicates) to the compiler's summary line. Mitts printed every copy (pest, quote). Located diagnostic blocks are hashed per build, on compilation and on cache replay alike; the cache entry keeps the compiler's full output.
  • build.rs is linted when another worktree ran the build script. In a swarm of worktrees sharing one cache, a mitts clippy process that waited on the build-script lock and found the result published meanwhile returned before the clippy pass over build.rs, so its warning was missing from that run and appeared only on the next, fully cached one (ring). The restored result is handled like a first-try hit.

Benchmark harness

  • A test target behind required-features is not an injection root: reqwest's tests/blocking.rs and smallvec's tests/arbitrary.rs are never built with default features, so the injected defect was caught by no tool and the run was invalidated.
  • The corpus keeps a hundred projects Cargo can build: askama, syn and prost leave it (their test suites do not build in a stable, default-feature environment: askama's workspace tests do not compile upstream, syn's suite is nightly-only, prost's test crates need protoc's compiler includes); minijinja, strum and log take their places.
  • Diagnostics parity compares the set of distinct diagnostics and reports repeats separately; swarm commits whose tests Cargo cannot build are replaced by the nearest buildable commit and the substitution is recorded.

Checked

Full suite green on Linux (836 passed, the 8 intentional fixture failures), clippy clean. The corpus smoke (cargo check|clippy|test --no-run --workspace against the same Mitts command from an empty cache, every project at HEAD) agreed on the 50 projects it reached before it was stopped to start the full series; the 0.3.16 benchmark series on all 100 projects, on three machines with one toolchain (Rust 1.99.1), carries the complete comparison. Toolchains per machine: docs/benchmark-environment.md.

Install or update:

cargo install mitts --version 0.3.16 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.15...v0.3.16

v0.3.15

· Mitts 0.3.15

Mitts 0.3.15 closes two target-discovery gaps found by comparing the number of test executables Cargo and Mitts build for each of the 100 corpus projects.

Fixes

  • An example declared with test = true is a test target. cargo test --tests compiles such examples as test executables; clap declares pacman and 05_01_assert_derive that way, and Mitts built 22 test binaries where Cargo built 24. Examples are discovered with their path, harness and required features and selected under --tests.
  • An explicit target without path may live in its directory form. Cargo infers tests/<name>.rs or tests/<name>/main.rs for a [[test]], and src/bin/<name>.rs or src/bin/<name>/main.rs for a [[bin]]; Mitts tried only the flat file. toml_edit declares its directory tests with autotests = false, so nothing else found them: 26 test binaries where Cargo built 29.

Checked

Full suite green on Linux (831 passed, the 8 intentional fixture failures), clippy clean. Corpus smoke pass on the release candidate: all 100 projects agree with Cargo on check, clippy and test --no-run, test-binary counts included; evidence in docs/corpus-smoke-v0.3.15.json.

Install or update:

cargo install mitts --version 0.3.15 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.14...v0.3.15

v0.3.14

· Mitts 0.3.14

Mitts 0.3.14 fixes four defects found by a smoke pass of the 100-project corpus that compares Cargo and Mitts on check, clippy and test --no-run for every project.

Fixes

  • Dependencies are never excluded by name. A list of "foreign platform" crate names (windows-*, core-foundation, wasm-bindgen, objc2, …) removed such packages from the plan on other hosts even when a manifest depended on them unconditionally. chrono's test suite uses windows-bindgen, a pure code generator that builds everywhere, and failed with "unresolved import windows_bindgen". Platform exclusion now comes only from [target.'cfg(...)'] tables, as in Cargo; a tokio/mio workspace still builds no Windows crates on Linux.
  • --check-cfg only for toolchains that accept it. dashmap pins Rust 1.70 through rust-toolchain.toml; rustc of that age rejects the flag and Cargo of that era never passed it. The probed toolchain's release gates the flag for unit compiles, build-script compiles and doctests.
  • A library with native crate types is a workspace root. A member whose [lib] declares crate-type = ["staticlib", "cdylib", "rlib"] was never selected by --workspace, so mitts clippy --workspace on regex exited 0 while Cargo reported deny-level errors in the C API crate rure.
  • Underscore spellings of manifest keys. Cargo accepts proc_macro, crate_type and required_features; derive_arbitrary 1.3.2 publishes [lib] proc_macro = true and Mitts planned it as a plain library.

Checked

Full suite green on Linux (829 passed, the 8 intentional fixture failures), clippy clean. Corpus smoke pass on the release candidate: all 100 projects agree with Cargo on check, clippy and test --no-run (the first pass on 0.3.13 disagreed on dashmap, regex and tokei); evidence in docs/corpus-smoke-v0.3.14.json.

Install or update:

cargo install mitts --version 0.3.14 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.13...v0.3.14

v0.3.13

· Mitts 0.3.13

Mitts 0.3.13 fixes two more defects the 100-project corpus exposed and cleans up failure output.

Fixes

  • Resolver 1 activates unified optional dependencies on the host side. A virtual workspace without a resolver key uses resolver 1, where host and target features are unified. argh's argh_shared is used by the argh_derive proc-macro (host) and by argh with the serde feature on: Mitts unified the feature names, so the host copy was compiled with --cfg feature="serde", but never activated serde for the host and failed with "can't find crate for serde". After unifying, feature propagation now runs again until nothing changes, so the host dependency closure matches Cargo's.
  • A failed check or clippy prints each diagnostic once. The progress callback already streams the compiler's output; the failure path printed the captured output a second time, doubling every warning and error.

Benchmark harness

  • A project Cargo cannot build either (askama's workspace tests do not compile under cargo test --workspace --tests upstream) is recorded as SKIPPED_CARGO_FAILS_<stage> with both tools' output instead of an ERROR attributed to Mitts.
  • Diagnostics parity compares compiler diagnostics only: Cargo's own notes (unused manifest key, resolver and profile messages) carry no source location and are left out.

Checked

Full suite green on Linux (825 passed, the 8 intentional fixture failures), clippy clean; mitts check --workspace and mitts test --workspace --tests --no-run pass on argh.

Install or update:

cargo install mitts --version 0.3.13 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.12...v0.3.13

v0.3.12

· Mitts 0.3.12

Mitts 0.3.12 completes the link-search fix of 0.3.11 for warm builds.

Fix

  • A restored unit passes its dependencies' link-search directories on. 0.3.11 propagated a build script's cargo:rustc-link-search down the dependency graph, but only through units that were compiled in the same build. A unit restored from the cache recorded its own directives and nothing else, so with test → openssl → openssl-sys and the two libraries cached, a recompiled test still failed with ld: library 'ssl' not found. The restore path now inherits and records the directories the same way; the regression test builds the three-crate chain cold and then warm with an edited test.

Checked

Full suite green on Linux (824 passed, the 8 intentional fixture failures), clippy clean.

Install or update:

cargo install mitts --version 0.3.12 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.11...v0.3.12

v0.3.11

· Mitts 0.3.11

Mitts 0.3.11 fixes three defects the first run over the 100-project corpus exposed. Each has a regression test.

Fixes

  • An older version of a workspace member is not the member. A library's dev-dependencies often pull in an older published version of the library itself (ahash's tests depend on hashbrown, which depends on ahash). That copy shares the member's name, and the planner treated it as the primary package: it received the member's root features and test targets and failed to compile with "cannot find crate" for an optional dependency the lockfile had never activated. The primary role and the root feature requests now belong to workspace members only, and a package's own library reaches its binaries and tests under its own name even when a renamed dependency on the older version (foo_old = { package = "foo", … }) exists.
  • mitts test uses the test profile. Every unit was built with the dev profile. Cargo builds tests with test (and bench under --release), which inherits its base profile and overrides the keys it sets; ahash's [profile.test] opt-level = 2 is what lets its #[no_panic] tests link at all. Profile resolution now layers test/bench over dev/release at every level: top-level keys, package and build-override tables and the CARGO_PROFILE_* environment. lto applies to test executables as well.
  • Dependency link-search directories reach the final link. A build script's cargo:rustc-link-search was passed to that package only. A native library linked as dylib is resolved when the final executable is linked, by a unit that never ran the script, so Cargo passes every dependency's directories to its dependents. Mitts now propagates them down the dependency graph; on macOS actix-web's tests stopped at ld: library 'ssl' not found.

Checked

Full suite green on Linux (824 passed, the 8 intentional fixture failures), clippy clean. ahash and actix-web test builds on macOS with the fixed binary; the corpus series restarts on this version.

Install or update:

cargo install mitts --version 0.3.11 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.10...v0.3.11

v0.3.10

· Mitts 0.3.10

Mitts 0.3.10 prepares the 100-project benchmark run: the diagnostics every command prints and the provenance of a packaged binary.

Diagnostics

  • MITTS_TIMINGS=1 works for build, check and clippy. The I/O counters (bytes cloned, copied and hardlinked), the phase sums (restore, publish, rustc, build scripts, unit keys) and the build-script hit counts were printed only by mitts test. The three other commands now print the same [mitts::io] and [mitts::timings_sum] lines, so a cold build or a history replay reports how many bytes it cloned and how long the cache spent restoring and publishing.
  • mitts --version names the commit of a crates.io build. A package built from the crates.io tarball has no .git, so the version line said (unknown). The build script now reads the commit from .cargo_vcs_info.json, which cargo package writes into every tarball.

Benchmark harness

The harness (scripts/benchmark_project.py) keeps every metric it measures: CPU time and peak RSS for every timed run and summed over the 12 worktrees of a swarm, compiled, cached and tainted unit counts for every arm, full per-iteration sample lists, bytes read from the device as well as written, Mitts I/O and phase counters in the swarms, smoke-test tallies, and the selected swarm and replay commits. A resumed corpus run keeps every measured or skipped project and redoes only the ones that errored; the T4 and T5 cache snapshots are removed as soon as their stage ends; the sources of every selected commit are unpacked before the timed stages; provenance records the volume device, mount options, disk model and free space. --online-fetch adds one cold download per tool over the live network to T1.

Checked

Full suite green on Linux (821 passed, the 8 intentional fixture failures), clippy clean. Smoke runs of the new harness on two corpus projects produced every new field.

Install or update:

cargo install mitts --version 0.3.10 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.9...v0.3.10

v0.3.9

· Mitts 0.3.9

Mitts 0.3.9 closes the third review round of the benchmark methodology.

Diagnostics

  • MITTS_NO_REFLINK=1 copies bytes. The flag exists to measure what a real copy costs, but its fallback was std::fs::copy, which clones on APFS (fclonefileat) and on XFS with reflink (the kernel turns copy_file_range into a clone). The benchmark's copy arm therefore wrote nothing on either filesystem and matched the reflink arm; only ext4 copied. With the flag set the bytes now go through a user-space read/write loop. The ordinary fallback, where cloning is the point, keeps std::fs::copy. Measured on ripgrep over XFS: copy 0.066 s and +408 MB written against reflink 0.017 s and nothing written.

Benchmark harness

  • The T4 copy-on-write ablation settles the filesystem before each disk-usage and device-write sample, as the T2 cold-build samples already did, so the reflink arm no longer reports a negative delta.
  • docs/benchmarks-execution-plan.md records which series compared what in T4 (≤ 0.3.6 reflink against a read-only store hardlink, 0.3.7 and 0.3.8 reflink against a kernel clone on APFS and XFS) and that bytes_hardlinked also counts intra-workspace aliases.

Checked

Full isolated suite green on Linux and macOS, clippy clean. The 0.3.7 and 0.3.8 series on both machines are in the repository's benchmark results; the review thread covers them.

Install or update:

cargo install mitts --version 0.3.9 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.8...v0.3.9

v0.3.8

· Mitts 0.3.8

Mitts 0.3.8 closes the second review round of the 0.3.7 changes (04118d5).

Correctness

  • A poisoned store object is refused through its named artifact too. In native mode (mitts test, check, clippy, build --native) rustc receives --extern paths under <store>/artifacts/, hardlinks to the store objects that involve no restore step. 0.3.7 re-hashed a writable object only on the restore path; the check is now shared, so an object made writable and overwritten through any link is re-hashed, removed on mismatch and resealed on match before it reaches rustc.

macOS

  • -oso_prefix covers every linked unit. The prefix is derived from the checkout that owns the target directory rustc receives, not from the linked package's own workspace root, so registry proc macros (whose manifests live in the store) and test binaries linking archives under target/build get it as well.
  • The macOS test now links a transitive crates.io crate through the checkout's deps directory, which is the path that used to be absolute; the 0.3.7 version of that test passed without the fix.

Housekeeping

  • mitts explain resolves the manifest before pointing the toolchain probe cache at the cache root, so a failing call leaves the process-wide cache root alone.

Checked

Full isolated suite green on Linux and macOS, clippy clean. The 0.3.7 benchmark series on both machines completed between the two review rounds; the numbers are in the repository's benchmark results alongside the review thread.

Install or update:

cargo install mitts --version 0.3.8 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.7...v0.3.8

v0.3.7

· Mitts 0.3.7

Mitts 0.3.7 follows an independent review of the 0.3.6 benchmark series: every finding that was real is fixed here, the benchmark harness measures what its field names say, and one macOS-only loss of cache sharing is gone.

Correctness (e43d598)

  • A poisoned store object is no longer resealed. With store hardlinks (the default where reflink is unavailable) a workspace file shares the store object's inode; chmod u+w plus a write changed the object, and the trusting restore relinked and resealed it. A restore now re-hashes any object that carries a write bit, removes it when the hash mismatches, and reseals it when it matches. The ordinary read-only path still reads no bytes.

macOS (2a55e39)

  • Linked binaries are shared across checkouts. ld64 records every linked object's absolute path in the output's N_OSO stabs, which --remap-path-prefix does not reach; the dependency rlibs restored under a checkout's target/ put the checkout path into every binary, so a second clone relinked it (ripgrep's rg: 2 s on macOS against 20 ms on Linux). Mitts passes -oso_prefix with the workspace root, the stabs become target/mitts/debug/deps/…, and a second checkout restores the binary. Start a debugger in the workspace root for it to find the object files.
  • The config start directory is chosen on real paths, so a project under /var (reported as /private/var) no longer skips a member's .cargo/config.toml (d266166).

Performance (e43d598)

  • mitts explain now uses the toolchain probe cache like the builder; it used to spawn rustup and rustc on every call.

Knobs

  • MITTS_FAST_LOCK=0|1 overrides the fast build lock's default of "on only for the default cache root", so a benchmark with an explicit --cache-dir can measure it.

Benchmark harness (e43d598, 392e736, 2a55e39)

  • The T4 copy ablation sets MITTS_STORE_HARDLINKS=0, so the copy arm copies bytes; in series up to 0.3.6 it compared reflink against a read-only store hardlink.
  • T2 gains s2_fast_lock_noop_ms (fast-lock hits on mitts build, with a hit counter) next to s2_fast_noop_ms, which is the plan + action-cache no-op.
  • T0 warms the probe cache before timing and reports the metrics of a warm run.
  • Disk-usage deltas are sampled after the filesystem settles; the known limits of du, device write counters and df deltas are written down in docs/benchmarks-execution-plan.md.

Checked

Full isolated suite green on Linux and macOS, per-target store isolation probe clean, clippy clean. Both findings the review got wrong (a cache purge that supposedly missed directories, an invariant supposedly hardcoded) were checked against the code and rejected.

Install or update:

cargo install mitts --version 0.3.7 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.6...v0.3.7

v0.3.6

· Mitts 0.3.6

Mitts 0.3.6 closes the gap between the ways Cargo obtains a crate and the ways Mitts did. Before this release a dependency existed for Mitts only if it came from crates.io or if Cargo had already checked it out; now every source Cargo's configuration can name works from that same configuration, without running Cargo, and a lockfile resolved by Mitts matches the one Cargo writes.

Git dependencies (300a44a, be007fd)

  • Mitts clones git dependencies itself with the system git: a bare mirror under <cache>/git/db/ and a working tree per locked commit under <cache>/git/checkouts/. SSH keys, agents, credential helpers and GIT_SSH_COMMAND apply unchanged; prompts are disabled so a missing credential fails instead of hanging. A checkout Cargo already made is reused.
  • Without a lockfile, the manifest's tag, branch or rev is resolved to a commit with git ls-remote (an annotated tag pins the tagged commit, as Cargo does), the package's own dependencies join the resolution, and the lock entry is written exactly as Cargo writes it. mitts fetch re-resolves when the reference moved. MITTS_GIT selects the git binary.

Registries, mirrors, vendoring, patches (31e4e5f)

  • Alternative sparse registries: [registries.<name>] index = "sparse+…" with registry = "<name>" on the dependency. The index's config.json gives the download template and auth-required; each index caches under <cache>/index/<digest>/, its packages under <cache>/sources/src-<digest>/. Git-index registries and local-registry sources are refused with advice.
  • Mirrors: [source.crates-io] replace-with = "<name>"; bytes come from the mirror, Cargo.lock keeps naming crates.io.
  • Vendored sources: [source.vendored-sources] directory = "vendor" for crates.io and git packages alike, verified against .cargo-checksum.json; without a lockfile the vendor directory serves as the index. No network is touched.
  • [patch.<source>] with path or git replacements, resolved and pinned without a lockfile and required to satisfy the requirement.

Credential providers (ef4d0ca)

  • Tokens come from Cargo's providers in Cargo's order: cargo:token (CARGO_REGISTRIES_<NAME>_TOKEN, [registries.<name>] token, credentials.toml), cargo:macos-keychain, cargo:libsecret, cargo:token-from-stdout <command>, and plugins such as cargo-credential-1password through the credential provider protocol. [registries.<name>] credential-provider, [registry] global-credential-providers (later entries first) and [credential-alias] are honoured.

Lockfile resolution (31e4e5f)

  • Resolution follows Cargo's rules: features flow along dependency edges (dep:, dep/feat, dep?/feat, implicit features, features2 from the index), an optional dependency of a transitive package enters only when a feature activates it, requirements in one compatibility range share one version, and errors name the package that required the unsatisfiable requirement. The previous resolver pulled every optional dependency of every package into the lock.
  • Cached index entries older than MITTS_INDEX_TTL_SECS (default 900) are re-read when online, so a fresh lockfile sees current versions.

Cargo config (e2fdd86)

  • [env] tables are applied with Cargo's force and relative rules to rustc, build scripts and the programs mitts run and mitts test start. A config holding one (a ~/.cargo/config.toml with SCCACHE_CACHE_SIZE, say) no longer makes Mitts refuse the whole configuration.

Checked against real projects

A private workspace with eight SSH git dependencies and no Cargo checkout cloned them all in 17 s and built from the clones; a public Cloudsmith sparse registry; two crates.io mirrors on Azure Artifacts (61 and 442 packages fetched); a committed 1000-crate vendor directory planned with the network cut; [patch] builds of two public projects; a library without a lockfile resolving to the same 101 packages cargo generate-lockfile resolves. Full isolated suite green on Linux and macOS, per-target store isolation probe clean, clippy clean.

Install or update:

cargo install mitts --version 0.3.6 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.5...v0.3.6

v0.3.5

· Mitts 0.3.5

Mitts 0.3.5 is a performance release for warm cache hits and for many checkouts of large workspaces. Profiling the warm no-op path showed the time was not filesystem work but serial toolchain probes, a full source scan on every run, re-hashing of every restored byte, and per-package path locks that cascaded through result keys. Each of those is fixed here.

Warm-hit path (f279d90, ce712b7, 65fb4da, de2b86e)

  • Toolchain probes are cached on disk. rustup which rustc, rustc -vV and rustc --print cfg ran serially on every invocation; they now live under <cache>/toolchain/, keyed by the binary's identity and the rustup selection (RUSTUP_TOOLCHAIN, RUSTUP_HOME, settings and the nearest rust-toolchain file). Rustup proxies are never cached.
  • Restored objects are trusted. A cache hit no longer re-hashes every restored artifact (one read of every byte, hundreds of MB for a mid-size workspace). Store objects are immutable and read-only; MITTS_VERIFY_RESTORE=1 restores the check.
  • The env! scan is memoized per file. The scan that finds CARGO_MANIFEST_DIR readers used to read every .rs of every local package on each run; it is now keyed by file length and mtime under <cache>/env_macros/. Adding, removing or editing files still invalidates it.
  • Scheduler wake-ups. One worker is woken per ready unit instead of all of them per completion; the registry index is listed once per process. MITTS_CACHE_IO_BUDGET overrides the number of concurrent cache readers.

Path locks scoped to the target (facf59f, 83cdf10, f497a92)

  • A CARGO_MANIFEST_DIR read in one example or test used to lock the whole package on its absolute path, and because dependents key on their dependencies' result keys, every unit downstream was rebuilt per checkout. Locks are now scoped by Cargo target layout (src/ for the library, root file plus module directory for bins, tests, examples and benches). The publish-time leak scan remains the safety net.
  • The scan stops at nested packages and treats env!(#x) inside quote! as interpolation, not a read.
  • Artifacts that embed their checkout path are published under a per-checkout key; once that is known, other checkouts no longer queue on the shared single-flight lock and build in parallel.

Store hardlinks (0d3c0d4, ef7fc6a, 0ffe678)

  • MITTS_STORE_HARDLINKS is a three-state policy. The default is auto: reflink where the filesystem supports it, otherwise a read-only hardlink to the store object, otherwise a copy. Linked files are never writable (0o444, 0o555 for executables); the target index rejects a link that gained write bits and restores it. MITTS_STORE_HARDLINKS=0 keeps the old copy-only behaviour, 1 always links. On ext4 this removes multi-gigabyte byte copies from every warm hit of a large workspace.

Build scripts (a7ad705, f4c0298, 1254078, 857fbc0, 7435b66)

  • Build scripts receive the full CARGO_PKG_* metadata for both compile and run.
  • Executables a build script writes into OUT_DIR keep their exec bit in the store.
  • A package's library, unit tests and integration tests share one build-script run on a cold miss instead of each executing it.
  • A cache entry that lost its directives is replaced on the next save.
  • [lints.cargo] is never forwarded to rustc (it produced E0602 and made some workspaces unbuildable).

Measured

Warm single hit, Apple Silicon/APFS: semver 83 ms → 20 ms, ripgrep 250 ms → 60 ms. Fresh 12-checkout swarm on x86_64 Linux/ext4, v0.3.4 → 0.3.5: ratatui 7.0 s → 0.21 s, tokio 7.0 s → 0.16 s, rustls 3.2 s → 0.45 s, delta 34 s → 5.9 s, winnow 34 s → 5.1 s, bat 6.2 s → 2.1 s, axum 0.57 s → 0.08 s; actix-web, lsd and tokei did not build on 0.3.4 and do now (actix-web swarm 0.25 s). On XFS with reflink, ratatui (462 packages) warm single 0.22–0.49 s → 0.08 s, swarm 1.45 s → 0.22 s. Remaining swarm time in clap, xh, delta and winnow is real per-checkout compilation of test binaries that embed the checkout path.

Install or update:

cargo install mitts --version 0.3.5 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.4...v0.3.5

v0.3.4

· Mitts 0.3.4

Mitts 0.3.4 is a performance release for warm cache hits, aimed at the gap between macOS/APFS and Linux that the T5 worktree-swarm study exposed: on a warm cache Mitts compiles nothing, so its time is filesystem and process work, which costs several times more per operation on APFS than on XFS or ext4.

Cache hits (42da312, 77017dc, e0997b1)

  • Named artifact hits are read-only. A hit no longer repairs the link between a cache object and its named alias; snapshot links are preserved instead of being recreated by every reader. On a cache restored by copying, twelve concurrent readers used to spend most of their time on link/rename/unlink repair.
  • Checkout path aliases are normalized. Canonical and lexical checkout/output paths are remapped so a local proc macro is reused across macOS path aliases (/tmp vs /private/tmp) without retaining checkout paths. The remap protocol is versioned in unit keys and fast-lock options; all input freshness and leak checks are kept.
  • Less per-invocation work on macOS. Runtime-detected ARM SHA-256 acceleration; per-invocation cache and planning work is bounded; package-tree hashes that no unit consumes are skipped; real compilation and publication stay outside the cache-reader queue.
  • Jobserver work is deferred until something compiles. The managed pool initializes lazily and execution tokens are acquired only after cache and single-flight checks; a build-script miss keeps its reservation for the consuming unit; managed unit reservation happens after the single-flight lock and the second restore. Build-script last-use updates are throttled while GC refresh is preserved.

Jobserver (7970284, ae9206a)

  • Live slot descriptors are reused during contention instead of repeated directory creation and open/close cycles; a local atomic lease precedes the kernel lock so one shared descriptor is never granted twice. The blocking single-slot path and retry of failed opens are unchanged. FIFO token counting is portable on macOS.

Diagnostics (42ff7c6)

  • MITTS_TIMINGS=1 measures input validation boundaries separately.

Measured so far (paired warm-hit diagnostics, not a full study): anyhow 12-worktree hit on Apple Silicon/APFS 1.53 s → 0.50 s, itoa 1.51 s → 0.31 s, aggregate system CPU 29 s → 4–5 s; on x86_64 Linux/XFS itoa 0.062 s → 0.043 s. The full T0–T5 series on both platforms is being rerun on this release.

Install or update:

cargo install mitts --version 0.3.4 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.3...v0.3.4

v0.3.3

· Mitts 0.3.3

Mitts 0.3.3 reduces planning and filesystem work on cache hits and fixes host feature handling for primary proc-macro crates.

Cache-hit performance

  • Share manifest bytes, parsed manifests and manifest digests within one build plan, including its key and DAG workers. The snapshot is invocation-scoped; disk-byte and ancestor-manifest checks still reject changed inputs.
  • Allocate build-script staging/output directories only when needed. Reuse the current execution's OUT_DIR purity calculation instead of scanning the same output twice.
  • Continue linting a primary build.rs in Clippy mode even when its execution is cached.

In a five-pair diagnostic on itoa (12 concurrent worktrees, 47 cached units, zero compiled units and two test binaries per worktree), median wall time changed from 1.510 to 0.306 seconds on Apple Silicon/APFS (4.94x), and from 0.0622 to 0.0429 seconds on x86_64 Linux/XFS (1.45x). Single-worktree improvements were about 1.2x. Linux successful Cargo.toml opens decreased from 544 to 301; freshness rereads remain. These are measurements of this warm-cache case, not a general build-speed guarantee or a complete T0-T5 study.

Correctness

  • Seed primary proc-macro roots in the host context and propagate their host dependency features.
  • Preserve defaults, explicit features and dev-dependencies for proc-macro test targets under Resolver 2; retain Resolver 1 unification.
  • Preserve impure OUT_DIR cache matching and native OS paths in build-script command construction.

Library API note: callers constructing EffectivePlanExplanation with a struct literal must initialize the new runtime-only manifest_snapshot field with Default::default(); serialized plan output is unchanged. The build_script_cas::try_restore_build_script_cas output-directory argument is now optional.

Validation: 32 focused release-mode tests passed on Linux, 13 on macOS, plus the directly affected manifest and build-script invalidation/purity tests. Library Clippy passed with warnings denied. The full test suite was not run for this change.

Install or update:

cargo install mitts --version 0.3.3 --locked

Full history: https://github.com/alex09x/mitts/compare/v0.3.2...v0.3.3

v0.3.2

· Mitts 0.3.2

Mitts 0.3.2 drops the built-in list of "known pure" proc macros in favour of a project-level declaration, and teaches the benchmark harness to measure on a machine that is never idle.

Engine (ada8b2b, 9d89a07, 561ae0f)

  • Proc macros are pure unless the project says otherwise. A unit that depended on any proc macro outside a hard-coded list of two dozen names was keyed on its absolute manifest directory, so every new worktree recompiled and relinked it although nothing had changed; rustversion in [dev-dependencies] was enough to path-lock every test target of a crate. The list is gone: every macro's dependents now get path-independent keys that are shared across checkouts. A macro that reads package files while it expands (sqlx, askama, rust-embed, include_dir, a local derive) is declared in the root Cargo.toml:

    [workspace.metadata.mitts]          # [package.metadata.mitts] in a single crate
    impure-proc-macros = ["sqlx", "askama"]
    

    Its direct dependents are keyed on every file in their package and on their absolute path, so an edited template rebuilds them and another checkout never reuses them. A malformed table fails the build; an unknown key warns once. The artifact scan that keeps a path-embedding artifact from being shared across checkouts is unchanged. Verified against a real crates.io macro that registers nothing with rustc (include_dir): declared, an edited asset changes the key; undeclared, it does not, exactly as with Cargo.

  • MITTS_LOG_KEYS=1 prints every unit's action key with its flags, inputs and dependency hashes, and the reason whenever a unit is keyed on its absolute path.

Benchmark harness (55b71e5, ca8ebc1, 3468eb4, c87afde, f718f21)

  • The quiet-rig gate measures the machine's CPU baseline before a run and accepts the larger of --max-busy and baseline + 0.10. A steady foreign load that holds for five samples with no compiler running is adopted as the new baseline and released when it ends. A timeout no longer aborts the run: the result is flagged GATE_TIMEOUT and every gate decision is recorded under gate_events.
  • An idle sccache server is not a foreign compiler; the macOS device lookup is cached per run; a swarm stage reads the load average instead of re-gating; a results file whose project ended in ERROR or NOISY no longer blocks a rerun into the same file.

Full history: https://github.com/alex09x/mitts/compare/v0.3.1...v0.3.2

v0.3.1

· Mitts 0.3.1

Mitts 0.3.1 fixes two correctness bugs found by running the T0–T5 study on anyhow across XFS, ext4 and APFS, and makes the benchmark harness itself honest about time.

Engine (9fbaf71)

  • Build scripts are keyed on [build-dependencies] only. The cache key and --extern line of a build script used every regular dependency of the package: the bytes of each dependency rlib were hashed on every build, and the digest differed between the cold build and the restored artifact, so scripts re-ran after each cache restore. Only build-dependencies (including target-specific ones) reach a script now, as in Cargo. Warm test --no-run of anyhow (53 units, 27 scripts): 0.23 s → 0.03 s on Linux, 2.1 s → 0.27 s on macOS; the 12-worktree swarm on XFS went from 3.5 s to 2.9 s (5.6× plain Cargo, 4.5× sccache).
  • Generated lockfiles carry dev-dependencies and optional dependencies. The native resolver dropped [dev-dependencies], optional dependencies and [target.*] tables, so mitts test --no-run on a project without a Cargo.lock could not build its tests. Members' dev, build and target-specific dependencies and optional dependencies now enter the lockfile like cargo generate-lockfile; the planner also discovers path dependencies declared under [dev-dependencies].
  • MITTS_TIMINGS=1 reports build_script_sum_s, unit_key_sum_s and build-script cache hits/misses; MITTS_LOG_COMPILE=1 logs each script's hit or miss and the inputs of its key.

Benchmark harness (e24add7)

  • The quiet-rig gate samples CPU busy time over one second (/proc/stat, macOS iostat) instead of the 1-minute loadavg, which the swarm itself inflated: the anyhow runs had spent 70–80 % of their wall time waiting between arms (metrics were unaffected). --max-busy replaces --max-load as the gate; loadavg is still recorded.
  • On macOS ps -eo comm truncates paths, so foreign cargo/rustc processes were never detected there; the check now reads args.
  • Every stage prints one progress line per measured arm.

Full history: https://github.com/alex09x/mitts/compare/v0.3.0...v0.3.1

v0.3.0

· Mitts 0.3.0

Mitts 0.3.0 gives every store one cache root and makes the test suite prove its own isolation. The public API changes shape (new cache_dir parameters, a new RustBuildOptions field), hence the minor bump.

One cache root for every store (d260ef2)

  • A single resolver (core::cache_root) picks the root for the artifact store, action cache, locks, jobserver, unpacked sources and the sparse-index cache: --cache-dir / RustBuildOptions::cache_dir, then $MITTS_CACHE_DIR, $XDG_CACHE_HOME/mitts, ~/.cache/mitts. An empty variable counts as unset. The source store and the index cache now honour XDG_CACHE_HOME like the other stores.
  • An explicit cache_dir reaches every consumer that used to fall back to the default location: NativeResolver::for_cache_dir, SparseIndexClient::for_cache_dir, CargoLock::resolve_or_sync(.., cache_dir), RustAdapter::resolve_lockfile(.., cache_dir), RustAdapter::fetch(.., cache_dir), the rustc invocation (RustcInvocation::cache_root replaces the MITTS_CACHE_DIR / out_dir heuristic), mitts explain --cache-dir, build-script purity prefixes and mitts gc, which prunes only the sources of its own root.
  • is_immutable_package_dir recognises a source-store entry by its <root>/sources/<name>-<version> layout and .mitts-ok marker, so dependencies fetched into a custom cache keep their immutable treatment (no package-tree hashing, --cap-lints allow).
  • RustBuildOptions::fast_lock: Option<bool> keeps the fast build lock active with an explicit cache_dir when set to Some(true); the default behaviour is unchanged.

Test isolation (63f8bac)

  • Every test that builds uses its own cache root; tests that fake HOME also clear and restore XDG_CACHE_HOME. Run on its own with a throwaway HOME, no test target reaches ~/.cache/mitts any more (169 targets probed, 0 writers).
  • tests/cache_root_isolation_test.rs runs the binary with a throwaway HOME and checks that --cache-dir, MITTS_CACHE_DIR and XDG_CACHE_HOME relocate all stores together.
  • scripts/run_tests_isolated.sh runs the suite in a clean room and fails if the real ~/.cache/mitts changed; scripts/probe_store_isolation.sh finds any target that still uses the default store.

Verified on Linux: 670 tests passed, 0 failed, clippy clean, line coverage 87.2 %.

Full history: https://github.com/alex09x/mitts/compare/v0.2.1...v0.3.0

v0.2.1

· Mitts 0.2.1

Mitts 0.2.1 refines the native Rust action-key model, CAS artifact naming, single-flight compile locking, and the unified T0–T5 cross-filesystem benchmark harness (XFS, ext4, and macOS APFS).

Engine and cache (src/adapter/rust/)

  • Fine-grained dep-info input keying (14084e4, 82295e3):
    • Units without impure proc-macros are keyed by crate root (unit.src_path), common build inputs, and the exact files recorded by rustc / build.rs in .d dep-info rather than hashing the entire package tree.
    • Cargo.lock and non-build manifest metadata fields (description, readme, documentation, homepage, repository, keywords, categories, authors) are excluded from unit action keys, so edits to non-compiled files, tests/, benches/, or docs no longer invalidate library/binary units.
  • Result-keyed CAS artifact naming (0b5bbfc):
    • Shared CAS artifacts (-C metadata / extra_filename) are named by the fine-grained result_key rather than the coarse action key, eliminating StableCrateId collisions when units share a coarse action key across different .d dep-info inputs.
  • Build-script key normalization (2ca59e6, 3d37500):
    • Empty [target.*] tables left after stripping dev-dependencies are dropped from normalized manifests.
    • Test-only manifest tables ([[bench]], [[test]], [[example]], [dev-dependencies]) are excluded from build.rs action keys, so benchmark/test/doc-only commits hit the CAS without re-executing build.rs.
  • Source-aware single-flight compile lock (4e262ae):
    • Cross-process single-flight compilation locks include the crate root's directory tree (src/), preventing false serialization across concurrent worktrees checked out at different commits in T5.

Unified T0–T5 Benchmark Suite (scripts/)

  • Interleaved S1 cold-build arms with rotation and fresh mtimes (copy_repo_tree) for fair incremental comparisons (a12b531).
  • Linux PSI CPU pressure sampling (cpu_some_avg10), NOISY variance gate (<= 15% spread across sound arms), and INVALID_L5 / INVALID_T5 soundness gates with status_flags tracking (83dce9d, be1ecef, aa51e8a, 6e7814c).
  • #![no_std]-compatible L5b clippy anomaly injection ("a".len() == 0) (be1ecef).
  • Automatic RLIMIT_NOFILE promotion (65536) on macOS so 12-worktree sccache swarms do not exhaust the default 256-FD soft limit (aa51e8a), plus rlimit_nofile_soft, sched_pri, and nice provenance recording (1a9d383).

Full history: https://github.com/alex09x/mitts/compare/v0.2.0...v0.2.1

v0.2.0

· Mitts 0.2.0

Mitts 0.2.0 is the first release built on the native engine. Mitts plans the Cargo workspace itself and calls rustc directly. Each compile action is keyed by its full set of inputs and stored once in a machine-wide immutable cache. Any workspace, worktree or branch that needs the action restores it from there.

This release is meant to be tested against. It is not published to crates.io.

Engine and cache

  • Native DAG executor. Mitts calls rustc directly and pipelines on .rmeta. A managed jobserver keeps build scripts and compilers inside one shared token pool.
  • Path-independent action keys for workspace crates and pure proc-macros. Worktrees and clones of the same commit share artifacts.
  • Package identity is (name, version, source). Two packages with the same name and version from different sources no longer collide.
  • Per-unit input tracking. Inputs come from dep-info extras and dynamic keys for transitively dependent units. Unknown or unhashable inputs fail closed and the unit is rebuilt.
  • Build-script results are cached in the content-addressed store. OUT_DIR purity is checked against the unit's dep-info, and cached entries are read-only.
  • Fast no-op path. A clean rebuild with no changes skips planning when every tracked input is unchanged.
  • target/mitts/ is the only directory Mitts writes to. The Cargo registry is read-only. Fetched sources are published atomically into Mitts' own store.

Commands

  • build / check / clippy
    • Cargo package, target and feature selectors, --workspace and --all-targets.
    • check emits metadata only for non-host units.
    • clippy runs the driver and user arguments on primary targets only, including the package's build.rs.
  • test
    • Integration tests, custom harnesses (harness = false), doctests, filters, runner arguments.
    • --workspace and --exclude.
    • Cargo-compatible CARGO_BIN_EXE_<name> and CARGO_TARGET_TMPDIR.
  • run. Honours default-run, sets the Cargo package environment and the dynamic-library search path.
  • coverage. Respects workspace selection and --no-fail-fast.
  • fmt. Formats target roots only and inherits each package's edition.
  • explain. Shows the plan and action keys (--keys) and why a unit missed the cache.
  • fetch.
    • Parallel download and unpack into Mitts' own store, with an atomic .mitts-ok publish.
    • Git dependencies without a local checkout are reported as errors instead of being built from crates.io sources.
  • gc.
    • Builds, tests, runs and coverage hold a cache-wide lease, so the collector never prunes artifacts in use.
    • Temporary files are only removed after an age threshold.
  • clean. Deletes only directories carrying Mitts' ownership marker. It refuses /, $HOME, the project and workspace roots and their ancestors.

Cargo compatibility

  • Profiles: opt-level, debug, debug-assertions, overflow-checks, panic, lto, rpath, with separate host and target settings.
  • Flags: RUSTFLAGS / CARGO_ENCODED_RUSTFLAGS, [build] and [target.<cfg>] rustflags, [env], and the .cargo/config* chain.
  • Workspace inheritance: virtual workspaces, inherited check-cfg and lints, CARGO_PKG_RUST_VERSION.
  • Features (resolver 2): host and target decoupling, weak and optional dependencies, target-specific and dev-dependencies, renamed and multi-version dependencies.

Known limitations

  • No incremental compilation inside a crate. Editing a large crate in a single worktree can be slower than cargo with incremental compilation enabled.
  • Disk use on filesystems without reflink support (for example ext4) is higher than Cargo's, because artifacts are copied into both the cache and each workspace.
  • Some Cargo configuration keys are rejected rather than ignored. [env], target.<triple>.linker and target.<triple>.runner in any applicable .cargo/config.toml, including the global one, stop the build with an Unsupported build option error, because Mitts cannot track them yet.
  • Linux is the reference platform. macOS is being validated against this release.

Full history: https://github.com/alex09x/mitts/compare/v0.1.1...v0.2.0

Release history from GitHub as of 2026-11-06.