Skip to content

fix(bootstrap): parse [bootstrap.linux.firewall] on every OS - #14615

Merged
jdx merged 3 commits into
claude/mise-config-schemafrom
claude/mise-config-cfg-free
Oct 18, 2026
Merged

jdx merged 3 commits into
claude/mise-config-schemafrom
claude/mise-config-cfg-free

Conversation

@jdx

@jdx jdx commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

https://entire.io/gh/jdx/mise/trails/836

[bootstrap.linux.firewall] is now parsed the same way on every platform.

  • Firewall: before this change, only Linux type-checked [bootstrap.linux.firewall]. macOS and Windows kept it as an unchecked map, so a mistake showed up only on the Linux machines that load a shared config. All platforms now parse the typed form. macOS and Windows still skip the section at bootstrap time with the same warning (ignoring [bootstrap.linux.firewall] on non-Linux host), but an invalid value is now an error there too:

    [bootstrap.linux.firewall]
    backend = "iptables"
      Γ— Invalid TOML in config file
     2 β”‚ backend = "iptables"
       Β·           ─────┬────
       Β·                ╰── unknown variant `iptables`, expected one of `auto`, `ufw`, `firewalld`, `nftables`
    
  • brew adopt: test(schema): check schema/mise.json against the config parserΒ #14613 already landed the same change on main (Windows no longer warns about [bootstrap.brew] adopt), so this PR now only carries the firewall part.

This also prepares for generating schema/mise.json from the mise-config types (#14611), because the declaration types no longer depend on the build host.

Validation

  • cargo +1.95 clippy --workspace --all-features --all-targets -- -D warnings
  • cargo check -p mise-config for aarch64-apple-darwin and x86_64-pc-windows-gnu. mise-system can't be cross-compiled here because of its C build scripts, so the macOS and Windows CI jobs cover the one-line firewall_non_linux.rs change.
  • mise-config and mise-system nextest: 750 passed. test_bootstrap_linux_firewall is no longer Linux-only. After merging main, the conformance test from test(schema): check schema/mise.json against the config parserΒ #14613 passes too.
  • The error above is from a debug build.

Stacked on #14611.


πŸ€– Generated with Claude Code

AI-assisted β€” Tool: Claude Code; model: anthropic/claude-opus-5-5; version: 2.1.299.

Summary by CodeRabbit

  • Configuration
    • Firewall settings now use the same validated schema across platforms. Invalid firewall values can cause configuration errors even where firewall changes are not applied.
    • Firewall rules and settings support backend, state, policy, direction, action, protocol, port, and network-interface options.
  • Documentation
    • Clarified that firewall configuration is parsed on macOS and Windows, although firewall application remains Linux-only.

Note

Low Risk
Behavior change is stricter config validation on non-Linux; Linux apply paths are unchanged aside from a simpler presence check.

Overview
[bootstrap.linux.firewall] is now validated on every platform, not only Linux. The typed firewall schema (backends, policies, rules, etc.) lives in a single firewall.rs module instead of Linux-specific types plus a non-Linux β€œraw map” stub.

On macOS and Windows, bootstrap still skips applying the section with the same warning, but invalid TOML (e.g. backend = "iptables") now fails at config load on those hosts tooβ€”so shared configs are checked before they reach Linux.

Non-Linux β€œis firewall configured?” detection no longer probes a generic values map; it only checks whether the parsed section is present. Docs note the cross-platform parse behavior, and test_bootstrap_linux_firewall runs on all targets.

Reviewed by Cursor Bugbot for commit b3530f6. Bugbot is set up for automated code reviews on this repo. Configure here.

@jdx
jdx added this pull request to stack #14612 October 17, 2026 18:24
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack β†’

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 2 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

βš™οΈ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c350c38b-ddb6-4343-969c-4f422cfd18e3
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between af8b49a and b3530f6.

πŸ“’ Files selected for processing: 6
  • crates/mise-config/src/firewall.rs
  • crates/mise-config/src/firewall/linux.rs
  • crates/mise-config/src/firewall/other.rs
  • crates/mise-system/src/firewall_non_linux.rs
  • docs/bootstrap/firewall.md
  • src/config/config_file/mise_toml.rs

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1274b877-5538-45d1-b116-8f272991e21d
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 9ed1fd7 and af8b49a.

πŸ“’ Files selected for processing: 6
  • crates/mise-config/src/firewall.rs
  • crates/mise-config/src/firewall/linux.rs
  • crates/mise-config/src/firewall/other.rs
  • crates/mise-system/src/firewall_non_linux.rs
  • docs/bootstrap/firewall.md
  • src/config/config_file/mise_toml.rs
πŸ’€ Files with no reviewable changes: 2
  • crates/mise-config/src/firewall/other.rs
  • crates/mise-config/src/firewall/linux.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

πŸ“ Walkthrough

The firewall TOML schema is now defined on all platforms with shared typed configuration. Non-Linux configuration detection checks section presence directly. Documentation describes cross-platform parsing, and the systemd bootstrap test runs on all platforms.

Changes: Cross-platform firewall configuration

Layer / File(s) Summary
Shared firewall schema
crates/mise-config/src/firewall.rs, crates/mise-config/src/firewall/linux.rs, crates/mise-config/src/firewall/other.rs
The shared module defines firewall types, defaults, and backend mappings. It replaces the Linux-specific definitions and the non-Linux arbitrary TOML map.
Cross-platform configuration checks
crates/mise-system/src/firewall_non_linux.rs, docs/bootstrap/firewall.md, src/config/config_file/mise_toml.rs
Non-Linux configuration detection checks whether the firewall section is present. Documentation states that the section is parsed on every platform. The systemd bootstrap test is no longer Linux-only.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Suggested reviewers: marukome0743

Merge Risk: βšͺ Minimal Β· up to af8b4

This change makes the firewall section parse the same way on every platform, so a bad value now errors on macOS and Windows as well as Linux. No concrete merge-blocking risk was identified in the reviewed changes.

Pre-merge checks: Passed 4 Β· Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 3 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: parsing [bootstrap.linux.firewall] on every operating system.
Full details: Docstring Coverage

Explanation

Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 3 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Autofix Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

[bootstrap.linux.firewall] now uses the same typed parser on every platform.

  • Every host validates the shared Linux firewall settings.

Reviews (6) Β· Last reviewed commit: "Merge branch 'claude/mise-config-schema'..." Β· Reviewed by Greptile

@jdx
jdx force-pushed the claude/mise-config-cfg-free branch from 5b83ebd to 4b4c2f3 Compare October 17, 2026 18:43
@jdx jdx changed the title fix(bootstrap): parse [bootstrap.linux.firewall] and brew adopt on every OS fix(bootstrap): parse [bootstrap.linux.firewall] on every OS Oct 17, 2026
The mise-config declaration types now have no platform cfgs, so a
schema generated from them does not depend on the build host.

- [bootstrap.linux.firewall] used typed fields on Linux and a raw map
  elsewhere. Every platform now parses the typed form. macOS and Windows
  still skip it at bootstrap time with the same warning. An invalid value
  is now an error there too, instead of only on Linux.
- [bootstrap.brew] adopt existed only on Unix, so Windows warned that the
  key was unknown. It is now parsed everywhere and still read only on Unix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M55HQ9WE9984KDKEGZG0E6A4
@jdx
jdx force-pushed the claude/mise-config-cfg-free branch from af8b49a to f3d2912 Compare October 17, 2026 23:14
@jdx
jdx merged commit a586bd2 into main Oct 18, 2026
55 of 82 checks passed
@jdx
jdx deleted the claude/mise-config-cfg-free branch October 18, 2026 03:18
jdx added a commit that referenced this pull request Oct 18, 2026
<!-- entire-trail-link-start -->
https://entire.io/gh/jdx/mise/trails/837
<!-- entire-trail-link-end -->

`[bootstrap]` in `schema/mise.json` is now generated from the Rust types
that parse it, as `[history]` is since #14611. Editors now get the keys
and checks mise actually uses. Generating it found one gap right away:
launchd agents accept `keep_alive_on_failure` and `nice`, but the
hand-written schema didn't list them, so editors flagged both as
unknown.

## Schema changes for users

- **Unknown keys are rejected throughout `[bootstrap]`.** `[bootstrap]`
itself and its `macos`, `linux`, `user`, `brew`, `apt`, `dnf`,
`macos.launchd`, `linux.systemd`, launchd agent and systemd unit tables
used to accept any key in the schema, while mise warned about the
unknown ones. They now reject unknown keys, like the rest of the schema,
so an editor flags typos like this one:

  ```toml
  [bootstrap.user]
login_shel = "/bin/zsh" # now flagged; mise already warned "unknown
field"
  ```

- **New keys:** launchd agents gain `keep_alive_on_failure` and `nice`,
with the rules mise enforces when it builds the agent: `nice` from -20
to 20, and `keep_alive_on_failure` not combined with `keep_alive =
true`.
- **Defaults:** boolean options and `phase` now show their defaults
(`template = false`, `start = true`, …). `[history]` loses the empty
`[]` and `{}` defaults #14611 added.

I validated all 104 `[bootstrap]` TOML examples in `docs/` against the
old and new schema. None that passed before fails now. (`macos-defaults`
example 4 fails both, an existing gap in the hand-written
`macos.defaults` schema.)

## How it is built

- Each typed subsection derives `JsonSchema`. That covers files,
directories, packages, repos, remote, services, compose, secrets,
groups, users, brew, login items, launchd agents, systemd units and the
firewall. Field doc comments are the descriptions, with the existing
text kept. Cross-field rules (`if`/`then`, `oneOf`, `dependentRequired`,
`propertyNames`) are `#[schemars(extend(...))]` attributes on the type
they constrain.
- Fields that stay raw TOML have no type to derive from: `hooks`,
`mise_shell_activate`, apt `sources`, dnf `repos`, and the macOS
`dock`/`finder`/`keyboard`/`trackpad`/`defaults` tables. They keep raw
TOML so newer shapes warn instead of failing. Their hand-written schema
moved unchanged into `$defs` (`bootstrap_hooks`, `bootstrap_macos_dock`,
…), and the generated tree points at it with `$ref`. `config keys`
completion and the `mise edit` editor already follow `$ref`s.
- `bootstrap_remote_install_mise` and `launchd_calendar_interval` stay
in `$defs` and are now generated too.
- `schemars` is a plain dependency of `mise-config`, and the `schema`
feature from #14611 is gone. mise already links schemars through `rmcp`,
and putting `cfg_attr` on every one of these annotations made them hard
to read.
- New generator transforms: strip `null` from `Option` enums and `anyOf`
(TOML has no null), drop empty `[]`/`{}` defaults, drop integer `format`
(`uint16` and similar fail ajv strict mode), and close only `type:
object` schemas, never `if`/`then`/`oneOf` branches.

`[dotfiles]` and `[dotfile_groups]` stay hand-written. `mise-config`
declares them as `IndexMap<String, toml::Value>`, and `mise-system`
parses the entries by hand. A generated schema would move about 630
lines of JSON into the crate without tying it to any parser. That has to
wait until the entry types live in `mise-config`.

## After merging `main` (#14613)

#14613 changed parts of `[bootstrap]` that this PR generates, so its
edits now live in the Rust attributes: the `login_shell`,
`queue_directories` and `umask` patterns, which accept a template, and
the `login_shell` description. Its `macos.defaults` value change is in
`$defs/bootstrap_macos_defaults`, the hand-written part this PR moved.
Its conformance test then flagged the two systemd units in
`e2e/cli/test_bootstrap_unit_templates` that have a deliberate
`exec_startt` typo. mise warns about that typo when it uses the unit,
and the schema now rejects it, so both heredocs are marked `# schema:
invalid`, the test's marker for configs mise reads only with a warning.

## Validation

- `cargo +1.95 clippy --workspace --all-features --all-targets -- -D
warnings`
- `mise-config` and `mise-system` nextest: 750 passed, including
`schema_json_is_up_to_date`. `cargo test -p mise --lib
config::config_file`: 154 passed. `cli::config` tests: 9 passed.
- All 16 `e2e/config/test_schema_*` tests (tombi and ajv) pass, and so
does `schema_matches_parser` from #14613.
- `ajv compile --spec=draft2020 --strict-types=true
--strict-tuples=true` on the schema. `mise run render:schema` is
idempotent.

Stacked on #14615.

---

πŸ€– Generated with [Claude Code](https://claude.com/claude-code)

*AI-assisted β€” Tool: Claude Code; model: anthropic/claude-opus-5-5;
version: 2.1.299.*

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Large schema surface area affects editor validation and CI conformance
tests; runtime parsing is unchanged but users may see new diagnostics
for unknown keys or previously undocumented fields.
> 
> **Overview**
> **`[bootstrap]` in `schema/mise.json` is now generated from
`crates/mise-config` parser types** (same pipeline as `[history]`), so
editor validation and completions track what mise actually parses. Field
doc comments on those types become schema descriptions; cross-field
rules live in `#[schemars(...)]` on the Rust structs.
> 
> Raw-TOML areas (`hooks`, `mise_shell_activate`, apt/dnf repo tables,
macOS dock/finder/etc.) stay hand-written under `$defs` and are wired in
via `$ref` from the generated tree. The `mise-config` **`schema` Cargo
feature is removed**β€”`schemars` is always a dependencyβ€”and schema
generation adds transforms (strip nulls, drop empty defaults, `oneOf` vs
`anyOf`, tighter `additionalProperties` on objects).
> 
> **User-visible schema behavior:** most `[bootstrap]` tables now
**reject unknown keys** (editors flag typos mise already warned about).
Launchd agents gain documented **`keep_alive_on_failure`** and
**`nice`** with the same mutual-exclusion/range rules as the runtime.
Boolean defaults and similar show up in the schema; `[history]` loses
noisy empty collection defaults.
> 
> E2E configs that deliberately contain invalid keys for warning-only
tests are marked `# schema: invalid`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
809ea73. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Expanded configuration schema coverage across bootstrap, accounts,
packages, services, systemd, launchd, Compose, and other settings, with
clearer descriptions, defaults, and validation constraints.
* Schema generation is now available without an optional feature setting
and includes additional bootstrap, history, and launchd scheduling
definitions.
* Configuration schemas now preserve hand-written definitions referenced
by generated schemas.

* **Documentation**
* Clarified configuration guidance and descriptions, including
requirements for managed files, login items, and generated
configuration.
* Updated architecture documentation to identify bootstrap and history
as schema-generated sections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Instruction counts

The comparison never ran β€” an earlier step failed.

b3530f6754f4 vs `` Β· measured on the runner, not pushed to the history.

jdx pushed a commit that referenced this pull request Oct 18, 2026
<!-- entire-trail-link-start -->
https://entire.io/gh/jdx/mise/trails/826
<!-- entire-trail-link-end -->

### πŸš€ Features

- **(backend)** reject tool options a backend does not read by @jdx in
[#14629](#14629)
- **(config)** let env_file take several filenames by @jdx in
[#14606](#14606)
- **(config)** add config.override.toml so global config can override
project config by @jdx in
[#14610](#14610)
- **(config)** let paranoid take a list of categories by @jdx in
[#14609](#14609)
- **(env)** let a find_up env._.file entry search several names together
by @jdx in [#14620](#14620)
- **(task)** read #MISE headers through TaskDecl by @jdx in
[#14637](#14637)

### πŸ› Bug Fixes

- **(activate)** stop fish not-found recursion after mise implode by
@jdx in [#14594](#14594)
- **(bootstrap)** find nix installed by a pre-packages hook by @jdx in
[#14596](#14596)
- **(bootstrap)** parse [bootstrap.linux.firewall] on every OS by @jdx
in [#14615](#14615)
- **(cargo)** honor rename_exe for cargo-installed tools by @jdx in
[#14626](#14626)
- **(config)** require content-bound trust for env files in paranoid
mode by @jdx in [#14604](#14604)
- **(hooks)** don't report git rewrites when HEAD stayed on the same
commit by @JamBalaya56562 in
[#14585](#14585)
- **(npm)** report an unusable TLS root store instead of aborting by
@jdx in [#14595](#14595)
- **(pipx)** bind the real python for locked uv installs by @jdx in
[#14593](#14593)
- **(rust)** don't put an external rustup's directory ahead of mise's
tools by @jdx in [#14597](#14597)
- **(schema)** generate [bootstrap] from its parser types by @jdx in
[#14616](#14616)

### 🚜 Refactor

- **(config)** move doctor, tool_config, watch_files and wrappers into
mise-config by @jdx in [#14617](#14617)
- **(config)** move the oci and daemons declarations into mise-config by
@jdx in [#14618](#14618)
- **(config)** move alias, min_version and monorepo into mise-config by
@jdx in [#14627](#14627)
- **(config)** declare [tools] in mise-config, keyed by string by @jdx
in [#14631](#14631)
- **(config)** parse mise.toml through MiseTomlDecl by @jdx in
[#14638](#14638)
- **(env)** move env directives and the [env] parser into mise-config by
@jdx in [#14621](#14621)
- **(task)** move the task declaration field types into mise-config by
@jdx in [#14622](#14622)
- **(task)** split TaskDecl from Task by @jdx in
[#14624](#14624)
- rename mise-system-config to mise-config by @jdx in
[#14608](#14608)

### πŸ“š Documentation

- **(env)** explain env_file and _.file find_up are different features
by @jdx in [#14602](#14602)

### ⚑ Performance

- **(dotfiles)** build snapshot trees without a git process per tracked
file by @waynehoover in [#14607](#14607)

### πŸ§ͺ Testing

- **(npm)** install a popular package in the dependency check by @jdx in
[#14633](#14633)
- **(schema)** check schema/mise.json against the config parser by @jdx
in [#14613](#14613)

### πŸ“¦οΈ Dependency Updates

- bump mbx to 1.24.1 by @jdx in
[#14635](#14635)

### Chore

- **(schema)** generate the [history] schema from mise-config by @jdx in
[#14611](#14611)
- **(schema)** generate the task schema from TaskDecl and TaskTemplate
by @jdx in [#14625](#14625)
- **(schema)** generate the whole schema from a top-level MiseTomlDecl
by @jdx in [#14632](#14632)

### Ci

- restore the nextest timeout for the mise-oci blob test by @jdx in
[#14619](#14619)
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.

1 participant