Skip to content

fix(setup): fix the agent sandbox and give the agent more facts (6/6) - #899

Draft
atornsii wants to merge 3 commits into
atorns/agent-5-opencode-handlerfrom
atorns/agent-6-run-fixes
Draft

atornsii wants to merge 3 commits into
atorns/agent-5-opencode-handlerfrom
atorns/agent-6-run-fixes

Conversation

@atornsii

@atornsii atornsii commented Oct 20, 2026 •

Copy link
Copy Markdown

This fixes problems that test runs found.

Sandbox (run 8)

  • Resolving a path reads the metadata of each parent folder. The sandbox denied it, so realpath, uv, and git failed with "Operation not permitted", and the agent fell back to pip. The parents of each open folder now allow metadata reads, but not their contents.
  • ~/.local/share/uv is now writable, because uv writes there when it inspects a managed Python.
  • The sandbox now closes /private/tmp, where the agent found another program's files. Each run gets its own temporary folder there, which OpenCode gets as TMPDIR.
  • The loopback proxy no longer writes "http: proxy error" lines into the wizard's screen.

Facts (runs 5, 7, and 8)

The facts message now gives the LaunchDarkly project and environment, and the names (never the values) of the model provider keys that are set in the environment or in the project's .env. It tells the agent not to look for keys, print the environment, or ask for a key, and to use $TMPDIR. Before, the agent spent about 25 tool calls finding the project, and it printed the environment or asked the user to paste a key. ldcli setup agent takes --project and --environment for the same facts.

Testing

Sandbox tests now also check realpath in the project, a closed file in /private/tmp, and a writable run folder. uv python find, realpath, git status, and OpenCode work in the sandbox in the test app. New tests cover the provider key names and the facts.

Diagram

flowchart TD
  subgraph facts [Facts for the agent]
    cmds["commands.go<br/>startAgent: project, environment"]:::chg
    cmdag["cmd/setup/agent.go<br/>agentTask with project, environment<br/>--project, --environment"]:::chg
    keys["provider_keys.go<br/>ProviderKeys, dotEnvNames"]:::new
    task["agent.go<br/>Task.ProjectKey, EnvironmentKey<br/>Task.ProviderKeys"]:::chg
    prompt["prompt.go<br/>BuildFacts: project, environment<br/>key names, TMPDIR note"]:::chg
    cmds -->|agentTask| cmdag
    cmdag -->|ProviderKeys| keys
    cmdag -->|fills Task| task
    prompt -->|reads Task| task
  end
  subgraph box [Sandbox and screen]
    srv["server.go<br/>TMPDIR = box.TempDir"]:::chg
    sb["sandbox.go<br/>parentFolders<br/>RunTemp, sharedTemp<br/>.local/share/uv writable"]:::chg
    proc[["opencode serve<br/>own TMPDIR"]]:::ext
    tmp[["/private/tmp<br/>closed, except the run folder"]]:::ext
    proxy["relay_proxy.go<br/>ErrorLog: discard"]:::chg
    srv -->|sandboxCommand| sb
    srv -->|sets TMPDIR| proc
    sb -.->|profile rules| tmp
  end
  classDef new fill:#e6f0fa,stroke:#1d6fb8,stroke-width:2px,color:#19202b
  classDef chg fill:#fbf1e1,stroke:#a86a12,stroke-width:2px,color:#19202b
  classDef earlier fill:#ffffff,stroke:#7a8494,stroke-dasharray:5 4,color:#19202b
  classDef ext fill:#eceefa,stroke:#4e5a9c,stroke-width:2px,color:#19202b
Loading

Blue boxes are new files, orange boxes are changed files, dashed boxes are files from an earlier PR, and purple boxes are outside ldcli. A solid arrow goes from the caller to the code that it calls. A dashed arrow shows data that moves without a direct call.

The facts group starts in the wizard. commands.go passes the selected project and environment to agentTask, which also calls ProviderKeys to get the names of the provider keys that are set. agentTask puts these values in the Task, and BuildFacts writes them into the first message. In the sandbox group, sandboxCommand now creates a run folder in /private/tmp and closes the rest of that folder. It returns the run folder as TempDir, and server.go gives it to OpenCode as TMPDIR. The profile also allows metadata reads on parent folders, so realpath, uv, and git work. relay_proxy.go stops writing proxy errors on the wizard screen.

The two groups do not depend on each other. The facts group changes the wizard from #895 and the prompt from #897. The sandbox group changes files from #896 and #897.

Stack

This is one of six PRs for the ldcli setup agent. Review and merge them in order, after #877 (Go 1.26):

  1. OpenCode adapter
  2. Wizard agent step
  3. macOS sandbox
  4. AI SDK and relay
  5. OpenCode handler
  6. Run fixes

They replace #876 and #878.

🤖 Generated with Claude Code

atornsii and others added 2 commits October 19, 2026 23:43
A test run found three problems with the macOS sandbox.

Resolving a path reads the metadata of every parent folder, and the
sandbox denied it. So realpath, uv, and git failed with "Operation not
permitted", and the agent fell back to pip and edited pyproject.toml by
hand. The parents of each open folder now allow metadata reads, but not
their contents.

uv writes to ~/.local/share/uv when it inspects a managed Python, and
the sandbox opened that folder read-only. It is now writable.

The agent searched /private/tmp and found another program's files
there. The sandbox now closes /private/tmp and gives the run its own
temporary folder in it, which OpenCode gets as TMPDIR.

The loopback proxy also wrote "http: proxy error" lines into the
wizard's screen. It now discards its log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In test runs, the agent spent about 25 tool calls finding the project
and environment that setup used, and it printed the environment or
asked the user to paste an API key to learn whether one was set.

The facts message now also gives the LaunchDarkly project and
environment, and the names of the model provider keys that are set in
the environment or in the project's .env. It never gives a value. It
tells the agent not to look for keys, print the environment, or ask for
a key, and to use $TMPDIR instead of /tmp.

`ldcli setup agent` takes --project and --environment for the same
facts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@atornsii
atornsii added this pull request to stack #902 October 20, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant