feat(sessions): session-container command builders (Phase 1a) - #139
Merged
Conversation
… (Phase 1a) Foundation for long-lived session containers, wired into nothing (zero runtime behavior change). Adds to execution/docker.py: - build_session_run_command: builds `docker run -d` for a long-lived session, starting from base_isolation_args(auto_remove=False) so the gVisor posture is byte-for-byte identical to a job and cannot drift, then appending --network=none (no egress in Phase 1), a read-write /workspace mount, the SESSION_ID label, and resource limits. - build_session_exec_command: builds `docker exec` into a live session, dropped to the unprivileged user, in /workspace, timeout-wrapped. Provisional drop model; the root+gosu /tako-meta classification path lands in Phase 1b. - container_running / stop_container helpers mirroring the existing inspect/remove style. Tests (tests/test_session_lifecycle_commands.py, 87): assert the session run command reuses every base_isolation_args flag, always emits --network=none and -d and never --rm, carries the session label and a read-write /workspace mount, and emits no escape-class flags, across the full argument cross-product. This is the tripwire that pins "the session path routes through base_isolation_args, so it cannot bypass gVisor." 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
First slice of Phase 1 (the run-once→run-forever inversion). Additive, wired into nothing, zero runtime behavior change — only
tako_vm/execution/docker.py+ a new test file. Adds:build_session_run_command— buildsdocker run -dfor a long-lived session container. Starts frombase_isolation_args(..., auto_remove=False)so the gVisor posture is byte-for-byte identical to a job (and cannot drift), then appends--network=none(no egress in Phase 1), a read-write/workspacemount (the one writable cross-exec surface), theSESSION_IDlabel, and resource limits. No--rm(the container must outlive a single exec).build_session_exec_command— buildsdocker execinto a live session, dropped to the unprivileged user, in/workspace,timeout-wrapped. Provisional drop model — the final root+gosu/tako-metaper-exec OOM/timeout classification lands in Phase 1b (flagged in-code).container_running/stop_container— mirror the existinginspect_oom_killed/remove_containerstyle.Why
The single most important invariant of the whole session design: isolation flags are assembled in exactly one place (
base_isolation_args) and the session path reuses it. This is the direct architectural fix for the class of bug where a separate session command path forgets--runtime=runscand silently runs untrusted code on runc. This PR establishes the builder + the test that pins it.Dynamic testing
tests/test_session_lifecycle_commands.py(87 tests) — across the full argument cross-product, assert the run command reuses everybase_isolation_argsflag (--read-only/--init/--cap-drop=ALL/runsc), always emits--network=noneand-d, never--rm, carries theSESSION_IDlabel and exactly one read-write/workspacemount, and emits no escape-class flags (a--privileged/host-mount/host-network/extra-cap denylist). Exec command never runs as root/--privileged, targets/workspace, andtimeout-wraps.--network=none→bridgein the builder turns 17 tests red.ruff check+formatclean (pinned 0.15.16).Scope
Branches off current
main(post-Phase-0). Onlydocker.py+ the new test touched. Nothing calls the new builders yet — they get wired in Phase 1c (SessionManager).🤖 Generated with Claude Code