v2026.8.2
abus-aikorea/voice-prov2026.8.2Aug 5, 2026by mise-en-dev
AI Summary
Turns `mise bootstrap` into a Terraform-style declarative system for host provisioning, enabling remote execution over SSH, while also enforcing strict precompiled-only mode for Ruby and fixing lockfile issues.
Key Highlights
- Terraform-style declarative model with plan/apply/status workflows for resources.
- Provisioning capabilities for privileged files, users, groups, systemd services, Docker Compose projects, and firewall rules.
- Remote provisioning over SSH with automatic OS and architecture detection.
Breaking Changes
- `ruby.compile = false` is now a strict precompiled-only mode (no fallback to ruby-build).
- `task.auto_infer` is now opt-in instead of running whenever experimental features are enabled.
New Features
- Bootstrap resource management (files, directories, users, groups, systemd, compose, firewall).
- SSH remote bootstrap with signature-verified binary downloads.
- Secret handling via environment variables for managed files.
- Lockfile fixes and improved package handling (brew, pacman).
Full Release Notes
This release turns `mise bootstrap` into a full declarative host-provisioning system: alongside packages, mise can now converge privileged files, Linux users and groups, systemd services, Docker Compose projects, and firewall rules — all with plan/apply/status workflows, secret handling, and the ability to run over SSH against remote hosts. It also makes Ruby's `ruby.compile=false` a strict precompiled-only mode and lands a batch of install and lockfile fixes.
## Highlights
- `mise bootstrap` gains a Terraform-style declarative model. A new `mise bootstrap plan` previews changes with table or JSON output and detailed exit codes, and each resource type has its own `apply`/`status` commands that converge only when something actually differs.
- Bootstrap can now provision far more than tools and packages: privileged files and directories, Linux accounts, systemd services, Compose projects, and host firewall rules, with dependency ordering, fail-closed safety checks, and secret inputs sourced from environment variables (never stored in config).
- The same bootstrap project can be applied to remote machines over SSH via `mise bootstrap remote`, including automatic detection of the target's OS/arch/libc and signature-verified download of the matching mise binary.
## Added
- **bootstrap:** declarative resource plans. `mise bootstrap plan` previews what bootstrap would change before applying, with table or `--json` output and optional `--detailed-exitcode` (0 = no changes, 2 = changes, 1 = error). Resources have stable identities, dependency graphs, and validation for duplicates, missing dependencies, and cycles. ([#11669](https://github.com/jdx/mise/pull/11669) by @jdx)
- **bootstrap:** manage privileged files and directories via `[bootstrap.files]` and `[bootstrap.directories]`, with content (inline or from a source), ownership, mode, and explicit `present`/`absent` state. Writes are atomic, removal is opt-in (and requires `recursive = true` for non-empty directories), and privileged work runs through hidden helpers that never expose file content in argv or logs. ([#11674](https://github.com/jdx/mise/pull/11674) by @jdx)
- **bootstrap:** secret inputs for managed files. `[bootstrap.secrets]` references sensitive values through environment variables so nothing is stored in config, and managed files with `template = true` can render them via `{{ secret(name="...") }}`. `mise bootstrap secrets status` reports availability without revealing values, and `--prompt-secrets` prompts securely for anything missing. ([#11680](https://github.com/jdx/mise/pull/11680) by @jdx)
- **bootstrap:** manage Linux users and groups via `[bootstrap.users]` and `[bootstrap.groups]`, with create/update/remove, supplementary groups, home handling, and explicit `state = "absent"`. Accounts converge before the files that reference them, and UID/GID collisions fail closed. ([#11681](https://github.com/jdx/mise/pull/11681) by @jdx)
- **bootstrap:** manage Linux systemd services via `[bootstrap.services]` for running/stopped, enabled/disabled, and masked state. Managed files and directories can set `notify` to trigger `reload`, `restart`, or `reload_or_restart` handlers, but only after a real file change. ([#11688](https://github.com/jdx/mise/pull/11688) by @jdx)
- **bootstrap:** manage Docker Compose projects via `[bootstrap.compose]` for running, stopped, and absent states, with pull/build/recreate/wait policies, one-shot services, orphan/volume/image removal, and explicit dependencies. Convergence compares live container runtime and health to the rendered Compose model (Compose v2 only). ([#11689](https://github.com/jdx/mise/pull/11689) by @jdx)
- **bootstrap:** manage Linux host firewall rules via `[bootstrap.linux.firewall]` with nftables, firewalld, and UFW backends (`backend = "auto"`). Includes SSH-lockout protection (default-deny requires a covering allow rule or `allow_lockout = true`), drift detection, and preservation of undeclared rules unless `exclusive` is set. ([#11694](https://github.com/jdx/mise/pull/11694) by @jdx)
- **bootstrap:** run bootstrap over SSH with `mise bootstrap remote`, targeting a named `[bootstrap.remote.hosts]` inventory or ad-hoc `user@host` targets. mise archives and stages your project, provisions a compatible mise binary on the host, runs bootstrap with forwarded flags, and cleans up staging afterward. ([#11690](https://github.com/jdx/mise/pull/11690) by @jdx)
- **bootstrap:** remote provisioning now detects each target's OS, architecture, and Linux libc (glibc vs musl) and, when the local binary is not compatible, downloads the matching raw executable for the same release from GitHub with minisign-verified checksums. Custom or debug builds fail closed and require an explicit `mise_bin`, `remote_mise`, or `bootstrap_command`. ([#11693](https://github.com/jdx/mise/pull/11693) by @jdx)
## Changed
- **ruby:** `ruby.compile = false` is now a strict precompiled-only mode, matching `python.compile`. Installs error with `no precompiled ruby found` instead of silently falling back to ruby-build, and version listings (`mise ls-remote ruby`, fuzzy resolution) are filtered to versions that actually have a precompiled binary for your platform. Previously `false` was a no-op after precompiled binaries became the default in 2026.8.0. Unset and `compile = true` are unchanged; Windows is unaffected. ([#11710](https://github.com/jdx/mise/pull/11710) by @jdx)
- **task:** workspace task inference is now opt-in per provider via `task.auto_infer` (e.g. `task.auto_infer = ["node"]`) instead of running whenever experimental features are enabled. Explicit mise tasks always take precedence over inferred package scripts on name and alias collisions. ([#11706](https://github.com/jdx/mise/pull/11706) by @jdx)
## Fixed
- **brew:** `:any_skip_relocation` bottles no longer leave unresolved `@@HOMEBREW_*@@` placeholders in scripts and config files. That tag now only skips binary linkage relocation while text placeholders are still replaced. ([#11665](https://github.com/jdx/mise/pull/11665) by @jdx)
- **brew-cask:** detect extensionless DMG downloads (such as Raycast) by their UDIF trailer instead of treating them as raw executables and failing to find the app bundle. ([#11692](https://github.com/jdx/mise/pull/11692) by @jacobbednarz)
- **lock:** `mise lock --bump` now errors instead of writing an incomplete lockfile when a version bump would drop platform coverage that the previous locked version had. Best-effort skips are retained for platforms a tool never supported. ([#11664](https://github.com/jdx/mise/pull/11664) by @jdx)
- **pipx:** release-age gating now uses PyPI's precise RFC3339 `upload_time_iso_8601` timestamp instead of the timezone-naive `upload_time`, which previously made freshly released packages appear up to ~24h younger and over-gated them under `minimum_release_age`. ([#11662](https://github.com/jdx/mise/pull/11662) by @Guria)
- **pacman:** `pacman -Q` is now parsed under `LC_ALL=C` so missing-package detection works in non-English locales; previously `[bootstrap.packages]` could bail on a translated "was not found" message. ([#11673](https://github.com/jdx/mise/pull/11673) by @rarandeyo)
- **sync:** clear stale `incomplete` markers when an external link (from uv, nvm, pyenv, nodenv, or Homebrew) is confirmed healthy, so `mise where` no longer treats a working external version as incomplete after an interrupted install. ([#11172](https://github.com/jdx/mise/pull/11172) by @risu729)
- **completions:** an explicit `--` no longer hijacks task argument completion after usage v5. `mise run <task> -- <TAB>` again offers the task's declared choices instead of falling back to filenames, while still forwarding extra arguments. ([#11711](https://github.com/jdx/mise/pull/11711) by @jdx)
- **registry:** shim auto-install uses new declared `bins` metadata to pick the correct provider before falling back to incidental executables, fixing cases where invoking the `npm` shim could run Node's bundled npm instead of the configured npm version. ([#11666](https://github.com/jdx/mise/pull/11666), [#11671](https://github.com/jdx/mise/pull/11671), [#11676](https://github.com/jdx/mise/pull/11676), [#11677](https://github.com/jdx/mise/pull/11677), [#11678](https://github.com/jdx/mise/pull/11678) by @jdx)
## New Contributors
* @jacobbednarz made their first contribution in [#11692](https://github.com/jdx/mise/pull/11692)
* @rarandeyo made their first contribution in [#11673](https://github.com/jdx/mise/pull/11673)
**Full Changelog**: https://github.com/jdx/mise/compare/v2026.8.1...v2026.8.2
## 💚 Sponsor mise
mise is maintained by [@jdx](https://github.com/jdx), an open source developer for [**entire.io**](https://entire.io), the title sponsor of the [jdx.dev](https://jdx.dev) open source tools. Development is funded by sponsors.
If mise saves you or your team time, please consider sponsoring at [jdx.dev](https://jdx.dev/sponsors.html). Individual and company sponsorships keep mise fast, free, and independent.