Files
CoreRasurae fe5941bf3c
CI / typecheck (pull_request) Successful in 1m52s
CI / security (pull_request) Successful in 2m7s
CI / build (pull_request) Successful in 1m47s
CI / quality (pull_request) Successful in 2m12s
CI / integration_tests (pull_request) Successful in 3m45s
CI / unit_tests (pull_request) Failing after 7m6s
CI / lint (pull_request) Failing after 13m19s
CI / coverage (pull_request) Has been skipped
CI / status-check (pull_request) Failing after 4s
CI / benchmark (pull_request) Failing after 26m31s
fix(agents): enforce sandbox containment inside FileAccessCore itself
Further review found that InlineFileHelperFactory.build's read_file/
write_file closures close over the FileAccessCore instance, and
FileAccessCore.write/read_window performed no containment check of their
own -- by design, per D-2's original division of labor. Inline code could
reach the closed-over core via read_file.__closure__[0].cell_contents (or
the equivalent for write_file) and call core.write(...)/core.read_window(...)
directly, bypassing SandboxRootPolicy entirely -- the same class of bypass
as the bound-method __self__ leak already fixed, reached through a
different introspection path.

FileAccessCore.read_window/write now accept a keyword-only confine: bool =
True parameter. When true (the default), the method resolves path through
the root policy itself before touching disk. The inline-code read_file
closure passes confine=safe_mode; write_file passes confine=False (it only
reaches the core after safe_mode has already refused); the built-in
_file_read_tool/_file_write_tool pass confine=False, since they perform
their own admission checks that intentionally permit escaping the sandbox
root in the tools' own unsafe mode. Any caller that reaches the core without
specifying confine -- including via closure introspection -- now lands on
the safe default.

Adds ADR-2035 D-8 recording the decision, a Behave scenario proving the
closure-introspection path is closed, and adjusts the ASV read-window
benchmarks to pass confine=False explicitly so they keep measuring pure I/O
in isolation from the already-dedicated resolve benchmark.

Refs: #93
2026-08-06 17:32:02 +00:00
..