Merge nucleic/olive-willow-newt-96nb into dev

This commit is contained in:
2026-07-27 21:20:25 -07:00
parent ea257181dd
commit bc11afc63d
5 changed files with 77 additions and 12 deletions
+46 -3
View File
@@ -30,6 +30,9 @@ ARG GO_SHA256_ARM64=fe4789e92b1f33358680864bbe8704289e7bb5fc207d80623c308935bd69
ARG MISE_VERSION=v2026.7.7 ARG MISE_VERSION=v2026.7.7
ARG MISE_SHA256_AMD64=0953810c2785eb4a75159f67f8b5721c4f3c80b8a6a812015d5af7d7fbd1b8a4 ARG MISE_SHA256_AMD64=0953810c2785eb4a75159f67f8b5721c4f3c80b8a6a812015d5af7d7fbd1b8a4
ARG MISE_SHA256_ARM64=c4e542b53a15d2ec641e072f7b2d9da8a0554b92fd2c09a51febde32c6080ab8 ARG MISE_SHA256_ARM64=c4e542b53a15d2ec641e072f7b2d9da8a0554b92fd2c09a51febde32c6080ab8
ARG SWIFT_VERSION=6.3.3
ARG SWIFT_SHA256_AMD64=19e0c78cad5418ad48bfa87aa20c53ac9ac9996d1695d04dd94f7c7ea4eb133f
ARG SWIFT_SHA256_ARM64=ecba8ef87b54a5048d466af500f3169c939a6b8a2cb7c600f76b5184457f293a
# Warm shared caches at fixed world-readable paths (§6.3). Exported here so the BUILD's # Warm shared caches at fixed world-readable paths (§6.3). Exported here so the BUILD's
# own installs warm them; the runtime equivalent for agent shells is # own installs warm them; the runtime equivalent for agent shells is
@@ -42,7 +45,7 @@ ENV npm_config_cache=/opt/cache/npm \
RUSTUP_HOME=/opt/rustup \ RUSTUP_HOME=/opt/rustup \
GOMODCACHE=/opt/cache/gomod \ GOMODCACHE=/opt/cache/gomod \
PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers \ PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers \
PATH=/opt/mise/shims:/opt/cache/cargo/bin:/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin PATH=/opt/mise/shims:/opt/cache/cargo/bin:/usr/local/go/bin:/opt/swift/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
# The local apt pool (CI's just-built Nucleic packages) rides in only for this stage's # The local apt pool (CI's just-built Nucleic packages) rides in only for this stage's
# installs; the hosted signed repo (naros-keyring, already in the base) is the runtime # installs; the hosted signed repo (naros-keyring, already in the base) is the runtime
@@ -114,6 +117,43 @@ RUN set -eu; \
mkdir -p /opt/mise/shims; \ mkdir -p /opt/mise/shims; \
MISE_DATA_DIR=/opt/mise mise --version MISE_DATA_DIR=/opt/mise mise --version
# Swift — the swift.org release toolchain (pinned + checksummed, same shape as Go above).
# Baked because Nucleic itself is a Swift package and agents work on Swift repos all day:
# swiftc, SwiftPM, swift-testing, sourcekit-lsp and swift-format all run in-container now.
# It does NOT replace host_exec / the macOS VM for anything Apple-SDK — there is no
# SwiftUI/AppKit/UIKit or xcodebuild on Linux — but pure-Swift targets build and test here.
#
# The `debian12` slice is the newest Debian build swift.org publishes; it runs unmodified on
# trixie (verified: swift build/test/swiftc on the 26.07 image) once libncurses6 is present,
# which naros-tier-agent now pulls along with the rest of the toolchain's runtime libs
# (libxml2, libcurl4, libsqlite3-0, libuuid1, libtinfo6, zlib1g). Debian's own `swiftlang`
# is deliberately NOT used here: trixie carries 6.0.3, too old for a swift-tools-version 6.2
# package like this repo's. (The VM desktop rootfs is the mirror-image case — forky's
# libxml2 soname bump to .so.16 makes the swift.org build unloadable there, so it takes
# forky's swiftlang 6.2.3 instead; see os/mkimage/profiles/vm-desktop.pkgs.)
#
# LLDB is stripped: upstream links it against libpython3.11, which trixie does not ship, so
# lldb/lldb-dap/liblldb could never load — dropping them keeps 338 MB out of the image and
# makes `swift repl` fail as a plain "not found" instead of a loader error. Nothing else in
# the toolchain depends on liblldb (checked via NEEDED).
RUN set -eu; \
case "$TARGETARCH" in \
amd64) swift_slice=debian12; swift_sha="$SWIFT_SHA256_AMD64";; \
arm64) swift_slice=debian12-aarch64; swift_sha="$SWIFT_SHA256_ARM64";; \
*) echo "unsupported TARGETARCH: $TARGETARCH" >&2; exit 1;; \
esac; \
swift_tag="swift-${SWIFT_VERSION}-RELEASE"; \
curl -fsSL "https://download.swift.org/swift-${SWIFT_VERSION}-release/${swift_slice}/${swift_tag}/${swift_tag}-${swift_slice}.tar.gz" \
-o /tmp/swift.tgz; \
echo "$swift_sha /tmp/swift.tgz" | sha256sum -c -; \
mkdir -p /opt/swift; \
tar -C /opt/swift --strip-components=1 -xzf /tmp/swift.tgz; rm /tmp/swift.tgz; \
rm -f /opt/swift/usr/bin/lldb /opt/swift/usr/bin/lldb-dap \
/opt/swift/usr/bin/lldb-server /opt/swift/usr/bin/lldb-argdumper \
/opt/swift/usr/lib/liblldb.so*; \
chmod -R a+rX /opt/swift; \
swift --version | grep -q "Swift version ${SWIFT_VERSION}"
# Runtime environment for agent shells: cache paths, toolchain PATH entries, mise # Runtime environment for agent shells: cache paths, toolchain PATH entries, mise
# activation. nash -l sources /etc/profile.d, which is how every containerized exec # activation. nash -l sources /etc/profile.d, which is how every containerized exec
# (ContainerEngine exec → nash -lc) sees this without OCI env. # (ContainerEngine exec → nash -lc) sees this without OCI env.
@@ -192,11 +232,14 @@ RUN set -eu; \
go_v="$(go version | awk '{print $3}')"; \ go_v="$(go version | awk '{print $3}')"; \
mise_v="$(mise --version 2>/dev/null | awk '{print $1}')"; \ mise_v="$(mise --version 2>/dev/null | awk '{print $1}')"; \
gcc_v="$(gcc -dumpfullversion)"; \ gcc_v="$(gcc -dumpfullversion)"; \
swift_v="$(swift --version | awk '/Swift version/ {print $3; exit}')"; \
pw_v="$(playwright --version | awk '{print $2}')"; \ pw_v="$(playwright --version | awk '{print $2}')"; \
jq --arg node "$node_v" --arg python "$python_v" --arg rust "$rust_v" \ jq --arg node "$node_v" --arg python "$python_v" --arg rust "$rust_v" \
--arg go "$go_v" --arg mise "$mise_v" --arg gcc "$gcc_v" --arg playwright "$pw_v" \ --arg go "$go_v" --arg mise "$mise_v" --arg gcc "$gcc_v" --arg swift "$swift_v" \
--arg playwright "$pw_v" \
'.tier = "agent" | .variant = "agent" \ '.tier = "agent" | .variant = "agent" \
| .toolchains = {node: $node, python: $python, rust: $rust, go: $go, mise: $mise, gcc: $gcc} \ | .toolchains = {node: $node, python: $python, rust: $rust, go: $go, mise: $mise, \
gcc: $gcc, swift: $swift} \
| .caches = {npm: "/opt/cache/npm", pip: "/opt/cache/pip", uv: "/opt/cache/uv", \ | .caches = {npm: "/opt/cache/npm", pip: "/opt/cache/pip", uv: "/opt/cache/uv", \
cargo: "/opt/cache/cargo", gomod: "/opt/cache/gomod"} \ cargo: "/opt/cache/cargo", gomod: "/opt/cache/gomod"} \
| .playwright = {version: $playwright, browsers: "/opt/playwright-browsers", chromium: true}' \ | .playwright = {version: $playwright, browsers: "/opt/playwright-browsers", chromium: true}' \
@@ -16,11 +16,11 @@ export PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers
# where the interactive `mise activate` hook would not run. # where the interactive `mise activate` hook would not run.
export MISE_DATA_DIR=/opt/mise export MISE_DATA_DIR=/opt/mise
# Baked toolchains (§6.2): cargo/rustup bins, Go, and the mise shims ahead of them all # Baked toolchains (§6.2): cargo/rustup bins, Go, the swift.org toolchain at
# so `mise use` versions win per-project. Idempotent (guarded) — profile.d can be # /opt/swift/usr/bin, and the mise shims ahead of them all so `mise use` versions win
# sourced more than once per session. # per-project. Idempotent (guarded) — profile.d can be sourced more than once per session.
case ":$PATH:" in case ":$PATH:" in
*:/opt/mise/shims:*) ;; *:/opt/mise/shims:*) ;;
*) PATH="/opt/mise/shims:/opt/cache/cargo/bin:/usr/local/go/bin:$PATH" ;; *) PATH="/opt/mise/shims:/opt/cache/cargo/bin:/usr/local/go/bin:/opt/swift/usr/bin:$PATH" ;;
esac esac
export PATH export PATH
+10
View File
@@ -70,3 +70,13 @@ python3-venv
python3-pip python3-pip
nodejs nodejs
npm npm
# Swift, from forky's own swiftlang (6.2.3 in the pinned snapshot) rather than the swift.org
# release tarball the container image bakes (6.3.3, os/images/agent/Dockerfile). Not a
# preference for older — the upstream builds are simply unloadable here: every swift.org slice
# links libxml2.so.2, and forky replaced libxml2 with libxml2-16 (soname .so.16, no versioned
# symbols to alias), so swift-build/swift-test die in the loader. Debian's package is built
# against forky's own libxml2-16 and python3.14, which also means its LLDB works — the piece
# the container layer has to strip. Same rule as the GNOME stack above: one coherent pocket,
# no trixie/forky ABI mixing. ~2.6 GB installed.
swiftlang
+12 -4
View File
@@ -8,10 +8,18 @@ Depends: naros-tier-base, nucleic-bridge, build-essential, pkg-config,
python3, python3-pip, python3-venv, sudo, gh, ripgrep, fd-find, jq, yq, python3, python3-pip, python3-venv, sudo, gh, ripgrep, fd-find, jq, yq,
sqlite3, htop, tree, zip, unzip, zstd, xz-utils, moreutils, rsync, less, sqlite3, htop, tree, zip, unzip, zstd, xz-utils, moreutils, rsync, less,
procps, file, bsdextrautils, e2fsprogs, util-linux-extra, mount, login, procps, file, bsdextrautils, e2fsprogs, util-linux-extra, mount, login,
gpgv gpgv, libncurses6, libtinfo6, libxml2 | libxml2-16, libsqlite3-0, libuuid1,
libcurl4t64 | libcurl4, zlib1g
Description: narOS agent tier — apt-resolvable half (NAROS.md §4, §6) Description: narOS agent tier — apt-resolvable half (NAROS.md §4, §6)
The dev toolchain and modern CLI kit that come from Debian, plus the control The dev toolchain and modern CLI kit that come from Debian, plus the control
bridge. The non-apt half of the agent tier — Node (NodeSource), rustup, Go, bridge. The non-apt half of the agent tier — Node (NodeSource), rustup, Go,
mise, warm caches, agent CLIs, Playwright — is layered by the naros-agent Swift (swift.org toolchain), mise, warm caches, agent CLIs, Playwright — is
image build (milestone N2); this meta is what `apt install` can deliver into layered by the naros-agent image build (milestone N2); this meta is what
any Debian-family container (NAROS.md §7.3 conversion path). `apt install` can deliver into any Debian-family container (NAROS.md §7.3
conversion path).
.
The trailing lib* entries are the swift.org toolchain's runtime dependencies
(its full external NEEDED set beyond libc/libstdc++/libgcc, which
build-essential already carries). Most arrive transitively today — libncurses6
does not, and without it every Swift driver binary dies in the loader — so all
of them are declared here rather than left to another package's whim.
+5 -1
View File
@@ -95,7 +95,11 @@ case "$FLAVOR" in
test -x /usr/local/bin/nucleic-a11y-agent test -x /usr/local/bin/nucleic-a11y-agent
test -x /usr/local/bin/nucleic-linux-agent test -x /usr/local/bin/nucleic-linux-agent
test -f /usr/share/gnome-shell/extensions/[email protected]/metadata.json test -f /usr/share/gnome-shell/extensions/[email protected]/metadata.json
grep -q "AutomaticLogin=agent" /etc/gdm3/daemon.conf' grep -q "AutomaticLogin=agent" /etc/gdm3/daemon.conf
# Swift comes from forky swiftlang here (vm-desktop.pkgs), so assert the compiler
# actually loads — a soname drift in the pocket (the libxml2 .so.2→.so.16 kind) would
# otherwise ship a Swift that only fails the first time an agent invokes it.
swiftc --version > /dev/null'
;; ;;
*) *)