Keep the sandbox's own chatter off the stream the command owns

stdout inside the container belongs to the command that ran. Two readers take it as
data: ai-sandbox-autophase's preflight reads its answer from that stream, and
progress.mjs reads the child pi's JSON event stream from it. Five notices in the
pi-seeding block went there instead of stderr, and the steady state (host file
unchanged, so cur = prev) prints one on *every* pi-bridged run -- the driver refused a
working sandbox on every project. They all go to stderr now, like log() and fail().

The preflight takes the aisb-ok marker from wherever it appears instead of insisting it
come first: a banner from an older image or from the user's own launcher is warned about
and quoted back, because that stream is parsed as data in every unit. It still refuses on
a non-zero exit, on silence, and on a launcher that runs no command -- the failures that
would repeat in every unit -- and quotes the foreign stdout instead of a bare exit code.

The same block, second contract: the thinking level is policy, so a home the sandbox
creates gets it on the *first* seed, not one run later via the merge.

tests/unit/06_entrypoint.sh runs the seeding block with the two streams split and asserts
stdout empty in every state (cold, steady, edited inside, unparseable, level changed), and
greps the entrypoint for any [aisb] line without >&2. tests/unit/10_autophase.sh adds the
noisy and the yapping launcher fixtures.

LLM-Generated: true
This commit is contained in:
2026-10-30 22:53:57 -04:00
parent 8b70967907
commit 90d98dcc9e
5 changed files with 171 additions and 11 deletions
+42
View File
@@ -89,6 +89,28 @@ broken-sandbox() {
return 125
}
EOF
# A launcher that puts a notice of its own on stdout before the command runs -- the shape the
# sandbox entrypoint had, where the pi-config notice came first on every bridged run. The
# sandbox does answer, so the run is workable: what the driver owes the user is a warning that
# names the pollution (the same stream is parsed as data every unit), not a refusal.
cat > "$WORK/rc/noisy.bash" <<'EOF'
noisy-pi() {
local -a cmd=()
while (($#)); do case "$1" in --) shift; cmd=("$@"); break ;; *) shift ;; esac; done
printf 'LAUNCH cmd=%s\n' "${cmd[0]:-none}" >> "${AISB_AP_TRACE:-/dev/null}"
printf '[aisb] pi config: refreshed models.json from the host config\n'
"${cmd[@]}"
}
EOF
# The same talking with no answer in it. That is a broken launcher, and it still has to stop
# the run -- with the foreign stdout quoted back rather than a bare exit code.
cat > "$WORK/rc/yap.bash" <<'EOF'
yap-pi() {
local -a cmd=()
while (($#)); do case "$1" in --) shift; cmd=("$@"); break ;; *) shift ;; esac; done
printf 'hello, I am a launcher that runs nothing\n'
}
EOF
# --- the harness and the git shim -------------------------------------------
cat > "$WORK/bin/pi" <<'EOF'
@@ -515,6 +537,26 @@ if grep -q 'cmd=pi' "$TRACE"; then _bad "no unit runs"; else _ok "no unit runs";
T_PREFLIGHT=0 ap_run --max-units 1
assert_rc 0 "--no-preflight is available for the runs that cannot afford it"
t_name "a sandbox that talks on stdout is named, not refused"
cd "$PROJ6" || exit 1
: > "$TRACE"
T_CMD=noisy-pi T_RC="$WORK/rc/noisy.bash" ap_run --max-units 1
assert_rc 0 "a launcher that answers is a working sandbox, banner or not"
assert_contains "aisb-ok" "the answer is taken from wherever it is in the stream"
assert_contains "put lines of its own on stdout" "and the pollution itself is named"
assert_contains "> [aisb] pi config: refreshed" "with the offending line quoted back"
if grep -q 'cmd=pi' "$TRACE"; then _ok "the pipeline went on to run its unit"; else _bad "the pipeline went on to run its unit: $(tr '\n' ';' < "$TRACE")"; fi
t_name "a launcher that talks instead of answering is still refused"
cd "$PROJ6" || exit 1
: > "$TRACE"
T_CMD=yap-pi T_RC="$WORK/rc/yap.bash" ap_run --max-units 1
assert_rc 1 "no aisb-ok answer means no run"
assert_contains "preflight failed" "and it says so"
assert_contains "no aisb-ok answer at all" "naming what the check was looking for"
assert_contains "> hello, I am a launcher that runs nothing" "quoting the stdout that came back instead"
if grep -q 'cmd=pi' "$TRACE"; then _bad "no unit runs"; else _ok "no unit runs"; fi
t_name "bad usage is refused before anything happens"
cd "$PROJ6" || exit 1
ap_run --not-a-flag