feat(prompt): tell the agent what its sandbox can run
Nightly Build / build (push) Successful in 8m6s

The agent had no way to know its container ships ffmpeg, ripgrep or
tesseract, so it either declined work it could do or spent a round finding
out. This adds a command list to the system prompt as a **discovery hint** —
explicitly not an inventory.

Every decision follows from it being a hint:

- The allowlist (~35 entries, `container/commands.rs`) is the curation; a
  full PATH dump is 800 entries of coreutils noise. The probe exists so the
  list cannot *lie*, not so it can discover: `command -v` at login means we
  never announce something a container recreate threw away.
- The rendered prose says the list is partial and names `command -v`, so a
  tool outside the allowlist costs one check rather than a wrong conclusion.
  An empty probe renders as an explicit "could not be read", never as
  silence under a heading promising a list.
- Order is the allowlist's own, grouped by kind of work — the grouping is
  the curation, and the reader is a model, not a grep.
- Staleness is cheap both ways, so there is no invalidation machinery: a
  login-time snapshot on `UserContext`, non-fatal, refreshed at next login.

The gate is the tool, not the sentinel. Every AGENT.md carries
`common/sandbox.md` — the four system agents included — and the section is
emitted iff the turn's model is shown `execute_cmd`, derived from
`allow_tools` plus the security group's visibility filter for a root turn
and from `child_defs` for a sub-agent: always the same definitions the model
will see. `has_execute_cmd` therefore joins the PrefixCache key, since the
group is switchable mid-conversation and that switch already rewrites the
tool payload in the same provider cache.

The fragment holds only the heading and one stable sentence; every
conditional claim lives in the renderer, because prose promising
`sudo apt-get install` is not the renderer's to retract when the tool is
absent. `execute_cmd`'s own description loses `(python + node available)`:
its job is steering away from the shell, and a capability advertisement
diluted it.
This commit is contained in:
Daniele
2026-08-09 09:49:50 +01:00
parent c27da4e6ab
commit 5765941758
31 changed files with 459 additions and 38 deletions
+2
View File
@@ -77,6 +77,8 @@ To change what gets notified, edit `data/notifications.md`.
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
## System configuration
Configuration tools are hidden by default to keep context small. Call `activate_tools(["config"])` to load them when you need to manage the instance's setup — plugins, scheduled jobs, secrets — then work normally.
+2
View File
@@ -122,3 +122,5 @@ No other output — the file is the report.
<!-- INCLUDE: common/mcp.md -->
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
+2
View File
@@ -66,3 +66,5 @@ _Date: 2026-06-03_
<!-- INCLUDE: common/mcp.md -->
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
+5
View File
@@ -0,0 +1,5 @@
# Your sandbox
You work inside your own private Linux container: your home, the shared folders and the projects you belong to are mounted in it, and `execute_cmd` runs there.
<!-- SANDBOX_COMMANDS -->
+2
View File
@@ -121,3 +121,5 @@ Assume the person you are writing about could one day read this. Write something
None. There is no filesystem, no memory, no search, no connector, no notification, nothing to call. Everything you need is in the message you were given, and the report is your answer — not something you save anywhere.
If you find yourself wanting to check something, you cannot, and that is the design. Say what the transcript supports, say plainly when it does not support something, and stop there.
<!-- INCLUDE: common/sandbox.md -->
+2
View File
@@ -142,6 +142,8 @@ You are producing **structured data, not a message to the user.** The main agent
<!-- INCLUDE: common/memory.md -->
<!-- INCLUDE: common/sandbox.md -->
You read memory primarily to evaluate relevance. Write to memory only when you discover something genuinely new and durable — for example, a new contact who wrote for the first time, or a project status update that changes what the user needs to monitor.
---
+2
View File
@@ -15,3 +15,5 @@ You do NOT delegate to other agents. Do the work yourself.
<!-- INCLUDE: common/mcp.md -->
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
+2
View File
@@ -85,6 +85,8 @@ There may be other helpers in the household's team — each good at different th
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
---
## Shared folders
+2
View File
@@ -6,6 +6,8 @@ You always run **for one specific user**, over `user-memory/` in their own encry
<!-- INCLUDE: common/memory-lint.md -->
<!-- INCLUDE: common/sandbox.md -->
---
## Your store
+2
View File
@@ -6,6 +6,8 @@ The shared store belongs to nobody in particular, so this pass runs as the **adm
<!-- INCLUDE: common/memory-lint.md -->
<!-- INCLUDE: common/sandbox.md -->
---
## Your store
+2
View File
@@ -14,6 +14,8 @@ The user is talking to a single assistant that already knows the project. They s
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
## System configuration
Configuration tools are hidden by default to keep context small. Call `activate_tools(["config"])` to load them all at once when you need to manage the system's setup — registering/removing MCP servers, configuring plugins, and managing scheduled (cron) jobs and secrets — then operate normally.
+2
View File
@@ -118,3 +118,5 @@ If the main agent calls you again on a related topic, check if a relevant scratc
<!-- INCLUDE: common/mcp.md -->
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
+2
View File
@@ -10,6 +10,8 @@ You are a staff-level software architect. You receive a change request, study th
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
## Available agents
Delegate work to these task specialists via `execute_task` / `execute_subtask`:
+2
View File
@@ -12,6 +12,8 @@ You work on **any file type** in any project: Rust, Swift, Python, JavaScript/Ty
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
---
## Project context
+2
View File
@@ -126,6 +126,8 @@ Do not wait for permission to use a tool that would clearly help.
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
## Persistent memory
<!-- INCLUDE: common/memory.md -->
+2
View File
@@ -12,6 +12,8 @@ You do **not** implement features yourself except for trivial scaffolding (creat
<!-- INCLUDE: common/skills.md -->
<!-- INCLUDE: common/sandbox.md -->
## Available agents
Delegate work to these task specialists via `execute_task` / `execute_subtask`: