Archive — history, not state. Kept for its reasoning and its evidence; its plan is closed.

L6 cross-builds — linux, windows, macOS from tonight’s tip

Branch p/cross-artifacts, based on dev af0126485 (the press switch: carts are pressed through pit.mcode.program@1). Artifacts live in the worktree at .claude/worktrees/night-crossbuild/cross-artifacts/ — binaries are NOT committed; their sizes and hashes are recorded below.

Verdict

CONFIRMED. “Linux, Windows, and macOS binaries with embedded boot cart + mcode sidecar” exists tonight, and all three were verified at the same level: drop the binary and its boot.qop into an otherwise empty directory, run ps, and the booted fleet lists itself.

That is a stronger claim than “it built”. On every platform the runtime mounted its root cartridge out of its own binary — Windows says so out loud under Wine:

boot: root cartridge mounted from binary boot section (9453584 bytes)
boot: shop actor 621e452469255ea06a3ef2df09908a783c30d21ae5250fb3d5a1d62df70ef018 bred

9,453,584 is exactly the Windows root.cart pressed on the Mac. The cart crossed from a darwin/arm64 press to a mingw-linked PE running under Wine on an emulated amd64 container, and booted.

Artifacts

cross-artifacts/, all sha256:

filebytessha256
macos/pit11,032,336a627bbf788d008732efe73ed000bc603b1961212456c4a7073aa3584171156bc
macos/boot.qop13,252,4961b228385d21f877bb8dd7ce9d8db70cc04c4e2d091561a938d4df50c657f86f3
linux/pit11,195,0248236301c56321efb994cfbee8f21790ea0ca529a5d9de711fcbd6c9a64f11c2c
linux/boot.qop13,257,178f621611e9f20259df18606b1a60a567822292b4fbe95473205cd4bbe17ca8d3e
linux/root.cart9,482,256aeba4b169154bb9e0f6a12de7100290d64d30bc22a5e17d514a9f4d327f980c7
windows/pit.exe11,525,6915b413689aa8a599f9399bef9437ed49c6f0760fba9342de74e83a078024e55f8
windows/windows-boot.qop13,240,930e8515a4434938c69e865a81452f58569678bf14684e042f8ebe640b59101ebac
windows/root.cart9,453,5842941c4051b4654bd02877863c57d3ee6a9f9cb9d189f9fd430bc04d7134b66d1

The root.cart files are the separable pressed roots — the same bytes that are linked into the binary beside them. macOS has none listed because make dist-vm copies the already-linked build/pit; its root is boot/root.cart in the checkout.

Shapes: macos/pit is Mach-O arm64, linux/pit is ELF64 x86-64 (\177ELF 002 001 001 … > \0), windows/pit.exe is PE (MZ).

Verification level, per platform

platformbuiltboots standaloneps answershow
macOS arm64yesyesyesnative, bare dir /tmp/macos-smoke
linux x86-64yesyesyesinside pit-ci:local, bare dir /work/linux-smoke
windows x86-64yesyesyespit.exe under Wine in the same container

All three: nothing on the path but pit and boot.qop, a fresh shop, and PIT_SEED=boot.qop. Windows ps exited 0 and listed shop_actor/clerk/logger/policy/system/courier/terminal/ps.

One shared limitation, not a per-platform defect. On all three, an inline -e program (pit '...') fails with no upstream for source file: std_endowments/package.json. The sealed distribution carries no sources, so the eval/compile lane cannot prepare a new program. Built-in shop tools (ps, down) work everywhere. This is the sealed-runtime boundary, and it is the same on the dev Mac — it did not appear at the cross-build seam.

How they were produced

  1. Cold build in a fresh worktree (rm -rf .pit build cold-build pit && make).
  2. make dist-vm → macOS pair (G5, as briefed — package_nightly.sh’s matrix check was not fought).
  3. PIT_CROSS_TARGETS="linux windows" PIT_CROSS_CONTENT=development make cross-checkbuild-cross/{linux,windows}/. cross-check reported ALL GREEN, including the playdate foreign-stamp arm and its content-volume refusal.
  4. Container lane in pit-ci:local (amd64 under Rosetta) seeded with the fresh linux press: cold floor → pit forge linux → linux binary.
  5. pit forge windows --cc x86_64-w64-mingw32-gcc --boot <mac-pressed root.cart>pit.exe; Wine smoke.

Emulation was a non-issue: the in-container cold floor plus linux forge ran in about 8 minutes. No slow-turn watchdog was tripped, so G3 did not bite.

Gaps closed (committed on this branch)

G1 — no artifact escape from the container. run_container was --rm with a read-only /src and a tmpfs /work; the lane’s whole product died with the container and only an exit code escaped. Added an /out volume (PIT_CI_OUT, default ci-out/) and an EXIT trap that copies build/pit, boot.qop, build-win/pit.exe, build-win/boot.qop, build-windows-seed/windows-boot.qop and the wine log out on every exit path — a lane that dies in its test step still built a binary worth having. This is how every Linux and Windows artifact above left the container.

G2 — stale committed Linux seed. boot/targets/linux/ was 81 commits behind: root.cart 1,789,968 bytes against the current 9,482,256. Refreshed from the fresh press and committed. ci/README.md’s regeneration recipe now routes through make cross-check (which runs smoke first, so the seed cannot be pressed by a stale daemon) and states plainly that the seed must be refreshed when the boot pair’s shape changes.

G4 — tmpfs /work ENOSPC. Added PIT_CI_WORK_DIR: set it and /work becomes a bind mount instead of a tmpfs. Not merely precautionary — see the in-container Windows press defect below, where the tmpfs is the prime suspect.

Defects found (fixed here)

1. cross_check.sh could never run PIT_CROSS_CONTENT=development on macOS. Line 111 expanded "${CONTENT_FLAG[@]}" on a deliberately empty array under set -u. In bash 3.2 — which is /usr/bin/env bash on macOS, the host this script presses from — that is unbound variable, and the press died on its first target. Fixed with the portable ${a[@]+"${a[@]}"} form. Since development is the mode that packs the runnable boot.qop sidecar, the arm that produces what CI actually consumes was dead on the Mac.

2. The Wine smoke gate was a false green. windows_smoke_lane ran an inline program printing WIN-SMOKE-OK and grepped the log for that marker. When program preparation fails, the runtime logs the program source — marker included:

link: executable preparation failed log.console("WIN-SMOKE-OK"); $stop(): no upstream for source file: std_endowments/package.json

grep -q WIN-SMOKE-OK matched that line. The lane passed while nothing ran. This was observed live tonight, not reasoned about: my run exited 0 with grep -c = 1 whose sole hit was the error text. Replaced with ps plus two assertions that cannot be satisfied by an error message quoting its input: root cartridge mounted from binary boot section and name: shop_actor.

Gaps remaining

A. The in-container Windows press dies with target stopped and no diagnostic. The stock windows-smoke lane got as far as build_windows_seed.shbootstrap --target windows, emitted 7 of the ~12 expected link: press: lines, then printed exactly target stopped and exited

  1. No panic, no OOM message, no ENOSPC — the only line in the log. Suspect resource exhaustion: the Docker VM has 8 GB and the tmpfs /work is 3.9 GB of that same RAM, so a heavy press competes with its own workspace. First thing to try: re-run with PIT_CI_WORK_DIR set (the G4 lever, now available). Worth attention regardless: a press that stops without saying why is bad on any host. The Windows artifact above was produced by pressing the root on the Mac and forging in the container, which is the L6 shape anyway — but the stock lane should work, and until it does, windows-smoke is red on this Mac.

B. Docker Desktop wedged repeatedly. Containers stuck in Created indefinitely, requiring a full Docker Desktop restart; it recurred three times. The correlation — not proven, but it held every time — is polling docker ps in a tight loop while a container is starting. Once I stopped polling, the same invocation ran fine four times in a row. The mounts, --user, --init and --tmpfs were each bisected and individually cleared. Local-harness annoyance, not a pit defect; noted so the next person does not re-bisect it.

C. macOS remains outside CI. As briefed (G5). The macOS pair is real and verified, but it is made by make dist-vm on this Mac, not by a runner. Apple targets still need a macOS runner.

D. wgpu and libgit2 probes drop on both linux and mingw toolchains (its C did not compile on this toolchain). Expected in the CI image; recorded because it means the cross binaries are probe-free relative to the Mac build.

E. Not attempted tonight: the full windows lane (the four Wine suites), vm-linux/vm-web lanes, and emscripten. Scope was the three binaries.

What is committed here

  • scripts/ci_local.sh — the /out artifact escape, PIT_CI_WORK_DIR, and the Wine gate fix.
  • scripts/cross_check.sh — the bash 3.2 empty-array fix.
  • boot/targets/linux/ — refreshed seed (the stale-seed trap dies).
  • ci/README.md — regeneration via cross-check, and why the seed must move.
  • this document.

Binaries are deliberately not committed.

Source: plans/archive/night-2026-08-04/cross-builds.md