Apple Container Backend
Status: Partially implemented — launch-path backend selection, manifest schema, session-contract/telemetry output, and persisted-instance lifecycle dispatch are wired and compile; Phase 0 hardware validation and real Apple Container finalization remain open.
Shipped facts
The backend code has landed and compiles: the container CLI client (crates/jackin-runtime/src/apple_container_client.rs), the launch/attach/reconnect/stop/remove/session-contract orchestration (crates/jackin-runtime/src/runtime/apple_container.rs), the JACKIN_CAPSULE_FORCE_DAEMON capsule patch (crates/jackin-capsule/src/main.rs, gated on forced_daemon_mode so an inherited env var can't capture a client-mode invocation), and the instance-manifest BackendResources union (crates/jackin-instance/src/manifest.rs, INSTANCE_MANIFEST_VERSION 2). The config/workspace [runtime] default_backend / [runtime] backend fields landed at schema version v1alpha8 with migration fixtures.
Backend selection for jackin load is wired: the load pipeline (crates/jackin-runtime/src/runtime/launch/launch_pipeline.rs) reads [runtime].backend / [runtime].default_backend via resolve_backend (unit-tested, fails closed on an unrecognised backend string) and routes a fresh load to apple_container::launch, so apple-container is a selectable backend at launch (jackin load the-architect . --backend apple-container).
Session contract and telemetry are also wired, not just planned: apple_container::launch calls print_session_contract (kernel boundary, mounts, DinD state, residual risks) and check_dns on attach, and emits debug_log!("apple-container", …) lines for version probe, container run, capsule-ready, and DNS check.
Persisted lifecycle dispatch is wired: crates/jackin-runtime/src/runtime/backend.rs defines ContainerBackend with required finalize, Docker and Apple Container implementations, and manifest-based backend resolution. crates/jackin-runtime/src/runtime/cleanup.rs routes purge guards, eject, and exile_all through it; crates/jackin-runtime/src/runtime/attach.rs routes hardline through it. Legacy manifests with no backend field still resolve to Docker.
Still to prove end-to-end: Apple Container finalize intentionally returns an explicit Phase 0 error from the backend trait. The real post-attach dirty-exit/finalization behavior needs macOS 26 ARM hardware validation before it can claim parity with the Docker path.
The VM path itself is empirical, not code: launch/attach runs the container CLI and rootless DinD inside an apple/container VM, which cannot be exercised without macOS 26 ARM hardware — the Phase 0 gate. Run scripts/phase0-apple-container.sh there to validate it; nothing in this branch claims Phase 0 has passed, and the launch dispatch currently starts then reclaims the Docker sidecar pending the Phase-0 reorder.
Full architecture (runtime stack, CLI shell-out surface, manifest/schema detail, telemetry spec, known v0.11.0 limitations, design alternatives): Apple Container backend — architecture and design.
Remaining work
- Phase 0 empirical validation — requires macOS 26 ARM hardware with
apple/containerv0.11.0+. Runscripts/phase0-apple-container.sh; result decides whether rootless DinD works inside apple/container VMs and whether the Docker-sidecar-then-reclaim ordering in the launch pipeline can be reordered to skip starting the sidecar at all. - Implement real Apple Container finalization —
ContainerBackend::finalizecurrently returns an explicit Phase 0 error for Apple Container; after hardware validation, wire the post-attach dirty-exit/finalization behavior to match the Docker lifecycle semantics where possible. - Rootless DinD validation — blocked on the Docker runtime hardening contract confirming
--cap-add CAP_SYS_ADMINworks inside an apple/container VM.
Out of scope
- smolvm as an alternative VM backend — separate fallback track, see smolvm backend research.
- Network egress enforcement at the VM boundary — tracked by Network egress policy.
Related work
- Agent isolation architecture — master architecture doc; Apple Container is Layer 2 (VM boundary).
- Docker runtime hardening contract — prerequisite; rootless DinD must validate before Phase 0 starts.
- jackin-exec — Layer 3 credential injection; works on top of any backend including apple-container.
- Selectable sandbox backends — umbrella for Docker and Apple Container as the two runtime families.
- Session contract and explain mode — Apple Container backend must feed the session contract with kernel boundary, caps, mounts.