Skip to content

Enforce leased filesystem write-roots against the worker's actual diff #440

Description

@hadamrd

Customer + failure mode: an operator dispatches a worker into an isolated worktree with a CapabilityPolicy whose filesystem.write_roots names exactly where it may write. render_worker_settings (worker_worktree.py) path-scopes Write/Edit to those roots, but the same renderer grants whole Bash(*) whenever ANY write root is present, because Claude's Bash permission grammar matches command strings, not paths (see the _WRITE_TOOLS note at worker_worktree.py:62-70). So a worker can cd out of its worktree and write anywhere on the host via Bash, and the loop currently TRUSTS the resulting changed-file set: no code compares the worker's produced diff against the write_roots it was leased. The preventive layer is necessarily incomplete; this epic adds the missing DETECTIVE control. After a worker runs, compute its real changed-file set, compare each path against the leased policy's write_roots, and treat any out-of-bounds path as a sandbox violation that blocks advancement and quarantines the worktree instead of merging it. Decomposes into: (1) a pure write_root_violations predicate; (2) a git-backed changed-file collector; (3) a merge-gate enforcer that fails-and-quarantines on a violation. Each ships as its own PR; only the sub-tickets are dispatchable.

Customer story

An operator dispatching workers on a real repository without trusting their context or code: the worktree allow-list scopes Write/Edit, but Bash escapes path-scoping, so I have no signal when a worker writes outside the roots it was leased — I need the diff itself audited against the lease before it can advance.

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

    axis:sandboxed-worker-executionValue axis: sandboxed worker executionepicMulti-PR umbrella tracking a major theme

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions