Repository navigation
spike(devcontainer): Phase-0 feasibility gate — rootless nested A0 boot - #8
Merged
Merged
Conversation
Proves the Critical-4 assumption behind the plugin-quality-standard SPEC: a devkit devcontainer (Playwright + rootless podman) can boot the Agent Zero container NESTED and UNPRIVILEGED (no --privileged, no host docker.sock) and the harness can reach + authenticate against it. - devcontainer/Containerfile Playwright base + rootless podman toolchain - devcontainer/spike/run-acceptance.sh nested boot + login acceptance - .github/workflows/devcontainer-spike.yml runs it on ubuntu-latest Mechanism already confirmed on a real Linux host; this lets the GH runner be the authoritative proof. Ref: SPEC DEC-018/031, Appendix E.6. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n can't nest
Spike finding: the Playwright/Ubuntu-jammy base + apt podman 3.4.4 fails
rootless nesting ("cannot setup namespace using newuidmap"). podman/stable
(podman 5.8.2, pre-configured for rootless nesting) nests cleanly — verified
locally inside the built image (NESTED_IN_DEVKIT_OK, unprivileged).
Playwright browser deps deferred to Phase 1 (Fedora install); the Phase-0
gate is nesting, which needs no browser. Ref: SPEC DEC-039.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… enforcing) CI proved the gate: on GH-hosted ubuntu-latest the devcontainer nests a rootless container (rootless:true, step 1/3 ✓). Step 2 failed only on "short-name resolution enforced but cannot prompt without a TTY" — podman/stable requires fully-qualified names. Pin docker.io/agent0ai/agent-zero:latest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…agnostics CI cd3db4e proved nesting works on GH ubuntu-latest AND A0 booted nested rootless (run_ui RUNNING, Flask serving) — but cold-CI first boot (pull + initialize.sh clone + pip install) reached services right as the 300s window expired. Bump BOOT_TIMEOUT→720s, job timeout→40m, and dump curl -v + podman logs on timeout for clearer diagnosis. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…its FATAL CI run 156e82a: A0 booted nested rootless (run_ui RUNNING, Flask serving) but sshd exits 255 under rootless podman; A0's supervisor event-listener (no args) kills the whole instance on ANY process FATAL → A0 died ~8s after boot → /login connection-refused for the rest of the window. Replace /usr/sbin/sshd with a no-op before initialize.sh so run_sshd stays RUNNING and never FATALs. SSH isn't used by the HTTP e2e. Watchdog stays armed for genuinely-critical procs. Ref: SPEC DEC-040 / Appendix F.6. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t-net CI run 23ae917: A0 stayed up (sshd fix worked) but its UI couldn't bind 0.0.0.0:80 — privileged port, rootless mapped-root denied. Inner container defaults to host netns so a --sysctl on the inner run is rejected. Verified-working model (reproduced locally, REACHED_80_OK): outer devcontainer run with --sysctl net.ipv4.ip_unprivileged_port_start=0, inner A0 with --network=host, reach at localhost:80. Ref: SPEC DEC-041. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase-0 feasibility spike for the plugin quality & structure standard SPEC. It proves the single riskiest assumption in that design (
Critical-4inSPEC-REVIEW-001): that a devkit devcontainer (Playwright + rootless podman) can boot the Agent Zero container nested and unprivileged — no--privileged, no hostdocker.sock— and that the harness can reach + authenticate against it.This is the gate for everything else (
DEC-018/DEC-031). If it's green, the devcontainer model is de-risked; if not, we take the documented self-hosted-runner fallback before Phase 1.Contents
devcontainer/Containerfile— official Playwright base (node + browsers + libs) + rootless podman toolchain (fuse-overlayfs, uidmap, slirp4netns, crun), configured rootless forpwuser.devcontainer/spike/run-acceptance.sh— (1) nested rootless container smoke test, (2) boot the real A0 image nested + wait for/login, (3) log in + authenticated fetch. A0 image is a parameter (DEC-019)..github/workflows/devcontainer-spike.yml— builds the image and runs the acceptance onubuntu-latest, rootless outer + rootless inner.Evidence so far
The core mechanism was already confirmed on a real Linux host (rootless podman-in-podman, no
--privileged):This PR lets the GitHub-hosted runner be the authoritative proof (booting the full A0 image nested).
Scope
Spike only — the full
install → verify-installed → uninstall → verify-uninstalledcycle layers on top via the existing Playwright harness (Phase 2). Not wiring the reusable e2e workflow or bootstrap here.🤖 Generated with Claude Code