Found while gating #337 item 1 (PR #361), pre-existing and out of that PR's scope.
What happens
PI_EGRESS unset means the policy is ARMED (worker/src/egress.mjs), so openSandbox puts the shell on its own --internal network. A container attached only to an internal network publishes nothing: docker accepts -p, exits 0, and binds no host port.
Measured on docker 27.4.0 (macOS):
$ docker network create --internal rbpub-net
$ docker run -d --name rbpub --network rbpub-net -p 127.0.0.1:18099:3000 busybox:latest sleep 60
$ docker ps --filter name=rbpub --format '{{.Ports}}'
# empty
$ docker port rbpub # empty, exit 0
Meanwhile worker/src/sandbox-cli.mjs:105 prints published: 127.0.0.1:3000:3000, and docs/sandbox.md documents the flag with no caveat. So the one case --publish exists for, "start the app and click through it", silently does not work on a default deployment, and the tool reports that it does.
REQ-RESURRECTABLE-SANDBOX's Acceptance states it the same way: "Given --publish 3000, the port is reachable at 127.0.0.1". That is true only with PI_EGRESS=0.
Why it is not simply a bug in the flag
The two features are in genuine tension. The point of the internal network is that the sandbox reaches nothing the run could not; the point of --publish is to reach the sandbox from the host. They are opposite directions, so "fix the flag" is a design decision rather than a repair:
- refuse
--publish while egress is armed, naming PI_EGRESS=0 as the opt-out (honest, costs the feature on the default posture);
- attach the bridge as a second network when
--publish is given, which reopens the whole internet for that session and would have to say so loudly;
- say it in the CLI line and the docs, and leave the behaviour (cheapest, and arguably enough given the flag is operator-typed).
Unmeasured
Docker Desktop on macOS only. Native Linux docker and Podman are unchecked, and the --internal semantics are the kind of thing that can differ.
Where the claims live
worker/src/sandbox-cli.mjs:105 (the published: line)
docs/sandbox.md, the --publish section
specs/requirements.md, REQ-RESURRECTABLE-SANDBOX Acceptance
specs/interfaces.md, INT-SANDBOX-CONTRACT Acceptance ("--publish 3000 yields 127.0.0.1:3000:3000", which is about the ARGV and stays true)
Found while gating #337 item 1 (PR #361), pre-existing and out of that PR's scope.
What happens
PI_EGRESSunset means the policy is ARMED (worker/src/egress.mjs), soopenSandboxputs the shell on its own--internalnetwork. A container attached only to an internal network publishes nothing: docker accepts-p, exits 0, and binds no host port.Measured on docker 27.4.0 (macOS):
Meanwhile
worker/src/sandbox-cli.mjs:105printspublished: 127.0.0.1:3000:3000, anddocs/sandbox.mddocuments the flag with no caveat. So the one case--publishexists for, "start the app and click through it", silently does not work on a default deployment, and the tool reports that it does.REQ-RESURRECTABLE-SANDBOX's Acceptance states it the same way: "Given--publish 3000, the port is reachable at127.0.0.1". That is true only withPI_EGRESS=0.Why it is not simply a bug in the flag
The two features are in genuine tension. The point of the internal network is that the sandbox reaches nothing the run could not; the point of
--publishis to reach the sandbox from the host. They are opposite directions, so "fix the flag" is a design decision rather than a repair:--publishwhile egress is armed, namingPI_EGRESS=0as the opt-out (honest, costs the feature on the default posture);--publishis given, which reopens the whole internet for that session and would have to say so loudly;Unmeasured
Docker Desktop on macOS only. Native Linux docker and Podman are unchecked, and the
--internalsemantics are the kind of thing that can differ.Where the claims live
worker/src/sandbox-cli.mjs:105(thepublished:line)docs/sandbox.md, the--publishsectionspecs/requirements.md,REQ-RESURRECTABLE-SANDBOXAcceptancespecs/interfaces.md,INT-SANDBOX-CONTRACTAcceptance ("--publish 3000yields127.0.0.1:3000:3000", which is about the ARGV and stays true)