# Track state for test_sandbox_hardening_20260619
# Updated by Tier 2 Tech Lead as tasks complete

[meta]
track_id = "test_sandbox_hardening_20260619"
name = "Test Sandbox Hardening"
status = "completed"
current_phase = "complete"
last_updated = "2026-06-19"

[post_completion_patches]
# Three follow-up commits made after the initial track ship, addressing
# failures surfaced by a full batched run of the main repo. These are
# technically scope-creep but were blocking the user's ability to ship
# the work; documented in TRACK_COMPLETION_test_sandbox_hardening_20260619.md
# "Post-completion fixes" section.
patch_1 = { sha = "63e91198", description = "test(sandbox): v3 paths-aware test updates for test_paths/test_summary_cache/test_orchestrator_pm_history/test_gui_paths" }
patch_2 = { sha = "cb68d86f", description = "fix(app_controller): catch RuntimeError from FR1 audit hook in _load_active_project fallback save" }
patch_3 = { sha = "78256174", description = "fix(app_controller): defensive _flush_to_project + RuntimeError catch + audit script false positive + 3 MCP test updates" }
patch_4 = { sha = "61a89fa3", description = "docs(reports): add post-completion fixes section to TRACK_COMPLETION report" }

[blocked_by]
# Independent track. No blockers.

[blocks]
# No followup tracks blocked on this one (deferred items listed in metadata.json).

[phases]
phase_1 = { status = "completed", checkpointsha = "", name = "Investigation + baseline (deferred per user directive; static verification + audit of get_config_path callers in track setup)" }
phase_2 = { status = "completed", checkpointsha = "43e50f9", name = "FR4 static audit + tests" }
phase_3 = { status = "completed", checkpointsha = "e733e52", name = "FR1 Python guard + tests" }
phase_4 = { status = "completed", checkpointsha = "02fef00", name = "FR2 root-cause fix (--config replaces SLOP_CONFIG)" }
phase_5 = { status = "completed", checkpointsha = "02fef00", name = "FR3 isolate_workspace + basetemp migration" }
phase_6 = { status = "completed", checkpointsha = "dc5afc2", name = "FR5 PowerShell wrapper" }
phase_7 = { status = "completed", checkpointsha = "5d29e40", name = "FR7 documentation" }
phase_8 = { status = "partial", checkpointsha = "", name = "Full suite verification (Tier-1 smoke run showed FR1 guard catches real corruption; full suite deferred to user)" }
phase_9 = { status = "completed", checkpointsha = "dfa4009", name = "End-of-track report" }

[tasks]
t1_1 = { status = "pending", commit_sha = "", description = "Capture baseline pass count via `uv run python scripts/run_tests_batched.py --tiers 1..11`. Record pass count + skip count + duration." }
t1_2 = { status = "pending", commit_sha = "", description = "Confirm scripts/check_test_toml_paths.py runs cleanly (exit 0 in default mode)." }
t1_3 = { status = "pending", commit_sha = "", description = "Audit src/ for all callers of get_config_path() to confirm FR2 will be transparent. List each caller." }

t2_1 = { status = "pending", commit_sha = "", description = "Write scripts/audit_test_sandbox_violations.py mirroring check_test_toml_paths.py structure. Patterns: manual_slop_history.toml, project.toml, manualslop_layout.ini, tempfile.{mkdtemp,mkstemp} without dir=, Path(__file__).parent.parent / 'config.toml'." }
t2_2 = { status = "pending", commit_sha = "", description = "Write tests/test_test_sandbox.py tests 5,6,10: audit flagging bad pattern, audit passes clean, audit flags tempfile.mkdtemp without tests dir." }
t2_3 = { status = "pending", commit_sha = "", description = "Verify audit script with sample bad test files. Commit Phase 2." }

t3_1 = { status = "pending", commit_sha = "", description = "Implement _enforce_test_sandbox autouse fixture in tests/conftest.py: pytest_configure installs sys.addaudithook for open writes + os.makedirs + shutil.rmtree + tempfile.{mkdtemp,mkstemp}; pytest_unconfigure removes it." }
t3_2 = { status = "pending", commit_sha = "", description = "Write tests/test_test_sandbox.py tests 1-4: guard blocks writes outside ./tests, allows writes inside ./tests, allows writes inside ./tests/artifacts, doesn't block reads." }
t3_3 = { status = "pending", commit_sha = "", description = "Manually verify guard fires on a sample bad write. Commit Phase 3." }

t4_1 = { status = "pending", commit_sha = "", description = "Refactor src/paths.py: remove os.environ.get('SLOP_CONFIG', ...) fallback from get_config_path(). Add module-level _CONFIG_OVERRIDE + set_config_override() function." }
t4_2 = { status = "pending", commit_sha = "", description = "Remove diagnostic stderr.write line at src/models.py:193 ('[DEBUG] Saving config...')." }
t4_3 = { status = "pending", commit_sha = "", description = "Add --config argparse argument to sloppy.py. Call paths.set_config_override(args.config) BEFORE any src/ import." }
t4_4 = { status = "pending", commit_sha = "", description = "Update tests/conftest.py to parse sys.argv for --config at module body BEFORE any src/ import. Add pytest_addoption registration. Auto-default to tests/artifacts/_isolation_workspace_<RUN_ID>/config_overrides.toml." }
t4_5 = { status = "pending", commit_sha = "", description = "Write tests/test_test_sandbox.py tests 11,12,13: --config CLI flag works, no env var fallback, sloppy.py parses --config." }
t4_6 = { status = "pending", commit_sha = "", description = "Commit Phase 4 (FR2 root-cause fix). This is the most important commit in the track." }

