sandbox

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package sandbox provisions isolated working directories for R4 eval runs.

Per R4 spec decision D4.2, the sandbox is filesystem isolation — not a security boundary against deliberately malicious code. The v1 provider (NewWorktreeSandbox) materializes each run as a linked git worktree of the source repository, checked out detached at the repo's current HEAD, under the eval-namespaced run root (.agents/eval/runs/<run-id>/worktree), plus a scratch HOME directory so the agent CLI cannot write into the operator's real home. Two concurrent Provision calls yield working trees that cannot see each other's writes, and neither can mutate the operator's checkout (R4 requirement R4).

The detached-HEAD checkout is deliberate: gitwt's AddDetached is the documented path for ephemeral checkouts that need no branch, and it leaves no branch behind in the shared object store when the run is cleaned up. (Branch-mode worktrees would accumulate wt-* branches across runs because the gitwt seam has no branch-deletion operation — litter the plan's "ephemeral branch" sketch did not intend.)

Retention (R4 spec OQ6, R8)

Sidecars under a run dir (taskspec.yaml, eval-run.yaml, ...) are retained indefinitely — they are small and drive the dashboard. Working trees are subject to a retention window (DefaultRetention, 7 days): PruneStale removes the worktree, scratch HOME, and sandbox marker of every run older than the window while leaving the run dir and its sidecars in place. The harness calls PruneStale on the next eval run, so a crashed run cannot leak working trees beyond the window.

Provider swap point

Callers bind to the Sandbox interface only. A DockerSandbox, or the worktree-platform plan's managed-worktree provider, can replace the v1 implementation without any caller change.

Index

Constants

View Source
const DefaultRetention = 7 * 24 * time.Hour

DefaultRetention is how long a provisioned working tree may linger on disk before PruneStale removes it. Seven days is the R4 spec's OQ6 recommendation; sidecars under the run dir are never pruned by this package.

Variables

View Source
var (
	// ErrRepoPathRequired is returned by NewWorktreeSandbox when the config
	// names no source repository.
	ErrRepoPathRequired = errors.New("sandbox: repo path is required")

	// ErrNilTaskSpec is returned by Provision when the spec is nil.
	ErrNilTaskSpec = errors.New("sandbox: task spec is nil")

	// ErrEmptyTaskID is returned by Provision when the spec carries no task
	// id — the run id (and therefore the run dir) is derived from it.
	ErrEmptyTaskID = errors.New("sandbox: task spec task_id is required")
)

Typed errors callers can match with errors.Is.

Functions

This section is empty.

Types

type Config

type Config struct {
	// RepoPath is the main working tree of the source repository eval runs
	// are provisioned from (the repo whose KG generated the tasks). Required.
	RepoPath string

	// RunsRoot is the directory run dirs are created under. Defaults to
	// <RepoPath>/.agents/eval/runs, the eval-namespaced root from the R4
	// spec.
	RunsRoot string

	// Retention is the working-tree retention window PruneStale enforces.
	// Zero or negative means DefaultRetention.
	Retention time.Duration
}

Config configures a worktree sandbox.

type Instance

type Instance struct {
	// RunID uniquely identifies this eval run; it is the run dir's name.
	RunID string

	// RunDir is <RunsRoot>/<RunID>. Sidecar writers (taskspec.yaml,
	// eval-run.yaml) target this directory; it survives Cleanup.
	RunDir string

	// Workdir is the isolated working tree the agent operates in
	// (<RunDir>/worktree).
	Workdir string

	// BaseCommit is the source repo HEAD the working tree was checked out
	// at, recorded for reproducibility (R4 requirement R10).
	BaseCommit string

	// Env holds KEY=VALUE entries that pin the agent process's environment
	// to the sandbox (HOME and USERPROFILE point at the scratch home).
	// Append them after os.Environ() so they win.
	Env []string
	// contains filtered or unexported fields
}

Instance is one provisioned sandbox: the isolated working tree an agent operates in, plus the scratch environment that keeps it out of the operator's home. Instances are produced by Sandbox.Provision.

func (*Instance) Cleanup

func (in *Instance) Cleanup() error

Cleanup removes the instance's working tree, scratch home, and sandbox marker while preserving the run dir and any sidecars written into it. It is idempotent: a second call is a no-op.

type Sandbox

type Sandbox interface {
	// Provision creates an isolated working tree and scratch HOME for one
	// eval run of spec. The returned instance's Cleanup releases everything
	// except the run dir and its sidecars.
	Provision(ctx context.Context, spec *eval.TaskSpec) (*Instance, error)

	// PruneStale removes the working trees of runs older than the retention
	// window (R4 spec OQ6: default 7 days, pruned on the next eval run) and
	// returns the pruned run IDs. Sidecars are preserved.
	PruneStale(ctx context.Context) ([]string, error)
}

Sandbox provisions isolated per-run working directories (R4 spec D4.2). It is the provider swap point: the v1 worktree implementation, a future DockerSandbox, or the worktree-platform managed provider all sit behind this interface.

func NewWorktreeSandbox

func NewWorktreeSandbox(cfg Config) (Sandbox, error)

NewWorktreeSandbox opens the source repository and returns the v1 worktree Sandbox for it, applying the Config defaults (runs root, retention).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL