Skip to content

nix(darwin): run activation scan + first-enable sweep via postActivation - #22

Merged
ak2k merged 1 commit into
mainfrom
fix/darwin-activation-scan
Jul 9, 2026
Merged

nix(darwin): run activation scan + first-enable sweep via postActivation#22
ak2k merged 1 commit into
mainfrom
fix/darwin-activation-scan

Conversation

@ak2k

@ak2k ak2k commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Problem

nix-darwin, unlike NixOS, has no generic activation-script dag: its activate script splices only a fixed, enumerated set of script names (preActivationpostActivation). A custom system.activationScripts.<name> evaluates fine but is silently never run.

The darwin module registered system.activationScripts.machokeeper.text, so on darwin:

  • ✅ the post-build hook worked
  • ❌ the activation scan (scan-generation of the generation delta) never ran
  • ❌ the one-time first-enable full-store sweep never ran

i.e. two of the module's three darwin doors were inert. (NixOS was unaffected — its system.activationScripts.<name> is generic, which is also why the NixOS VM test passed and this slipped through.)

Found while adopting machokeeper on a real nix-darwin host (retiring the NixOS/nix#15638 patched daemon): the /nix/var/machokeeper/.swept marker never appeared and machokeeper was absent from /run/current-system/activate. A subsequent read-only doctor --scan found 46 pre-existing broken files, confirming the sweep genuinely wasn't running.

Fix

Append the repair snippet into system.activationScripts.postActivation.text via lib.mkAfter — a slot nix-darwin actually runs, still before the current-system symlink flips, with $systemConfig already in scope.

Test

New darwin-only eval check nix/module-darwin-test.nix: builds a darwinSystem with the module and greps the assembled activate script (config.system.activationScripts.script.text) for the scan + sweep, failing if a future change drops them again. Wires in nix-darwin as a check-only flake input.

Verified red-before-green (fails on the pre-fix custom-key module) and green after. Full gate on aarch64-darwin: nix flake check all-pass (incl. the new check), nix build .#default, go vet + go test -race ./....

nix-darwin's `activate` splices only a fixed, enumerated set of
activationScripts names (preActivation … postActivation), with no
generic dag like NixOS. The module's custom
`system.activationScripts.machokeeper` therefore evaluated fine but was
silently never run on darwin: the post-build hook worked, but the
activation scan and the one-time first-enable full-store sweep did not
fire at all.

Append the repair snippet into `system.activationScripts.postActivation`
via lib.mkAfter — a slot nix-darwin actually runs, still before the
current-system symlink flips. Add a darwin-only eval check
(nix/module-darwin-test.nix) that greps the assembled activate script
for the scan and sweep and fails if a future change drops them again;
wire in nix-darwin as a check-only flake input.
@ak2k
ak2k merged commit 96ee9d6 into main Jul 9, 2026
8 checks passed
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