Skip to content

bug(sandbox): workspace scope blocks toolchain temp and cache dirs (GOCACHE, TMPDIR); models waste steps relocating caches into the project #1399

Description

@dennisonbertram

Work type

Bug / regression

Observed behavior

With the default workspace sandbox (after #1397 network is allowed), Go toolchain commands fail until the model relocates caches into the workspace. Two live builds (2026-09-06, deepseek/deepseek-v4-flash) show the same detour:

go build ./...   → failed to initialize build cache at /Users/.../Library/Caches/go-build: operation not permitted
go test ./...    → go: creating work dir: mkdir /var/folders/.../T/go-build3245725623: operation not permitted
export GOCACHE=$(mktemp -d) && go build   → same (mktemp lands in $TMPDIR, outside the workspace)

The model then sets GOTMPDIR=$(pwd)/.go/tmp GOCACHE=$(pwd)/.go/cache on every command (5-10 wasted steps per run, plus a .go/ tree of 600+ files inside the project). The seatbelt profile (internal/harness/tools/sandbox_darwin.go) allows file-write* only under the workspace root; bubblewrap (sandbox_linux.go) binds / and /tmp read-only. Neither exempts the per-user cache/temp locations toolchains require ($TMPDIR, $HOME/Library/Caches, $HOME/.cache, $GOCACHE, $GOMODCACHE, npm/pip caches). Note go mod tidy succeeded because the module cache write happened to be permitted? — verify: it wrote under $HOME/go/pkg/mod; check whether that path was inside the run's HOME under the workspace or genuinely allowed.

Expected behavior

Build tools work out of the box in the workspace scope: writes to the process temp dir and the standard per-user cache directories are permitted (they hold no project data and are the conventional escape hatch every sandboxing coding agent grants), or the harness sets TMPDIR/GOCACHE/GOTMPDIR/GOMODCACHE/npm_config_cache/PIP_CACHE_DIR to a harness-owned directory outside the project tree that the profile allows. Either way the .go/ clutter inside the project must not be necessary.

Reproduction

Default permissions on macOS; prompt "create a Go module and run go build ./...". First go build fails with the build-cache error. Deterministic.

User and operational impact

Every Go (and likely Node/Python) task burns steps and money on cache relocation and litters the repository with cache directories that end up in the model's ls output and possibly commits.

Suspected seam and search evidence

seatbeltProfile (sandbox_darwin.go), bubblewrap args (sandbox_linux.go), bash env assembly in internal/harness/tools/bash_manager.go / core/bash.go. Searched rg "file-write\*|ro-bind|GOCACHE|TMPDIR" internal/harness/tools.

Blast-radius impact map

Security: cache dirs are per-user and outside the project; writes there cannot alter host config, but $HOME/.cache may hold credentials for some tools (e.g. ~/.cache/huggingface tokens) — prefer the harness-owned cache dir approach over blanket $HOME/.cache. Config/env: new default env for sandboxed commands. Clients: none. Docs: sandbox/permissions pages. Tests: profile tests; a live go build under workspace scope.

Regression test first

internal/harness/tools TestWorkspaceScope_GoBuildCacheWritable (skip without sandbox-exec/bwrap): run go env GOCACHE && go build of a trivial module under workspace scope; red today with "failed to initialize build cache".

Fix boundaries

In scope: temp and cache write access (or env redirection) for sandboxed commands. Out of scope: network policy (#1397 done), absolute-path heuristic wording.

Diagnostic and observability evidence

Run event logs from the two builds (commands above with exit codes and sandbox_network: allow).

Verification plan

Red/green; live: the tracker-API build prompt completes without any GOCACHE=/GOTMPDIR= overrides and without a .go/ directory in the project.

Rollout and rollback

Profile/env change only; revert PR.

Documentation and handoff

Engineering log; permissions docs.

Definition of done

  • Go build/test work in workspace scope without env overrides
  • No cache directories created inside the project
  • Regression test green

Process acknowledgement

  • I will preserve the failing regression test, update the issue if the root cause changes, and record any newly discovered bug as its own issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinguxUser experience improvements

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions