Promote the vsock control plane from opt-in to default, so a Nucleic Control container's approval +
interceptor channel runs over the vsock-relayed socket (no host IP listener, no macOS local-network
prompts) instead of TCP on the VM gateway. Only the agent's own internet egress + DNS stay on the
gateway NAT — the minimum that can't ride vsock.
- vsockControlPlaneEnabled defaults true when unset (an explicit stored false still wins); Settings
toggle default + caption updated.
- Sandbox image bumped v3 -> v4 (ProjectSandbox.defaultImage + sandbox-image.yml IMAGE_TAG). v4
ships control-bridge.js (required by the default-on vsock path) plus the Codex/Grok CLIs. The
client refresh is automatic: the launch-time rootfs prune drops the stale v3 cache and pulls v4.
- Fix the Grok install in the Dockerfile: the x.ai installer already symlinks
/usr/local/bin/grok -> /root/.grok/bin/grok, so the old `ln -sf /usr/local/bin/grok ...` made a
self-referential symlink ("Too many levels of symbolic links"), and /root is 0700 so the non-root
agent couldn't reach it anyway — this is why CI silently failed and the registry image was stuck
at the pre-bridge build (Jun 21). Relocate the install to a world-traversable /opt/grok and relink.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Codex via npm (@openai/codex); Grok via the official x.ai installer, symlinked onto the global PATH with a grok --version build check that fails loudly if the arm64 binary didn't land.
containerSpec() now seeds auth per backend: both store auth as plain files (no Keychain), so seedAgentHome copies the host's ~/.codex / ~/.grok into the per-session writable home (the agent's $HOME), where the CLIs find $HOME/.codex / $HOME/.grok automatically. API-key users are covered by forwarding OPENAI_API_KEY / XAI_API_KEY / GROK_CODE_XAI_API_KEY.
Completes the binaries + auth for the gated Grok/Codex control-container exec path. See docs/VSOCK_CONTROL_PLANE.md.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Run a Nucleic Control container's approval + interceptor channel over a vsock-relayed unix socket instead of TCP/HTTP on the VM gateway, so macOS raises no incoming-connection / local-network prompts.
- MCPApprovalServer: real AF_UNIX listener + transport-agnostic ByteConn (host UDS transport).
- ContainerEngine: relay the host control socket into the guest (UnixSocketConfiguration.into); init launches an in-guest loopback bridge (control-bridge.js) forwarding 127.0.0.1:9099 -> the relayed socket.
- ApprovalServerRegistry: one token-multiplexed approval server per shared control container.
- ClaudeCodeBackend: serve UDS-only (no IP listener) + point mcpConfig/interceptor env at the bridge; CommandInterceptor.hookEnv centralizes the interceptor wiring.
- GrokACPBackend / CodexAppServerBackend: exec inside the shared control container (stdio over vsock) for per-family isolation.
All gated behind ContainerServiceSettings.vsockControlPlaneEnabled (default off); legacy gateway-TCP path unchanged. Needs the sandbox image to ship control-bridge.js (and, for Grok/Codex, their CLIs + auth) before flipping the flag. See docs/VSOCK_CONTROL_PLANE.md.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Replace the Apple `container` CLI wrapper with Apple's `containerization`
Swift framework, driven in-process — no external CLI or daemon.
- ContainerEngine: in-process runtime (shared VZVirtualMachineManager from a
bundled kernel + runtime-pulled vminitd initfs, ImageStore, VmnetNetwork,
live-container registry, typed statistics for CPU/mem + OOM diagnosis).
Daemonless ⇒ ephemeral VMs; reconcile is on-disk GC.
- ContainerizedProcessHandle: bridges a guest LinuxProcess onto the existing
ProcessHandle contract (reusing LineSplitter), so backends stream NDJSON
identically in-container and on-host. Closes the stdio writers after wait()
to finish the line streams (the framework never calls Writer.close()).
- Sandbox image is built in CI (containers/nucleic-sandbox/Dockerfile +
.github/workflows/sandbox-image.yml) and pushed to GHCR; the app pulls +
unpacks it on first use (no on-device build, no user-installed tools). The
GHCR package may stay private — pulls authenticate with the user's GitHub
token via ContainerEngine.registryAuth (Settings → Sandbox, or
NUCLEIC_REGISTRY_USER/NUCLEIC_REGISTRY_TOKEN). vminitd is pulled from Apple's
public GHCR; only the kernel is bundled (scripts/fetch-kernel.sh, curl-only).
- ContainerManager rewired to the engine (policy preserved); ClaudeCodeBackend
execs in-container via the engine; Settings/ProviderAvailability use a static
capability check. Platform floor raised to macOS 26 (Apple silicon) + the
com.apple.security.virtualization entitlement (swift-tools 6.2).
- Verified end-to-end on macOS 27 / Apple silicon via Sources/container-spike:
pull vminitd + image, boot VM, exec, stream stdout. Builds clean; 21 tests pass.
Co-Authored-By: Claude Opus 4.8 <[email protected]>