2.3 KiB
The test sandbox is enforced via four-layer rules (FR1-FR4) — see the styleguide
The 4-Layer Model
| Layer | Mechanism | Where | Default-on? |
|---|---|---|---|
| Layer 1 | Python runtime file-I/O guard (sys.addaudithook) |
tests/conftest.py:_sandbox_audit_hook |
Yes |
| Layer 2 | isolate_workspace autouse + pyproject.toml --basetemp |
tests/conftest.py + pyproject.toml |
Yes |
| Layer 3 | OS-level restricted-token PowerShell wrapper | scripts/run_tests_sandboxed.ps1 |
Opt-in |
| Layer 4 | Static audit script (CI gate) | scripts/audit_test_sandbox_violations.py |
Yes (informational) / opt-in (--strict) |
Layer 1 + Layer 2 + Layer 4 are file-presence-on = enabled (delete the relevant file to disable). Layer 3 requires explicit invocation.
The --config CLI Flag (replaces SLOP_CONFIG)
The historical SLOP_CONFIG env var has been removed from src/paths.py. The CLI flag --config <path> is now the ONLY supported mechanism for overriding the default <project_root>/config.toml location.
# Use the default <project_root>/config.toml
uv run python sloppy.py
# Override
uv run python sloppy.py --config /path/to/your/config.toml
sloppy.py calls paths.set_config_override(Path(args.config).resolve()) AFTER parse_args() and BEFORE any from src.gui_2 import App import. This is the only way to override the config path in production.
The --basetemp Rule
pyproject.toml sets addopts = "--basetemp=tests/artifacts/_pytest_tmp". This redirects pytest's tmp_path and tmp_path_factory fixtures (which default to %TEMP%\pytest-of-<user>\ on Windows) into ./tests/artifacts/. This is what allows the Layer 1 allowlist to be a single rule: "anything under ./tests/ is allowed."
Layer 1 Audit Hook Contract
tests/conftest.py:_sandbox_audit_hook is a sys.addaudithook callback. It fires on every open() call. Behavior:
- Reads (mode
r,rb): pass through, no check - Writes (mode contains
w,a,x,+): check path - Allowed if path resolves under:
<project_root>/tests/- Path contains
.pytest_cache,__pycache__,.coverage,.slop_cache, or.ruff_cache - Original path string starts with
\\.\(Windows device namespace) or/dev/(Unix device namespace)
- Blocked otherwise: raises
RuntimeError("TEST_SANDBOX_VIOLATION: attempted to write to <path>...")