Skip to content

Migrate aaron off Determinate Nix to Lix #154

Description

@etrobert-bot

Plan: Migrate aaron off Determinate Nix to Lix

Status: not started — execution plan.

Why

Determinate Nix on aaron creates ongoing darwin/Linux divergence that
compounds with every new piece of system tooling:

  • nix.enable = false is required because Determinate manages the daemon.
  • nix.settings is ignored; custom settings must go in
    /etc/nix/nix.custom.conf (see aaron/configuration.nix:32).
  • Determinate owns post-build-hook at
    /nix/var/determinate/post-build-hook.sh, blocking simple post-build-hook
    use (e.g., Phase 2 of the cachix-push effort —
    cachix-push-from-aaron.md).
  • Known unresolved hang bug on macOS:
    DeterminateSystems/nix-installer#1500.

What we give up by leaving Determinate:

  • Parallel evaluation (faster nix flake check, evals).
  • Lazy trees (faster + less disk for some workloads).
  • Native Linux builder on macOS via Apple Virtualization framework.
  • determinate-nixd-managed automatic GC and Keychain integration.
  • Build-time flake inputs.

None are load-bearing for this setup: aaron rarely builds Linux derivations
(tower/leod + CI cover that), and GC/auth can be replicated with nix-darwin
options. Parallel eval and lazy trees are real perf wins but aren't in any
non-Determinate distribution today, so any migration loses them.

Approach

Replace Determinate Nix on aaron with Lix (community fork, drop-in for
upstream Nix from a config-semantics standpoint). Flatten
aaron/configuration.nix to use the same nix.settings interface as the
Linux hosts.

Why Lix specifically

  • nix-darwin upstream recommends Lix on macOS specifically because it
    ships a clean uninstaller — vanilla nixos.org Nix does not, and manual
    uninstall on macOS is notoriously painful. Keeping the ability to migrate
    again later matters.
  • Standard nix.conf semantics — no nix.custom.conf, no owned
    post-build-hook, no nix.enable = false. The exact same nix-darwin /
    NixOS option interface works across aaron, tower, and leod.
  • DetSys installer with --no-determinate was deprecated 2026-01-01
    (nix-installer#1622). That path is no longer supported.

Trade-off: Lix is still a fork. But it tracks upstream more closely than
Determinate, and you can switch tower/leod to Lix later with
nix.package = pkgs.lix if you ever want full uniformity.

Step-by-step

1. Pre-flight (do these locally before touching aaron)

  • Confirm no Determinate-only feature is actively used:
    • Run nix config show on aaron; note anything Determinate-specific.
    • Check whether the native Linux builder is enabled — if it is, decide
      whether to re-enable it post-migration via nix.linux-builder (Lix
      supports this via nix-darwin too).
  • Snapshot the current /nix size for comparison: du -sh /nix/store.
  • Confirm cachix push is shipped on tower/leod (PR feat(cachix): auto-push tower/leod builds to soft-nix cache #150). Once Determinate
    is gone, aaron's first rebuild pulls from soft-nix instead of compiling
    from scratch.

2. Code changes (separate PR)

Edit modules/hosts/aaron/configuration.nix:

  • Remove nix.enable = false; (configuration.nix:27).
  • Remove the environment.etc."nix/nix.custom.conf".text block
    (configuration.nix:30-34).
  • Add a nix.settings block (matches what tower/leod use via base.nix):
    nix.settings.trusted-users = [ "root" "@admin" ];
    nix.package = pkgs.lix;
  • Add automatic GC + store optimization to replicate Determinate behavior:
    nix.gc = {
      automatic = true;
      interval = { Hour = 3; };
      options = "--delete-older-than 30d";
    };
    nix.optimise.automatic = true;

Don't merge until the machine-side migration (Step 3) is ready, or vice
versa — these two changes must land together to avoid a broken aaron.

3. Machine-side migration (aaron only)

  1. Uninstall Determinate (wipes /nix, removes the daemon):
    /nix/nix-installer uninstall
  2. Reboot (or launchctl unload any lingering Determinate daemons — the
    uninstaller should handle this).
  3. Install Lix:
    curl -sSf -L https://install.lix.systems/lix | sh -s -- install
  4. Apply the new config:
    nix run nix-darwin -- switch --flake ~/setup

4. Verification

  • nix config show — no nix.custom.conf mention, trusted-users shows
    root @admin.
  • nix --version — reports a Lix version.
  • nix flake check on the setup repo from aaron — clean.
  • darwin-rebuild switch --flake . — succeeds without "Determinate Nix
    manages the daemon" warnings.
  • launchctl list | grep determinate — empty.
  • Build a small package: nix build nixpkgs#hello — succeeds.
  • Touch ID for sudo still works (that's security.pam.services.sudo_local,
    unaffected by the migration).

5. Follow-ups (separate work, not part of this plan)

  • Unblock cachix-push-from-aaron.md — Step 2 (SSE subscriber) can be
    dropped entirely because post-build-hook is now free; the simple
    post-build-hook recipe from cachix docs works directly.
  • Re-enable nix-darwin linux-builder module if you want Linux builds on
    aaron.
  • Consider migrating tower/leod to Lix too (nix.package = pkgs.lix in
    base.nix) for full uniformity — only if you actually want it; today's
    upstream Nix on Linux is fine.

Open questions

  • Does the existing /nix store survive uninstall? No — the Determinate
    uninstaller wipes it. Plan for a full rebuild of aaron's closure. With PR
    feat(cachix): auto-push tower/leod builds to soft-nix cache #150 shipped, most paths pull from soft-nix.cachix.org instead of
    recompiling.
  • Anything bound to determinate-nixd.socket? Confirmed nothing in this
    repo binds to it — the only references are inside this plan and
    cachix-push-from-aaron.md. Safe.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions