make xhigh the sandbox's thinking, and stop settings.json freezing
Two changes, one bug found through the other.
Thinking is policy now: defaultThinkingLevel is xhigh unless you say otherwise
(thinking / --thinking / AISB_THINKING, with pi's levels plus 'host' to decline
and 'off' meaning pi's own no-reasoning level). It is written into the bridged
settings and re-applied by the entrypoint on every run, so a run cannot set its
own reasoning down for the runs after it. Unknown levels are refused with the
list to pick from. Nothing is written for codex, claude or a command after --,
and --no-pi-config declines it along with the bridge, because pi's own defaults
are what that flag asks for.
The reason xhigh had never reached a sandbox is worse than a missing default:
settings.json was managed as one whole file, and pi rewrites its own settings
(a theme change, "seen the changelog"), so the first such write matched nothing
and froze every host preference out permanently -- provider, model, thinking
budgets and level included, a real session left holding just
{"lastChangelogVersion": "1.4.0"}. It is merged per key instead, against a copy
of what we last wrote: a key edited in the sandbox stays edited, a key never
touched follows the host again, an untouched key the host dropped is dropped, a
key pi invented survives, and a file with no base copy takes the host values --
which repairs the volumes already frozen. Unparseable JSON is re-seeded with a
warning since pi cannot use it either; a file the container cannot read is
reported with the fix, because nothing inside the sandbox can repair one.
One trap worth remembering: the seeding script is passed to bash -c in single
quotes, so a single quote inside it closes the argument early and the rest runs
in the outer shell -- valid bash, wrong program, clean bash -n and clean
shellcheck. tests/unit/06_entrypoint.sh extracts the seeding script and asserts
it is quote-free, and extracts the merge program to test its semantics without
a container; tests/e2e/12_sandbox.sh does the same in a real run, including
forcing the level back after the sandbox sets it to off.
LLM-Generated: true
This commit is contained in:
+28
-3
@@ -50,12 +50,37 @@ pi --allow aipi.reeseapps.com --pi-token-env GW_TOKEN
|
||||
# pass it yourself, which is what you want in shared scripts
|
||||
pi --allow aipi.reeseapps.com --env AI_API_TOKEN --no-pi-token-env
|
||||
|
||||
# no bridge: pi starts with its own defaults inside the volume
|
||||
# no bridge: pi starts with its own defaults inside the volume (and no thinking policy)
|
||||
pi --no-pi-config --allow aipi.reeseapps.com
|
||||
```
|
||||
|
||||
Edits made inside the sandbox are kept; changes to the host config are picked up on
|
||||
the next run; deleting `~/.pi/agent/models.json` inside the sandbox re-seeds it.
|
||||
`models.json` is kept in step with the host unless you edit it in the sandbox, where your
|
||||
edit then wins; deleting it inside the sandbox re-seeds it. `settings.json` is merged per
|
||||
key, so a preference you changed in the sandbox stays changed and every one you did not
|
||||
touch follows the host again.
|
||||
|
||||
### How hard it thinks
|
||||
|
||||
`defaultThinkingLevel` is policy, not preference: `xhigh` unless you say otherwise, and
|
||||
re-applied every run rather than remembered from whatever the last sandbox set.
|
||||
|
||||
```bash
|
||||
# the everyday case: xhigh
|
||||
pi --allow aipi.reeseapps.com
|
||||
|
||||
# one-off: the top of pi's range, or no reasoning at all for a mechanical job
|
||||
pi --thinking max --allow aipi.reeseapps.com
|
||||
pi --thinking off --net allow --allow registry.npmjs.org -- npm ci
|
||||
|
||||
# let settings.json decide, the way it did before this was policy
|
||||
pi --thinking host --allow aipi.reeseapps.com
|
||||
|
||||
# per repo, chosen by .ai-sandbox/config
|
||||
# thinking = high
|
||||
```
|
||||
|
||||
Nothing is written for `codex`, `claude` or a command after `--`: those read their own
|
||||
configuration and ai-sandbox does not touch it.
|
||||
|
||||
## Your skills and standing instructions
|
||||
|
||||
|
||||
@@ -88,10 +88,14 @@ Be honest about these, and design your work accordingly.
|
||||
uses is your real one. So the bridged config is a convenience, not a narrower
|
||||
credential: prefer a per-sandbox token from your gateway if it can mint one, and
|
||||
note that a bridged run whose token variable is unset or empty is refused rather
|
||||
than started. Sandboxed edits to `~/.pi/agent` persist in the home volume and are
|
||||
kept over later host changes (see the README), which is convenience with a
|
||||
consequence: a hostile run could rewrite the sandboxed pi config for later runs of
|
||||
that volume. `--ephemeral-home` removes that.
|
||||
than started. Sandboxed edits to `~/.pi/agent` persist in the home volume and win
|
||||
over later host changes (see the README), which is convenience with a consequence: a
|
||||
hostile run could rewrite the sandboxed pi config for later runs of that volume —
|
||||
point `baseUrl` at a host it controls, swap a model, change the provider. Merging
|
||||
`settings.json` per key limits this (a run can only pin the keys it actually writes,
|
||||
and everything else keeps following your host config), and `defaultThinkingLevel` is
|
||||
re-forced every run so a run cannot quietly lower the reasoning of the next. It is
|
||||
not eliminated: `--ephemeral-home` removes it, and `inspect` shows what is bridged.
|
||||
|
||||
## Residual risk rating
|
||||
|
||||
|
||||
Reference in New Issue
Block a user