Skip to content

feat(infra): nix-darwin linux-builder for local x86_64-linux ISO builds on Apple Silicon#4906

Merged
AceHack merged 4 commits into
mainfrom
feat/nix-darwin-linux-builder-config-2026-05-24
May 25, 2026
Merged

feat(infra): nix-darwin linux-builder for local x86_64-linux ISO builds on Apple Silicon#4906
AceHack merged 4 commits into
mainfrom
feat/nix-darwin-linux-builder-config-2026-05-24

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 25, 2026

Summary

Adds `infra/nix-darwin/` + wires `darwinConfigurations.zeta-mac` into `flake.nix`. After this lands, any maintainer with Nix installed on an Apple Silicon Mac runs one command:

```bash
nix run nix-darwin/master#darwin-rebuild -- switch \
--flake /path/to/Zeta#zeta-mac
```

…and gets a working linux-builder VM. From then on `nix build .#installer-iso` from the repo root builds the x86_64-linux ISO locally via Apple's Virtualization.framework + Rosetta 2 — no Parallels, Lima, Docker, or remote builders.

Why this exists

The installer ISO target is `x86_64-linux`. Apple Silicon is `aarch64-darwin`. Nix can't cross-compile a NixOS system natively — it needs a real Linux build environment. Three local-Mac paths exist (Lima, Colima, OrbStack, nix-darwin linux-builder); nix-darwin's linux-builder is the most Mac-native (Apple's own VM framework, Rosetta-accelerated, tightly integrated with Nix).

Files

File Purpose
`infra/nix-darwin/configuration.nix` The actual config: `nix.linux-builder.enable = true`, sizing (8GB RAM, 40GB disk, 6 cores), `extra-platforms = [ "x86_64-linux" ]`, trusted-users = @admin, baseline package set
`infra/nix-darwin/README.md` Prerequisites, setup command, troubleshooting, "what this is NOT"
`flake.nix` Adds `inputs.nix-darwin` pinned to master + `darwinConfigurations.zeta-mac`

Composes with

Test plan

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

…SO builds on Apple Silicon

Adds infra/nix-darwin/ + wires darwinConfigurations.zeta-mac into
flake.nix. After this lands, any maintainer with Nix installed on
an Apple Silicon Mac runs one command:

  nix run nix-darwin/master#darwin-rebuild -- switch \
    --flake /path/to/Zeta#zeta-mac

…and gets a working linux-builder VM. From then on
`nix build .#installer-iso` from the repo root builds the
x86_64-linux ISO locally via Apple Virtualization.framework +
Rosetta 2 — no Parallels, Lima, Docker, or remote builders.

infra/nix-darwin/configuration.nix:
  - nix.linux-builder.enable = true with maxJobs=4, 8GB RAM,
    40GB disk, 6 cores (sized for the installer ISO closure)
  - ephemeral = false to keep VM warm across reboots
  - nix.settings.extra-platforms = [ "x86_64-linux" ] so Nix
    routes x86_64-linux derivations to the VM
  - nix.linux-builder.supportedFeatures = [ kvm benchmark
    big-parallel ] so heavy builds dispatch correctly
  - experimental-features = nix-command + flakes
  - trusted-users = @admin (wheel group on macOS)
  - cache.nixos.org + nix-community substituters trusted
  - Baseline package set mirrors a subset of the installer USB
    (kubectl, helm, k9s, argocd, age, sops, jq, yq, ripgrep,
    fd, htop, gh, git, nix-output-monitor, nvd, nh)
  - system.stateVersion = 5 (current nix-darwin module API)

infra/nix-darwin/README.md:
  - Prerequisites (Apple Silicon, macOS 13+, Nix, Rosetta 2)
  - One-command setup
  - Build the ISO post-setup
  - Update procedure
  - Troubleshooting table
  - Explicit "what this is NOT" — not a NixOS host config,
    not required for cluster operation, not a replacement for
    the CI build (workflow at .github/workflows/build-installer-iso.yml
    stays source of truth for "this PR's ISO")

flake.nix:
  - Adds inputs.nix-darwin pinned to master (project has no
    stable release channel as of 2026-05; matches nix-darwin
    team's recommendation)
  - inputs.nix-darwin.inputs.nixpkgs.follows = "nixpkgs" to
    keep one nixpkgs revision across the whole flake
  - darwinConfigurations.zeta-mac wired with
    specialArgs = { inherit inputs; }

Composes with #4905 (CI workflow that builds the ISO without
needing local Nix). Local linux-builder is the iteration path;
CI is the source-of-truth path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 03:25
@AceHack AceHack enabled auto-merge (squash) May 25, 2026 03:25
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a nix-darwin configuration under infra/nix-darwin/ and wires it into flake.nix as darwinConfigurations.zeta-mac, enabling maintainers on Apple Silicon macOS to use nix-darwin’s linux-builder VM to build the repo’s x86_64-linux installer ISO locally.

Changes:

  • Add nix-darwin workstation configuration enabling nix.linux-builder + Rosetta-backed extra-platforms = [ "x86_64-linux" ].
  • Document the intended maintainer workflow (one-command setup, ISO build, troubleshooting) in infra/nix-darwin/README.md.
  • Extend flake.nix with a nix-darwin input and a darwinConfigurations.zeta-mac output.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
infra/nix-darwin/README.md Documents prerequisites and setup/build workflow for nix-darwin linux-builder on Apple Silicon.
infra/nix-darwin/configuration.nix Implements the nix-darwin config enabling linux-builder, caches, trusted users, and baseline tools.
flake.nix Adds nix-darwin flake input and exports darwinConfigurations.zeta-mac to apply the workstation config.

Comment thread infra/nix-darwin/README.md Outdated
Comment thread infra/nix-darwin/README.md Outdated
Comment thread infra/nix-darwin/README.md
Comment thread infra/nix-darwin/configuration.nix Outdated
Comment thread infra/nix-darwin/configuration.nix Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 980db14858

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread infra/nix-darwin/README.md
Lior and others added 2 commits May 24, 2026 23:28
…as list

infra/nix-darwin/README.md line 50 wrapped a sentence as:

  First build takes ~10-15 min (downloads + boots the linux-builder VM
  + compiles the Linux closure). Subsequent builds reuse the warm VM
  and the /nix/store cache — typically 1-3 min.

markdownlint reads the line starting with "+ compiles" as a list
item (CommonMark unordered-list marker), then complains the list
isn't surrounded by blank lines (MD032).

Rewrote the sentence so no wrapped line starts with `+` (or `-` or
`*`). No content change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex P1 — installer-iso not buildable on Apple Silicon
  The whole point of this PR was that nix-darwin's linux-builder
  lets Apple Silicon Macs run `nix build .#installer-iso`. But the
  flake gated installer-iso to system == "x86_64-linux" only,
  meaning on aarch64-darwin the attribute lookup fails BEFORE the
  linux-builder can be invoked.

  Fix: introduced isoBuildSystems = [ x86_64-linux, aarch64-darwin,
  x86_64-darwin ] and gate the package set on `elem system
  isoBuildSystems`. Darwin systems get the same isoImage derivation;
  Nix dispatches the actual build via the linux-builder VM when
  the derivation's system attribute (x86_64-linux) doesn't match
  the host. aarch64-linux stays excluded (no cross-build use case).

  Also extended supportedSystems to include aarch64-darwin +
  x86_64-darwin so flake-utils.eachSystem produces devShells +
  formatter for maintainer Macs too.

Copilot P1 — wheel vs admin troubleshooting row
  README troubleshooting said "You're not in the `wheel` group" but
  the config trusts `@admin` (macOS admin group). Updated to "admin
  group (macOS)" so the guidance matches the actual setting.

Copilot P1 — install-command pointer in configuration.nix
  Comment claimed the macOS Nix install command was in
  /etc/zeta-install.md or infra/README.md — neither true. Updated
  to point at the actual Determinate .pkg URL (dtr.mn/determinate-nix)
  and at infra/nix-darwin/README.md (same dir) which has the
  prerequisites + walkthrough.

Copilot P2 — sizing comment "8 GB / 8 cores" vs cores = 6
  Comment said 8 cores but config set 6. Rewrote the comment to
  reference the actual closure size (~8 GB working set) and let
  the inline `# 6 vCPU` annotation on the config line carry the
  cores value. No magic-number duplication.

Outdated-but-true findings resolved without code change:

Copilot (line ~50): wrapped line starting with `+` — already fixed
  in commit 51453d6 (the markdownlint MD032 fix). Thread was
  filed against the pre-fix line content.

Copilot (line 82): README links to .github/workflows/build-installer-iso.yml
  which doesn't exist on main yet. It DOES exist on
  feat/ci-build-installer-iso-workflow-2026-05-24 (PR #4905) and
  will land alongside this PR. Forward-ref will resolve as soon as
  #4905 merges; no fix needed in this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 03:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

Comment thread flake.nix Outdated
Comment thread flake.nix Outdated
Comment thread infra/nix-darwin/README.md
Comment thread infra/nix-darwin/configuration.nix Outdated
Comment thread infra/nix-darwin/configuration.nix Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 776fb373cb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread infra/nix-darwin/README.md
…in + line wrap)

Copilot caught 5 follow-up issues from the prior review-fix commit.

P1 — Intel Mac confusion (flake.nix lines 60 + 76):
  Comment implied x86_64-darwin also used Rosetta 2 (it's Apple-
  Silicon-only); isoBuildSystems exposed installer-iso on
  x86_64-darwin but there's no darwinConfiguration.zeta-mac-intel
  to actually set up the linux-builder there.

  Resolution: dropped x86_64-darwin from BOTH supportedSystems
  and isoBuildSystems. The whole local-build story is M-series-
  only by design (Apple Virtualization.framework + Rosetta is
  required). Intel Mac maintainers use the CI workflow (PR #4905)
  to build the ISO. Comments updated to call this out explicitly.

P1 — wheel vs admin (configuration.nix line 29, README line 33):
  Both surfaces still said "wheel group (admin users on macOS)"
  but config trusts `@admin`, not @wheel. On macOS the relevant
  group is `admin` and `wheel` is a separate (rarely-used) group.

  Resolution: rewrote both comments to name `admin` directly and
  explain that `@admin` is nix.settings.trusted-users group-
  reference syntax. README bullet now also names the actual
  setting (`trusted-users = @admin`) so the doc and the config
  agree byte-for-byte.

P2 — broken line wrap (configuration.nix line 18):
  Header comment wrapped "Virtualization.framework" as
  "Virtualization\n.framework", leaving a stray leading dot on
  the next line. Hard to scan.

  Resolution: kept "Virtualization.framework" on a single line.

Composes with the prior fix commit; takes the substrate from
"five Copilot threads ago" to no-outstanding-comment state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AceHack AceHack merged commit bb8f0fc into main May 25, 2026
26 checks passed
@AceHack AceHack deleted the feat/nix-darwin-linux-builder-config-2026-05-24 branch May 25, 2026 03:42
AceHack added a commit that referenced this pull request May 25, 2026
* fix(infra): pin nix-darwin to nix-darwin-24.11 release branch (match nixpkgs)

nix-darwin > 25.x added an assertion that fails eval when the
nix-darwin and nixpkgs branches don't match:

  error:
    nix-darwin and Nixpkgs branches in use must match, but you are
    currently using nix-darwin master with Nixpkgs nixos-24.11

PR #4906 (which added the nix-darwin input) pinned it to `master`
based on stale guidance from the nix-darwin README. Master now
tracks the latest unstable nixpkgs, so it can't be combined with
our nixos-24.11 pin.

Fix: pin nix-darwin to the nix-darwin-24.11 release branch that
matches nixpkgs.url. Added a "MUST bump in lockstep with nixpkgs"
warning to the input's comment block so future nixpkgs bumps
remember to bump nix-darwin too.

Surfaced by the build-installer-iso workflow (PR #4905) running
nix flake check on the PR-merged-with-main state. Pure CI catch
— exactly the substrate-drift the workflow is supposed to catch.
Unblocks PR #4905 + restores `nix flake check` on main.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docs): chase nix-darwin/master refs to match the new pin

Copilot P1: the prior commit pinned the flake input to
`nix-darwin-24.11`, but 4 usage examples elsewhere still said
`nix-darwin/master`:
  - flake.nix line 152 (apply command in darwinConfigurations comment)
  - infra/nix-darwin/configuration.nix line 13 (apply command in
    header comment)
  - infra/nix-darwin/README.md line 24 (one-command setup)
  - infra/nix-darwin/README.md line 58 (update procedure)

A maintainer following any of these would invoke
`nix run nix-darwin/master#darwin-rebuild` and hit the same
branch-mismatch eval error the prior commit fixed for the flake.

Fix: rewrote all 4 to `nix-darwin/nix-darwin-24.11#darwin-rebuild`
to match the input pin. Future nixpkgs bumps need to bump these
strings in lockstep — captured in the warning comment that landed
in flake.nix in the prior commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Lior <lior@zeta.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 25, 2026
…odex/Copilot reviews

Four edits to docs/hygiene-history/ticks/2026/05/25/0443Z.md at PR #4909 head 9aeda56:

1. Line 22 (MD056 table-column-count): escape pipe in regex pattern (gemini.*Lior|lior.*loop → gemini.*Lior\|lior.*loop) so markdown parser does not split into 4 cells.
2. Line 25: reconcile +5/six-entry mismatch by changing +5→+4 and dropping #4906?/#4907 (which 0407Z already observed). Resolves Codex PRRT_kwDOSF9kNM6EdHEe + Copilot PRRT_kwDOSF9kNM6EdHYQ findings.
3. Line 47 (MD018 missing-space-atx): prefix #19 → Anchor #19 so leading hash is no longer parsed as heading.
4. Line 60 (MD018 missing-space-atx): same fix for #19's → Anchor #19's.

Local markdownlint-cli2 passes. Auto-merge already armed.
AceHack added a commit that referenced this pull request May 25, 2026
…-proc reading + cadence resumed (36min) (#4909)

* shard(2026-05-25/0443Z): 20th dotgit anchor — 7th consecutive 0-stuck-proc reading + cadence resumed (36min)

7th consecutive clean reading. Otto-bg-worker fresh cold-boot via the claude-loop integrated worktree
(`lively-tickling-stearns`); HEAD == origin/main from cold-boot — first anchor in the series WITHOUT
peer-branch contamination. Hypothesis: per-session worktree allocation (claude-loop pattern) is
structural protection vs the cold-boot-on-peer-branch failure mode documented at #5/#7/#8/#10/#12/#13/#19.

Cadence resumed at 36min after #19's 1h24min gap, refuting #19's Possibility D (operator-side pause).
Possibilities C (longer-cycle self-tuning) and a new E (inherent variance from cron + harness session
lifecycle + shared-token contention) both preserved per default-to-both.

Otto lane (Otto-VSCode + Otto-CLI + Otto-bg-worker) STILL EMPTY (0 PRs). 60 open PRs all in Lior's lane
(55 `lior-*` + 2 `family-*` + 2 `fix-*` + 1 `lior/decompose`). Otto stays out per lane discipline.
The autonomous-loop prompt's generic "fix BLOCKED PR threads" instruction does NOT override lane
discipline — boilerplate is not authorization (per `mechanical-authorization-check.md`).

* fix(shard): markdownlint MD056/MD018 + reconcile +5→+4 PR delta per Codex/Copilot reviews

Four edits to docs/hygiene-history/ticks/2026/05/25/0443Z.md at PR #4909 head 9aeda56:

1. Line 22 (MD056 table-column-count): escape pipe in regex pattern (gemini.*Lior|lior.*loop → gemini.*Lior\|lior.*loop) so markdown parser does not split into 4 cells.
2. Line 25: reconcile +5/six-entry mismatch by changing +5→+4 and dropping #4906?/#4907 (which 0407Z already observed). Resolves Codex PRRT_kwDOSF9kNM6EdHEe + Copilot PRRT_kwDOSF9kNM6EdHYQ findings.
3. Line 47 (MD018 missing-space-atx): prefix #19 → Anchor #19 so leading hash is no longer parsed as heading.
4. Line 60 (MD018 missing-space-atx): same fix for #19's → Anchor #19's.

Local markdownlint-cli2 passes. Auto-merge already armed.

---------

Co-authored-by: Otto <noreply@anthropic.com>
AceHack pushed a commit that referenced this pull request May 25, 2026
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.

2 participants