The macOS job named 36 of the recorder's 731 tests by the module paths of its macOS sources. Its
tests are platform-neutral by module but worded in cfg!(target_os = "macos") branches (the options of a
recording, the keys of the viewer, the frames), so a Linux or Windows run takes the other side of
each and only a Mac takes this one, and a filter by name left most of that untested and would go stale
with every module. It runs the whole suite now: it compiles the same test binary the filter needed and
adds about 30 s of tests. In a depth-1 git checkout, as the runner has, all 731 pass (3 skip by design).
The filterset recorder-macos of tools/test-partition is gone with its use.
The test window and the agent of the e2e guests (class tool) have macOS sources (AppKit, the
accessibility API) that no other job compiles, and the tests of the test window's command line ran
nowhere. The job runs their tests and clippy.
With the os_sensitive step before it, every class of tools/test-partition that has macOS tests has a
run on a Mac: the macOS packages (macos-nextest), os_sensitive, the mixed ones (komorebi-client and
komorebi-bar in macos-nextest, the recorder whole) and tool.
Packages whose tests depend on the OS are in the class os_sensitive of
tools/test-partition.json, and a test of one can only pass on the host whose
behaviour it checks. windows-native-test runs them on Windows because the
Linux run cannot stand in for it. macos-hosted did not: macos-nextest builds
with -p of the macOS packages, so komorebic-core, whose docs_cli test
compares docs/macos/cli with what the macOS command line renders, ran on
no Mac in CI, and relied on the Linux run until the wording of Class
differed per platform (run 42311003287).
macos-hosted now runs `cargo nextest run` of the os_sensitive packages in the
native dev shell (92 tests; they pass on a Mac, checked locally). The cost is
macOS minutes on a public repository, which are free, and a compile of four
crates and their dependencies, a few minutes without a cache. docs/dev/ci.md
says so.
A README for e2e/platforms/tart_macos: what a run does, why the grants live in the golden image and
are inherited through Terminal, why the agent is a Rust program (the stock image has no developer
tools), and the limits (one display, no input, two guests per host, Apple hardware only, so not in
CI). docs/dev/ci.md and e2e-to-unit.md said macOS had no integration coverage; they now say where it
runs and what it cannot reach.
The step ran `cargo nextest` in `nix develop`, whose default shell exports
CARGO_BUILD_TARGET=x86_64-pc-windows-msvc for the Windows cross build. On the
macOS runner that made cargo build the recorder's test executables for Windows,
and nextest then failed to list them:
for `komorebi-recorder::assert`, command `.../target/x86_64-pc-windows-msvc/debug/deps/assert-ce31ab528bf795df.exe --list --format terse`
exited with exit code 126 ... cannot execute binary file
Use `nix develop .#native`, the shell without the cross environment that exists
for exactly these `cargo -p komorebi-<platform>` commands. The schemas step
keeps the default shell: `just jsonschema` runs cargo through `env -u
CARGO_BUILD_TARGET`. docs/dev/ci.md notes the shell.
macos-14 was retired on 2 November 2026 and the runner label was no longer
supported, so macos-hosted was cancelled and failed required.
Only Apple silicon and the latest macOS are supported, and a standard hosted
runner is free on a public repository, so:
- macos-hosted runs on macos-latest
- it runs on a pull request that touches the macOS paths, without the label
ci:macos
- it needs only changes and lint, like windows-native-test, and no longer
waits for the KDE VM suites
- macos-selfhosted.yaml, its install-nix input, its path filter, the label
ci:macos-self and the variable MACOS_SELF_HOSTED are removed
The write token goes to cachix-action on a push (master and the temporary komomono
trigger, without naming either), a manual run and a schedule; a pull request, a fork
and the merge queue only read. The flake-lock update goes through the nix action too,
and the nixpkgs canary reads the cache but never pushes (push: "false" replaces
cache: "false").
docs(ci): the write rule, the read-only path and a checklist for the first push to
komomono.
The tools of stage 0 are the latest releases, taken from the flake, and the code is changed to satisfy
them, not the other way round: every run says which versions it had, and docs/dev/ci.md says how they
are kept current (the weekly lock update, and nix flake update rust-overlay or nixpkgs in between).