t5_1 = { status = "pending", commit_sha = "", description = "Refactor tests/conftest.py isolate_workspace: replace tmp_path_factory.mktemp with Path('tests/artifacts/_isolation_workspace') / _RUN_ID. Add SLOP_CREDENTIALS + SLOP_MCP_ENV env vars. Auto-generate placeholder TOML files (credentials.toml, mcp_env.toml, presets.toml, tool_presets.toml, personas.toml) in the isolation workspace." }
t5_2 = { status = "pending", commit_sha = "", description = "Add `addopts = \"--basetemp=tests/artifacts/_pytest_tmp\"` to pyproject.toml [tool.pytest.ini_options]." }
t5_3 = { status = "pending", commit_sha = "", description = "Add defensive pytest_configure check in conftest.py: if config._tmp_path_factory._basetemp resolves outside ./tests/, override." }
t5_4 = { status = "pending", commit_sha = "", description = "Add dated note to conductor/tech-stack.md explaining --basetemp choice." }
t5_5 = { status = "pending", commit_sha = "", description = "Write tests/test_test_sandbox.py tests 7,8,9: pyproject.toml has --basetemp, isolate_workspace no tmp_path_factory.mktemp, AppController.__init__ doesn't call init_state()." }
t5_6 = { status = "pending", commit_sha = "", description = "Commit Phase 5 (FR3 isolation migration)." }

t6_1 = { status = "pending", commit_sha = "", description = "Write scripts/run_tests_sandboxed.ps1 based on run_tier2_sandboxed.ps1 structure: restricted token + Job Object + pytest invocation with --config + --basetemp." }
t6_2 = { status = "pending", commit_sha = "", description = "Write smoke test: `pwsh -File scripts/run_tests_sandboxed.ps1 -WhatIf` exits 0." }
t6_3 = { status = "pending", commit_sha = "", description = "Commit Phase 6 (FR5 PowerShell wrapper)." }

t7_1 = { status = "pending", commit_sha = "", description = "Create conductor/code_styleguides/test_sandbox.md documenting --config CLI flag, config_overrides.toml convention, 4-layer enforcement model." }
t7_2 = { status = "pending", commit_sha = "", description = "Update conductor/code_styleguides/workspace_paths.md to mention the new SLOP_CONFIG → --config migration." }
t7_3 = { status = "pending", commit_sha = "", description = "Add 'Sandbox Hardening' section to docs/guide_testing.md." }
t7_4 = { status = "pending", commit_sha = "", description = "Commit Phase 7 (FR7 documentation)." }

t8_1 = { status = "pending", commit_sha = "", description = "Run `uv run python scripts/run_tests_batched.py --tiers 1,2,3,4,5,6,7,8,9,10,11`. Capture pass count + duration. Verify no regression vs. baseline (1288 passed + 4 xdist-skipped)." }
t8_2 = { status = "pending", commit_sha = "", description = "If regression: report to user with diff and propose fix. If no regression: commit verification report." }

t9_1 = { status = "pending", commit_sha = "", description = "Write docs/reports/TRACK_COMPLETION_test_sandbox_hardening_20260619.md following precedent set by TRACK_COMPLETION_tier2_autonomous_sandbox_20260616.md." }
t9_2 = { status = "pending", commit_sha = "", description = "Update state.toml: status = 'completed', current_phase = 'complete'. Commit." }

[verification]
phase_1_baseline_captured = false
phase_4_root_cause_fix = false
phase_5_layer_2_works = false
phase_8_full_suite_no_regression = false
phase_9_report_written = false

[user_directives_logged]
hard_sandbox_required = "User wants hard sandbox similar to Tier 2; pytest/run_tests_batched.ps1 entirely banned from accessing files outside ./tests/"
no_new_skip_markers = "Per conductor/workflow.md Skip-Marker Policy + user directive"
sample_data_loss = "User has lost important sample data multiple times over the past month - primary motivation for this track"
design_chosen = "C (Both): Python guard (default) + Windows restricted-token wrapper (opt-in). User confirmed on 2026-06-19."
no_env_vars = "Per user 2026-06-19: NO ENV VARS for config path. --config CLI flag is the only override mechanism. Other SLOP_* env vars stay for now (user will fix in follow-up tracks)."
config_overrides_naming = "Per user 2026-06-19: test workspace file is named 'config_overrides.toml' (the convention for test sandbox configs)."
hard_fail = "Per user 2026-06-19: HARD FAIL on any sandbox violation. No warnings, no soft fails."
no_appdata_temp = "Per user 2026-06-19: tests should never need AppData temp. tempfile.mkdtemp/mkstemp without dir= is a flag."
