stop the driver hanging on a terminal and on a launcher
ai-sandbox-autophase could sit forever, printing nothing, in two places that are both before the first unit -- which is why both looked like a script that "does nothing". The rc probe ran `timeout 15 bash -ic` in front of the user's terminal. An interactive bash calls tcsetpgrp() to take that terminal, is in its background, and is stopped for trying; a stopped process does not take SIGTERM, so the timeout waited in front of it and the driver waited on the command substitution behind it. It now runs in its own session (setsid), with stdin closed, under `timeout -k`, and reads the definition from a temp file rather than a pipe, because a grandchild an rc file leaves behind holds a pipe's EOF open long after the shell it came from has been reaped. A launcher is called *with* the run, and a function ending at `--env NAME` -- the shape everyone writes for typing by hand, including every example this repo printed -- discards the flags and the in-container command. The container then starts the image's default harness with no prompt and, with --no-interactive gone, the terminal attached: an agent waiting for keystrokes behind a pipe nobody reads. `ap_forwards_args` checks the captured definition, --status and the preflight name it with the one-line fix, and every child now starts with stdin on /dev/null so a launcher cannot put the sandbox back on the keyboard. Aliases and whole command lines need no forwarding: the shell appends the words to those. Tests: a launcher fixture that drops its arguments, one that leaves a process behind, and shape assertions on ap_probe_rc. LLM-Generated: true
This commit is contained in:
+16
-4
@@ -243,15 +243,23 @@ The nightly case: `.agents/phases/todo/` full of task files, nobody watching, an
|
||||
agent that must not be able to reach the git remote or touch the host.
|
||||
|
||||
```bash
|
||||
# ~/.bashrc.d/ai-sandbox.bash -- the launcher, the way you already write it
|
||||
# ~/.bashrc.d/ai-sandbox.bash -- the launcher, the way you already write it, plus the
|
||||
# "$@" that lets a run hand it the command to sandbox
|
||||
sandbox-pi () {
|
||||
export AI_API_TOKEN=$(pass aipi/dev-token)
|
||||
ai-sandbox --allow aipi.reeseapps.com --allow github.com \
|
||||
--allow pi.dev --allow release-assets.githubusercontent.com \
|
||||
--env AI_API_TOKEN
|
||||
--env AI_API_TOKEN "$@"
|
||||
}
|
||||
```
|
||||
|
||||
A function written for typing by hand usually stops at `--env AI_API_TOKEN`, and that is
|
||||
the one thing the driver cannot work with silently: everything after the function name is
|
||||
the run, so dropping it starts the image's default harness with no prompt. With a terminal
|
||||
behind it that is an interactive agent waiting for input, its output going into a pipe the
|
||||
driver is reading — a run that appears to do nothing at all. `--status` names a launcher
|
||||
that takes no arguments and the preflight refuses it; the fix is the `"$@"` above.
|
||||
|
||||
```bash
|
||||
cd ~/Projects/foo
|
||||
ai-sandbox-autophase --status # what it resolved, what is pending, the git plan
|
||||
@@ -270,7 +278,11 @@ sandbox-pi --no-tty --no-interactive -- pi --no-approve --session-dir .agents/ph
|
||||
`pass` runs again per unit, so a run that starts at 23:00 is not holding a token
|
||||
fetched at 09:00. Reading the definition is all the probe does: `--status` and
|
||||
`--dry-run` never call the launcher, fetch a token, build an image or start a
|
||||
container.
|
||||
container. It reads it in a session of its own with no stdin — an interactive bash
|
||||
started from a terminal tries to take that terminal, gets stopped for trying, and a
|
||||
stopped process does not take the timeout meant for it. Every child is started with its
|
||||
stdin on `/dev/null` for the same reason in the other direction: nothing inside the
|
||||
sandbox can be waiting for your keyboard.
|
||||
|
||||
| you want | flag |
|
||||
|---|---|
|
||||
@@ -320,7 +332,7 @@ A project whose tests need something the image lacks gets it from the launcher:
|
||||
sandbox-pi () {
|
||||
export AI_API_TOKEN=$(pass aipi/dev-token)
|
||||
ai-sandbox --allow aipi.reeseapps.com --allow pypi.org --allow files.pythonhosted.org \
|
||||
--install 'python3-pip ripgrep' --env AI_API_TOKEN
|
||||
--install 'python3-pip ripgrep' --env AI_API_TOKEN "$@"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user