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:
@@ -125,7 +125,18 @@ networking or the image, `make e2e` green too.
|
||||
anywhere in there silently closes the argument and the rest runs in the *outer* shell
|
||||
— valid bash, wrong program, clean `bash -n` and clean shellcheck. Nothing in it may
|
||||
use `'`; jq programs there are written unquoted (`.defaultThinkingLevel=\$lvl`), and
|
||||
`tests/unit/06_entrypoint.sh` fails the build if that ever changes.
|
||||
`tests/unit/06_entrypoint.sh` fails the build if that ever changes. (It bit once while
|
||||
editing a comment: one apostrophe in a word like `pi's` is enough.)
|
||||
**Stdout inside the container belongs to the command that ran.** Everything the sandbox
|
||||
says about itself goes to stderr — `log()` and `fail()` do, and so must every new line,
|
||||
because the driver's preflight reads its answer from that stream and progress.mjs reads the
|
||||
child pi event stream from it. The pi-seeding notices were on stdout once, and the steady
|
||||
state (host file unchanged, so `cur = prev`) prints one on *every* pi-bridged run: it made
|
||||
`ai-sandbox-autophase` refuse a working sandbox on every project. `tests/unit/06_entrypoint.sh`
|
||||
now runs the seeding block with the two streams split and asserts stdout empty in each state
|
||||
(cold, steady, edited-in-sandbox, unparseable, level changed), and greps the entrypoint for
|
||||
any `[aisb]` line without `>&2`. Same block, second contract: the thinking level is policy,
|
||||
so it is written on the *first* seed too, not only by the merge on the second run.
|
||||
* `split_target()` / `classify_allows()` — the mapping from what the user typed to
|
||||
what the firewall and the proxy enforce.
|
||||
* `build_argv()` — every isolation flag lives here.
|
||||
@@ -189,6 +200,13 @@ networking or the image, `make e2e` green too.
|
||||
the preflight name it, and every child starts `</dev/null` so the launcher cannot put
|
||||
the terminal back. Keep the `"$@"` in every launcher this repo prints — `install.sh`,
|
||||
`README.md`, `docs/recipes.md`.
|
||||
- **The preflight reads the marker, not the first line.** `ap_preflight` asks for one
|
||||
sandboxed shell and takes the line starting `aisb-ok` wherever it appears, because a banner
|
||||
from an older image or from a launcher of the user's own is not a broken sandbox — it is
|
||||
warned about and quoted back, since the same 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: those
|
||||
are the failures that would repeat in every unit. Tests: the noisy and yapping launcher
|
||||
fixtures in `tests/unit/10_autophase.sh`.
|
||||
- **The push is the delivery contract.** `ap_push_pending` runs at start, at every
|
||||
phase boundary and at end of run; start is a warning, the boundary and the end are
|
||||
fatal, because exiting 0 with the work unpushed is the silent miss this script
|
||||
|
||||
Reference in New Issue
Block a user