diff --git a/conductor/tracks/workspace_path_finalize_20260609/plan.md b/conductor/tracks/workspace_path_finalize_20260609/plan.md new file mode 100644 index 00000000..0bebbff1 --- /dev/null +++ b/conductor/tracks/workspace_path_finalize_20260609/plan.md @@ -0,0 +1,283 @@ +# Workspace Path Finalize — Implementation Plan + +> **For Tier 3 workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. +> +> **This is the LAST track on this issue. Do not add scope. Do not refactor anything else. Do not add new tests beyond the 2 in this plan. Do not update docs. Do not file follow-up tracks. Execute exactly what is here, then stop.** + +**Goal:** Replace `tmp_path_factory.mktemp("live_gui_workspace")` in `tests/conftest.py` with a per-run timestamped folder under `tests/artifacts/`. Each `uv run pytest` invocation gets its own folder. All live_gui tests in that invocation share it (per-test pollution is intentional and exposes fragility). + +**Architecture:** Module-level constants in conftest.py compute the workspace path once at import time. The `live_gui` fixture uses those constants. The `live_gui_workspace` fixture (which already exists) returns the same path via the handle. No env vars, no CLI args, no runner changes. + +**Tech Stack:** Python 3.11+, pytest, pathlib. + +--- + +## Pre-Phase 0: Checkpoint + +- [ ] **Step 0.1: Pre-edit checkpoint** + ```powershell + cd C:\projects\manual_slop; git add . && git commit -m "wip: pre-workspace-path-finalize" --allow-empty + ``` + +--- + +## Phase 1: Apply the 1-line conftest change + +Focus: Add module-level constants + change 2 lines in conftest.py. + +### Task 1.1: Add the `datetime` import + +**Files:** +- Modify: `tests/conftest.py` (imports section, near the top) + +- [ ] **Step 1.1.1: Read the current imports section** + Use `manual-slop_get_file_slice` to read `tests/conftest.py:1-30` and see the existing import block. + +- [ ] **Step 1.1.2: Add `from datetime import datetime` to the imports** + Use `manual-slop_set_file_slice` to insert the import. The exact placement (alphabetical order, or grouped with stdlib imports) depends on what's currently there. Match the existing style. + + **CRITICAL — verify via `ast.parse` after the edit:** + ```powershell + cd C:\projects\manual_slop; uv run python -c "import ast; ast.parse(open('tests/conftest.py').read()); print('OK')" + ``` + +### Task 1.2: Add module-level constants + +**Files:** +- Modify: `tests/conftest.py` (module-level, after imports, before the first fixture or constant) + +- [ ] **Step 1.2.1: Find a good location** + Read `tests/conftest.py:1-50` with `manual-slop_get_file_slice`. Find a place after imports and before the first fixture/class definition. + +- [ ] **Step 1.2.2: Add the constants** + Insert: + ```python + _RUN_ID = datetime.now().strftime("%Y%m%d_%H%M%S") + _RUN_WORKSPACE = Path(f"tests/artifacts/live_gui_workspace_{_RUN_ID}") + ``` + + Use `manual-slop_set_file_slice` with the exact start_line and end_line of the insertion point. + + **CRITICAL — 1-space indent.** These are top-level statements, no indent. Use exactly the snippet above. + +- [ ] **Step 1.2.3: Verify syntax** + ```powershell + cd C:\projects\manual_slop; uv run python -c "import ast; ast.parse(open('tests/conftest.py').read()); print('OK')" + ``` + +### Task 1.3: Change the `live_gui` fixture signature + +**Files:** +- Modify: `tests/conftest.py:453` (the `def live_gui(...)` line) + +- [ ] **Step 1.3.1: Read the exact line** + Use `manual-slop_get_file_slice` to read `tests/conftest.py:453` and get the exact text. + +- [ ] **Step 1.3.2: Remove `tmp_path_factory` from the parameter list** + Change: + ```python + def live_gui(request, tmp_path_factory) -> Generator["_LiveGuiHandle", None, None]: + ``` + to: + ```python + def live_gui(request) -> Generator["_LiveGuiHandle", None, None]: + ``` + + Use `manual-slop_set_file_slice` with the exact line. + +- [ ] **Step 1.3.3: Verify syntax** + ```powershell + cd C:\projects\manual_slop; uv run python -c "import ast; ast.parse(open('tests/conftest.py').read()); print('OK')" + ``` + +### Task 1.4: Replace the workspace creation + +**Files:** +- Modify: `tests/conftest.py:465` (the `temp_workspace = ...` line) + +- [ ] **Step 1.4.1: Read the exact line** + Use `manual-slop_get_file_slice` to read `tests/conftest.py:464-466` and get the exact text. + +- [ ] **Step 1.4.2: Replace the workspace creation** + Change: + ```python + temp_workspace = tmp_path_factory.mktemp("live_gui_workspace") + ``` + to: + ```python + temp_workspace = _RUN_WORKSPACE + ``` + + Use `manual-slop_set_file_slice` with the exact line. + +- [ ] **Step 1.4.3: Verify syntax** + ```powershell + cd C:\projects\manual_slop; uv run python -c "import ast; ast.parse(open('tests/conftest.py').read()); print('OK')" + ``` + +### Task 1.5: Run a smoke test + +- [ ] **Step 1.5.1: Run a single live_gui test to verify the fixture works** + ```powershell + cd C:\projects\manual_slop; uv run pytest tests/test_gui_startup_smoke.py -v --timeout=30 + ``` + Expected: PASS. + +- [ ] **Step 1.5.2: Verify the workspace folder was created** + ```powershell + cd C:\projects\manual_slop; ls tests/artifacts/ | Where-Object { $_.Name -like "live_gui_workspace_*" } + ``` + Expected: a folder like `live_gui_workspace_20260609_HHMMSS` exists. + +- [ ] **Step 1.5.3: Verify the subprocess CWD is the new workspace** + Run `tests/test_gui_startup_smoke.py` with `-s` to see prints, OR add a temporary `print(handle.workspace)` in the test to verify. + + Expected: handle.workspace is `C:\projects\manual_slop\tests\artifacts\live_gui_workspace_`. + +### Phase 1 commit + +- [ ] **Step 1.C.1: Commit the conftest change** + ```powershell + cd C:\projects\manual_slop; git add tests/conftest.py + git commit -m "fix(test): per-run workspace under tests/artifacts/ (replaces tmp_path_factory)" + $h = git log -1 --format='%H' + git notes add -m "Replaces tmp_path_factory.mktemp with _RUN_WORKSPACE, a module-level constant computed once at conftest import time. Each pytest invocation gets tests/artifacts/live_gui_workspace_/. All live_gui tests in that invocation share the workspace (per-test pollution is intentional). The workspace is gitignored via tests/artifacts/. 1 import + 2 line changes in conftest.py." $h + ``` + +--- + +## Phase 2: Add 2 verification tests + +Focus: 2 small tests that prove the workspace is at the right path and is gitignored. + +### Task 2.1: Write the 2 verification tests + +**Files:** +- Create: `tests/test_workspace_path_finalize.py` + +- [ ] **Step 2.1.1: Write the test file** + Create `tests/test_workspace_path_finalize.py` with the following content: + ```python + """Tests for the per-run workspace path (workspace_path_finalize_20260609).""" + import subprocess + from pathlib import Path + + + def test_live_gui_workspace_is_under_tests_artifacts(live_gui_workspace: Path) -> None: + """The live_gui_workspace fixture returns a path under tests/artifacts/.""" + s = str(live_gui_workspace).replace("\\", "/") + assert s.startswith("tests/artifacts/live_gui_workspace_"), f"Expected tests/artifacts/live_gui_workspace_*, got {s}" + + + def test_live_gui_workspace_is_gitignored(live_gui_workspace: Path) -> None: + """The live_gui_workspace path is gitignored (via tests/artifacts/ in .gitignore).""" + result = subprocess.run( + ["git", "check-ignore", str(live_gui_workspace)], + capture_output=True, text=True, cwd="." + ) + assert result.returncode == 0, f"Workspace {live_gui_workspace} is not gitignored. git check-ignore output: {result.stdout!r} {result.stderr!r}" + ``` + + **CRITICAL — 1-space indent for all function bodies.** The file-level content has no indent. The `def` lines have no indent. The function body lines have exactly 1 space. + +- [ ] **Step 2.1.2: Verify syntax** + ```powershell + cd C:\projects\manual_slop; uv run python -c "import ast; ast.parse(open('tests/test_workspace_path_finalize.py').read()); print('OK')" + ``` + +- [ ] **Step 2.1.3: Run the 2 tests** + ```powershell + cd C:\projects\manual_slop; uv run pytest tests/test_workspace_path_finalize.py -v --timeout=30 + ``` + Expected: 2/2 pass. + +### Phase 2 commit + +- [ ] **Step 2.C.1: Commit the verification tests** + ```powershell + cd C:\projects\manual_slop; git add tests/test_workspace_path_finalize.py + git commit -m "test(workspace): verify per-run workspace path and gitignore status" + $h = git log -1 --format='%H' + git notes add -m "2 tests: test_live_gui_workspace_is_under_tests_artifacts (asserts the path starts with tests/artifacts/live_gui_workspace_) and test_live_gui_workspace_is_gitignored (asserts git check-ignore returns 0 for the workspace path). Both pass with the new _RUN_WORKSPACE constant." $h + ``` + +--- + +## Phase 3: Run the full batch and verify + +Focus: The moment of truth. tier-1 5/5, tier-2 5/5, tier-3 0 new failures. The 4 sim tests in `test_extended_sims.py` now pass. + +### Task 3.1: Run the full batch + +- [ ] **Step 3.1.1: Run the full batched test suite** + ```powershell + cd C:\projects\manual_slop; uv run .\scripts\run_tests_batched.py 2>&1 | Tee-Object -FilePath "tests/artifacts/post_finalize_batch_20260609.log" | Select-Object -Last 50 + ``` + + Expected: + - tier-1: 5/5 batches pass + - tier-2: 5/5 batches pass + - tier-3: 0 NEW failures vs the `fe240db4` baseline + - The 4 sim tests in `tests/test_extended_sims.py` PASS (they were failing at the `fe240db4` baseline due to the workspace path mismatch) + +- [ ] **Step 3.1.2: If tier-3 has new failures, STOP and report** + **DO NOT** try to fix new failures in this track. This track's scope is ONLY the workspace path. New failures are out of scope — document them in the git note and move on. + +- [ ] **Step 3.1.3: Verify the new workspace folder exists in tests/artifacts/** + ```powershell + cd C:\projects\manual_slop; ls tests/artifacts/ | Where-Object { $_.Name -like "live_gui_workspace_*" } + ``` + Expected: a fresh folder for this run. + +- [ ] **Step 3.1.4: Verify the old %TEMP% workspace is NOT being used** + ```powershell + cd C:\projects\manual_slop; ls $env:TEMP | Where-Object { $_.Name -like "pytest-of-*" } + ``` + Expected: nothing (or only stale folders from prior runs before this change). The conftest no longer creates new ones in %TEMP%. + +### Task 3.2: Commit the batch log + +- [ ] **Step 3.2.1: Commit the batch log** + ```powershell + cd C:\projects\manual_slop; git add tests/artifacts/post_finalize_batch_20260609.log + git commit -m "docs(batch): post-workspace-path-finalize batch log" + $h = git log -1 --format='%H' + git notes add -m "Final batch run log. tier-1 5/5, tier-2 5/5, tier-3 [count] failures. The 4 sim tests in test_extended_sims.py now pass because their os.path.abspath('tests/artifacts/...') paths resolve correctly to the project tree where the new workspace lives." $h + ``` + +--- + +## Final Verification + +- [ ] All 3 commits in place +- [ ] `tests/conftest.py` no longer uses `tmp_path_factory` in the `live_gui` fixture +- [ ] `tests/artifacts/live_gui_workspace_/` exists after a pytest run +- [ ] `.gitignore` already has `tests/artifacts/` (no change needed) +- [ ] 2 verification tests pass +- [ ] Full batch: tier-1 5/5, tier-2 5/5, tier-3 [count] failures (should match or improve on `fe240db4` baseline) +- [ ] The 4 sim tests in `tests/test_extended_sims.py` pass in batch + +## Track Done + +After the 3 commits and the full batch verification, the track is DONE. **Do not:** +- File follow-up tracks +- Add scope +- Refactor anything else +- Update docs +- Add more tests + +**Do:** +- Report the final state to the user +- Mark the track as complete in `conductor/tracks.md` +- Move on to the 4 upcoming tracks (qwen_llama_grok, data_oriented_error_handling, data_structure_strengthening, mcp_architecture_refactor) + +--- + +## Execution Constraints + +- **1-space indent, CRLF, type hints.** Per project conventions. +- **1-line edits via `manual-slop_set_file_slice`.** Per `conductor/edit_workflow.md`. The previous attempt at a conftest refactor was reverted due to corruption — use the recommended surgical tool. +- **Verify syntax with `ast.parse` after each edit.** +- **No diagnostic noise in production.** No `print()` statements added to conftest.py for debugging. +- **Per-task atomic commits.** Not batched. +- **No "while we're at it" refactors.** This is the LAST track on this issue. Stay in scope.