# Track Specification: Default Layout Extract + Hard Visual Verification ## Overview Extract tier-2's GOOD work on the default layout setup (the `layouts/` directory, the install-on-empty-INI helpers, the pre-run install timing fix, and the orphan-end-child cleanup) into `master`, and replace the previous tier-2 "fake" verification (INI content assertions only) with a HARD 4-layer visual verification protocol that catches the "panels don't render" regression every time it occurs. ## Current State Audit (as of commit `466d2656` on master) ### Branch State Warning The main working tree at `C:\projects\manual_slop` is currently on branch `tier2/post_module_taxonomy_de_cruft_20260627` (NOT master). This track targets `master`. All line numbers below are from `master` (verified via `git show master:src/gui_2.py`). The cruft-elimination tracks (`module_taxonomy_refactor_20260627` + `post_module_taxonomy_de_cruft_20260627`) are NOT merged to master — they live on tier-2 branches only. This track does NOT depend on those cruft tracks; it depends only on `cruft_elimination_20260627` (which IS merged to master) + the themes infrastructure in `src/paths.py` (which is on master). A separate master worktree exists at `C:\projects\manual_slop_master` for editing on the master branch without disturbing the cruft-branch working tree. ### Already Implemented on Master - `src/paths.py:60,83,150,209-216` — themes infrastructure (the pattern to mirror for layouts): `themes: Path` field in `_AppPaths`, default `root_dir / "themes"`, env override `SLOP_GLOBAL_THEMES`, getters `get_global_themes_path()` and `get_project_themes_path(project_root)`, plus the path info dict entry at line 295. - `src/theme_2.py:340-346` + `src/theme_models.py:181-225` — themes loader pair (the pattern to mirror for layouts): `load_themes_from_disk()` calls `get_global_themes_path()` then `load_themes_from_dir(path, scope)`; the latter iterates children, parses, builds typed `@dataclass(frozen=True, slots=True)` records, drains errors via `Result + ErrorInfo`. - `src/gui_2.py:1776` — `from src.command_palette import render_palette_modal`. **MASTER WORKS**: `src/command_palette.py` EXISTS (165 lines, has `Command`, `ScoredCommand`, `CommandRegistry`, `render_palette_modal`). Tier-2 broke because they deleted `src/command_palette.py` in `module_taxonomy_refactor_20260627` (commit `3dd153f7`, NOT merged to master). - `src/gui_2.py:580-611` — `_diag_layout_state` (one-shot startup diagnostic that logs `show_windows` count + INI file size + stale window name warnings). Used as the install verification hook. - `src/gui_2.py:619-703` — `App.run`. Calls `_run_immapp_result(self)` at line 691. HelloImGui reads `runner_params.ini_filename` ("manualslop_layout.ini") from cwd at load_user_pref time, BEFORE `callbacks.post_init` fires. - `src/gui_2.py:566-578` — `App._post_init`. Calls `_post_init_callback_result` and `_diag_layout_state`. Fires AFTER HelloImGui has loaded the INI from disk. - `src/gui_2.py:1449-1470` — `_post_init_callback_result` (drain-aware wrapper for `App._post_init`). The pattern Tier-2's `_install_default_layout_if_empty_result` and `_install_default_layout_pre_run_result` follow. - `src/gui_2.py:1658-1660` — orphan-end-child bug was refactored OUT of `_tier_stream_scroll_sync_result` (the helper that was previously buggy). The orphan at line 6990 (in `render_tier_stream_panel`'s except block) STILL exists on master. - `src/gui_2.py:6981-6991` — `render_tier_stream_panel` has the latent orphan-end-child bug: `try: ... imgui.end_child()` at line 6988; `except (TypeError, AttributeError): imgui.end_child()` at line 6990. When the try block raises (e.g. `len(None)`), the second `end_child()` fires with no matching `begin_child()` and ImGui emits "In window 'MainDockSpace': Missing End()". Currently latent because `len(content)` rarely raises. - `tests/conftest.py:700-712` — pre-baked `tests/artifacts/manualslop_layout_default.ini` shipped to fresh test workspaces. Hardcoded path (cwd-relative test fixture) — violates "production code uses cwd-relative paths only" rule. - `src/commands.py:248-275` — `reset_layout` command with hardcoded `tests/artifacts/live_gui_workspace/manualslop_layout.ini` path at line 268 (dead code in production; references a test-fixture path that doesn't exist in production cwd). - `conductor/tracks/default_layout_install_20260629/` — Tier-1 track scaffolding from this session. States the user's intent. - `conductor/tracks/default_layout_install_followup_20260629/` — Tier-1 followup track that supersedes Tier-2's wrong-theory `e9654518` strip-docking fix. ### Already Implemented on Tier-2 Branch (NOT on master) - `layouts/default.ini` (2971 bytes, 101 lines) — bundled INI with full `[Docking][Data]` hierarchy (DockSpace ID=0xAFC85805 + DockNode 0x00000001 + DockNode 0x00000002 + 8 per-window `DockId=...` entries). Comments document the runtime-generated ID semantics. - `src/layouts.py` (3178 bytes, 88 lines) — `LayoutFile` dataclass + `load_layouts_from_file()` + `load_layouts_from_dir()` + `load_layouts_from_disk()` (mirrors `src/theme_models.py:181-225` shape exactly). - `src/gui_2.py:1481-1540` — `_install_default_layout_if_empty` + `_install_default_layout_if_empty_result` (drain-aware wrapper). The function: reads dst INI; if empty (<1000 bytes OR no `[Window][`), reads bundled src INI, writes to dst, calls `imgui.load_ini_settings_from_memory(src_text)` to apply to live session. - `src/gui_2.py:1543-1590` — `_install_default_layout_pre_run_result`. Same logic but disk-only (no `load_ini_settings_from_memory`) because imgui is not yet initialized before `immapp.run()`. This is the timing fix Tier-2 added after the post-init version was too late for the first session. - `src/gui_2.py:701-706` — `App.run` wiring: calls `_install_default_layout_pre_run_result(self)` BEFORE `_run_immapp_result(self)`. Drains errors to `_startup_timeline_errors`. - `src/gui_2.py:579-582` — `App._post_init` wiring: calls `_install_default_layout_if_empty_result(self, src_layout_path, dst_layout_path)`. Drains errors. - `tests/test_layout_reorganization.py` (66 lines) — RED tests for the install-on-empty-INI behavior (per tier-2 claim "17/17 PASSED"; tests check INI content, not visible panels). ### Gaps to Fill (This Track's Scope) | Gap | Severity | Layer | |---|---|---| | `layouts/` directory + `layouts/default.ini` + `src/layouts.py` missing on master | High | (the assets themselves) | | `_install_default_layout_if_empty` + `_install_default_layout_pre_run_result` helpers missing on master | High | (the install behavior) | | `App._post_init` and `App.run` wiring missing on master | High | (the install triggers) | | `get_layouts_dir()` in `src/paths.py` missing on master | High | (the path resolver; mirrors themes) | | `reset_layout` command still references dead `tests/artifacts/manualslop_layout_default.ini` path | Medium | cleanup | | Orphan `imgui.end_child()` at `src/gui_2.py:6990` (latent; fires when tier-stream try-block raises) | Medium | cleanup | | **No hard verification that panels actually render visually** | Critical | verification infrastructure | ### Tier-2's "Bullshit" We're NOT Extracting | Commit | Why Skip | |---|---| | `e9654518` "strip stale dockspace IDs" | Wrong theory (superseded by `2afb0126`; that one we DO extract) | | `13ad9d3e` "idk" | Meaningless commit message; bulk-edited `manualslop_layout.ini` | | `28527851` "artifacts" | Meaningless commit; bulk-edited artifacts | | `9437af6c` "archive 27 diagnostic scripts" | 27 throwaway scripts not needed in master | | `4acf8b15`, `b80e5afb`, `c42a7599`, `cf5244b1`, `b1632f46`, `06476c56`, `519e1340`, `cf6a2e20`, `4bf5ecd6`, `5e53d477`, `d4116f19`, `7d5a5492`, `15cd1262`, `23566da8` | Tier-2 internal track-marking commits; we write our own | | `71028dad` "drop stale `from src.command_palette import`" | Tier-2 specific: master has `src/command_palette.py` so the import WORKS on master. The stale import bug only exists on tier-2 because they deleted the module. **We do not cherry-pick this.** | ### Why the User Wants This Track The tier-2 track was marked "SHIPPED" based on: - 17/17 install/layout tests PASS (which only check INI content, not visible panels) - Manual launch produces a 3072-byte INI with correct structure (content check, not visible check) - "the imgui core loader rejected the literal IDs from the bundled INI because the runtime IDs didn't match" — claim contradicted by post-fix INI matching runtime IDs **None of those commits empirically verified visible panels after install.** The user wants this regression to never happen again. The previous tier-2 "fake" verification must be replaced by a HARD one. ## Goals **G1.** Master has `layouts/default.ini` + `src/layouts.py` + `get_layouts_dir()` so the app boots with a non-empty INI on first launch. **G2.** Master has `_install_default_layout_if_empty` + `_install_default_layout_pre_run_result` wired into `App._post_init` + `App.run` so empty-INI detection + install-on-empty works at both phases (live session + first session). **G3.** Master has `reset_layout` cleaned up to remove the dead test-fixture path (no more `tests/artifacts/...` in production code). **G4.** Master has the orphan `imgui.end_child()` at `src/gui_2.py:6990` removed. **G5.** Master has a HARD 4-layer visual verification infrastructure: - **Layer 1 (Per-Panel Sentinel)**: a `tests/test_panels_visible_after_install.py` test that asserts every `show_windows[k]==True` panel has nonzero render size after first frame. - **Layer 2 (Win32 PrintWindow Pixel Baseline)**: a `tests/test_visual_baseline_default.py` test that captures the running GUI window's pixels via Win32 `PrintWindow` API and compares against `tests/artifacts/visual_baseline_default.png` with <1% pixel-diff tolerance. Catches ALL visual regressions (empty workspace, wrong INI, missing panels, overlap, theme corruption). - **Layer 3 (Forced Test Viewport + Theme)**: `MANUAL_SLOP_TEST_VIEWPORT=1680x1050` + `MANUAL_SLOP_TEST_THEME=dark` env vars honored at startup. Forces fixed viewport + known theme so the baseline PNG is deterministic. - **Layer 4 (Cannot-Skip Gates)**: `scripts/check_visual_baseline.py` (exits 1 if pixel diff > 1%); wire into `scripts/run_tests_batched.py`; require `git tag VERIFIED-` on the merge commit; `conductor/tracks.md` schema update so `[x]`-completion requires the tag. **G6.** A regression test demonstrates that the verification infrastructure catches the original "panels don't render" bug (negative test: corrupt the installed INI, verify the sentinel + pixel baseline both fail). ## Functional Requirements ### FR1. Tier-2 Asset Extraction (Hybrid Approach C) - F1.1. Port `layouts/default.ini` fresh from tier-2's `C:\projects\manual_slop_tier2\layouts\default.ini` (2971 bytes, 101 lines) to `layouts/default.ini` at master repo root. Rationale: clean history for new asset; user-facing content. - F1.2. Port `src/layouts.py` fresh from tier-2's `C:\projects\manual_slop_tier2\src\layouts.py` (88 lines). Mirrors `src/theme_models.py:181-225` shape. Rationale: clean history for new module; matches `src/theme_2.py` + `src/theme_models.py` pair. - F1.3. Add `get_layouts_dir()` to `src/paths.py` mirroring `get_global_themes_path()` at line 209. Add `layouts: Path` field to `_AppPaths` (line 60), default `root_dir / "layouts"` (line 83), env override `SLOP_GLOBAL_LAYOUTS` (line 150), path info dict entry (line 295). User explicitly authorized "make a layouts directory similar to the themes directory" in the prior session. - F1.4. Port `tests/test_layout_reorganization.py` fresh from tier-2 (66 lines). Rationale: tests for the install helpers. ### FR2. Install Helpers + Wiring - F2.1. Add `_install_default_layout_if_empty(src_ini: Path, dst_ini: Path) -> Result[bool]` to `src/gui_2.py` (per tier-2 line 1481). Reads dst; if empty (<1000 bytes OR no `[Window][`), copies src→dst and calls `imgui.load_ini_settings_from_memory(src_text)` to apply to live session. - F2.2. Add `_install_default_layout_if_empty_result(app: "App", src: Path, dst: Path) -> Result[bool]` (per tier-2 line 1530). Drain-aware passthrough wrapper. - F2.3. Add `_install_default_layout_pre_run_result(app: "App") -> Result[bool]` (per tier-2 line 1543). Disk-only install (no `load_ini_settings_from_memory`); imgui isn't initialized yet. - F2.4. Wire `_install_default_layout_if_empty_result` into `App._post_init` (line 566-578). Source path: `get_layouts_dir() / "default.ini"`. Dst path: `Path.cwd() / "manualslop_layout.ini"`. Drain errors to `_startup_timeline_errors`. - F2.5. Wire `_install_default_layout_pre_run_result` into `App.run` (line 619-703, insert before line 691 `_run_immapp_result(self)`). Drain errors to `_startup_timeline_errors`. ### FR3. Surgical Cherry-Picks - F3.1. Cherry-pick `c2155593 fix(gui): remove orphan imgui.end_child() in render_tier_stream_panel except handler`. Apply the 1-line deletion to `src/gui_2.py:6990`. Tier-2 verified this fixes an imgui "Missing End()" error in MainDockSpace when the tier-stream try-block raises. Latent on master but real. - F3.2. Cherry-pick `3b966288 chore(commands): remove dead test-fixture path from reset_layout`. Apply the deletion to `src/commands.py:268` (the `tests/artifacts/live_gui_workspace/manualslop_layout.ini` hardcoded path in the `layout_paths` list). ### FR4. Layer 1 — Per-Panel Render Sentinel - F4.1. New test file `tests/test_panels_visible_after_install.py`. Imports `live_gui` fixture from `tests/conftest.py`. - F4.2. RED: assert that for each `show_windows[k]==True` entry, after first frame, `imgui.find_window_viewport(k).size.x > 0 AND .size.y > 0`. Test should fail on the current baseline (we don't have the install helpers yet) — confirms sentinel catches the regression. - F4.3. GREEN: with the install helpers in place (FR2), test passes. - F4.4. Test must use poll-loop (not `time.sleep`) per `conductor/workflow.md` "Async Setters Need Poll-For-State". ### FR5. Layer 2 — Win32 PrintWindow Pixel Baseline - F5.1. New test file `tests/test_visual_baseline_default.py`. Imports `live_gui` fixture. - F5.2. Capture: import `win32gui` from `pywin32`; find imgui window HWND via `win32gui.FindWindow(None, "manual slop")`; allocate DC + bitmap; call `win32gui.PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT)`; convert bitmap to PNG via `Pillow` (already a dep); save to `tests/artifacts/_.png`. - F5.3. Baseline: commit `tests/artifacts/visual_baseline_default.png` (the "known good" reference). Generated AFTER F5.1 + F5.2 are GREEN against the new install infrastructure. - F5.4. Compare: load baseline + current via `Pillow.Image.open(...)`; convert to RGB; compute pixel diff via `numpy.abs(np.array(a) - np.array(b)).mean() / 255.0`. Threshold: 0.01 (1%). Fail if > 1%. - F5.5. RED: with the install infrastructure removed, the test must fail. Confirms the test catches the regression. - F5.6. Test must poll for first frame + capture screenshot AT MOST ONCE (don't spam captures). ### FR6. Layer 3 — Forced Test Viewport + Theme - F6.1. Add `MANUAL_SLOP_TEST_VIEWPORT=1680x1050` env var support to `App.run` (line 619). If set, override `self.runner_params.app_window_params.window_geometry.size` to the env-var value (parsed as `WxH`). - F6.2. Add `MANUAL_SLOP_TEST_THEME=dark` env var support to `App.run` (line 619). If set, force `self.runner_params.imgui_window_params.tweaked_theme = ImGuiTheme_.ImGuiColorsDark` (the default dark theme). - F6.3. RED: write `tests/test_test_mode_env_vars.py` that asserts both env vars are honored when set (via `live_gui` fixture with env vars). - F6.4. GREEN: implement the env-var parsing in `App.run`. ### FR7. Layer 4 — Cannot-Skip Gates - F7.1. New file `scripts/check_visual_baseline.py`. Imports `live_gui` (no — too heavy for a CLI script). Instead, accepts `--baseline ` + `--current ` + `--threshold ` CLI args. Uses `Pillow.Image.open()` + `numpy.abs(...).mean()` to compute diff. Exits 1 if diff > threshold. - F7.2. Add `scripts/check_visual_baseline.py` to `scripts/run_tests_batched.py` tier-2 test list (or a new tier dedicated to visual regression). - F7.3. Document the `VERIFIED-` git-tag requirement in `conductor/tracks.md` schema section. Tracks that touch `src/gui_2.py` MUST carry the tag for `[x]`-completion. - F7.4. New doc `docs/guide_visual_verification.md` (200-300 lines). Documents the 4 layers, how to add a new visual baseline, how to update an existing baseline, the env-var protocol, the tag protocol. ### FR8. Negative Test (Regression Catch Demonstration) - F8.1. New test file `tests/test_visual_baseline_catches_corrupt_ini.py`. Uses `live_gui` fixture; AFTER the install infrastructure has run, manually corrupt the installed INI (delete `[Docking][Data]` line). Re-launch + capture screenshot. Verify pixel diff > 5% (the corrupted INI shows empty workspace, baseline shows full panels). - F8.2. Negative test must run in a separate `pytest` session (not pollute `live_gui` state). ## Non-Functional Requirements ### NFR1. Atomic Per-Task Commits Every Phase task results in exactly ONE atomic commit. No batched commits. Per `AGENTS.md` "Critical Anti-Patterns" — "Do not batch commits - commit per-task for atomic rollback". ### NFR2. TDD Red-First Every implementation task has a preceding RED test task. Per `conductor/workflow.md` "Standard Task Workflow" §4. ### NFR3. No Comments in Source Code Per `AGENTS.md` "Critical Anti-Patterns" — "Do not add comments to source code; documentation lives in /docs". ### NFR4. No Diagnostic Noise in Production Per `AGENTS.md` "Critical Anti-Patterns" — diag stderr goes to `tests/artifacts/*.diag.log` or `/tmp`, NOT `src/*.py`. ### NFR5. 1-Space Indentation Per `conductor/workflow.md` "Code Style (MANDATORY - Python)" — exactly 1 space per level for ALL Python code. ### NFR6. CRLF Line Endings on Windows Per `conductor/workflow.md` "Code Style (MANDATORY - Python)" — preserve CRLF. ### NFR7. Type Hints Required Per `conductor/product-guidelines.md` "AI-Optimized Compact Style" — strict type hints on all parameters, return types, globals. ### NFR8. No `dict[str, Any]` / `Optional[T]` in Non-Boundary Code Per `conductor/code_styleguides/data_oriented_design.md` §8.5 + `python.md` §17. Typed `@dataclass(frozen=True, slots=True)` + `Result[T]` + `NIL_T`. ### NFR9. ImGui Defer Patterns Per `conductor/code_styleguides/python.md` — use `imscope` context managers over manual `imgui.begin/end` pairs (where applicable). Existing manual pairs in `src/gui_2.py` are unchanged. ### NFR10. Manual Slop MCP Tools Only Per the system prompt — use `manual-slop_*` MCP tools, NOT native `read`/`edit`/`grep` (where the MCP equivalents are available). When MCP tools aren't available (which is the case for this Tier-1 track creation), native `read`/`edit`/`grep`/`write` are the fallback. ## Architecture Reference - **`docs/guide_gui_2.md`** §"App class lifecycle" + §"_post_init + App.run" — current rendering flow; where the install helpers slot in. - **`docs/guide_architecture.md`** §"Thread domains, event system" — confirms main thread owns `App.run`; install helpers run on main thread (no thread-safety concerns). - **`docs/guide_testing.md`** §"`live_gui` fixture" + §"Puppeteer pattern" + §"Structural Testing Contract" — the live_gui fixture is the test harness for FR4-FR8. - **`conductor/code_styleguides/data_oriented_design.md`** §8.5 — the Python Type Promotion Mandate. Bound by NFR8. - **`conductor/code_styleguides/error_handling.md`** — `Result[T]` + `ErrorInfo` + `ErrorKind` usage. The install helpers return `Result[bool]` per this styleguide. - **`conductor/code_styleguides/type_aliases.md`** — `Metadata = TrackMetadata` etc. The new `LayoutFile` dataclass follows the typed-record pattern from this styleguide. - **`conductor/code_styleguides/feature_flags.md`** — "delete to turn off" (file presence) for the bundled INI. If `layouts/default.ini` is deleted, `_install_default_layout_if_empty` returns `Result(data=False)` (no install). - **`docs/guide_visual_verification.md`** (NEW, FR7.4) — the documentation deliverable. ## Out of Scope 1. **Fleury declarative view-constructs migration** (`PANELS: tuple[PanelDef, ...]`). Logged in `default_layout_install_20260629/metadata.json` `deferred_to_followup_tracks[0]`. Requires its own track. 2. **imgui_test_engine integration** (`test_engine_integration_20260627`). Provides pixel-level diff via `ctx.capture_screenshot_window()`. Our Win32 PrintWindow approach is simpler + works without test engine. The two approaches are complementary; layering them is a future task. 3. **Reverting tier-2's working tree state**. User's responsibility per the Inherited-Cruft rule. Tier-2's `git status` shows uncommitted `manual_slop.toml` + `manual_slop_history.toml` deletions; user must explicitly handle those. 4. **Cross-platform pixel diff** (Linux/macOS). Win32 PrintWindow is Windows-only. The track ships Windows-only; CI on Linux/macOS would skip FR5 (marked `@pytest.mark.skipif(sys.platform != "win32")`). 5. **Pre-baked test INI shipped from `tests/conftest.py:700-712`**. Replaced by FR5.3 baseline PNG. 6. **`render_persona_editor_window` bug** at `src/gui_2.py:3433+` (opens + immediately closes the Persona Editor window when not embedded). Pre-existing; unrelated to panel visibility. Logged for followup. ## Coordination with Pending Tracks - **`default_layout_install_20260629/`** — supersedes. Tier-1 scaffolding for this work. The plan.md tasks here replace `conductor/tracks/default_layout_install_20260629/plan.md`. - **`default_layout_install_followup_20260629/`** — supersedes. The followup plan assumed tier-2's `e9654518` INI strip was the right fix; this track's plan supersedes that with the hybrid extraction. - **`test_engine_integration_20260627`** — independent. Not blocked by, does not block this track. May consume the env-var protocol (FR6.1 + F6.2) once integrated. - **`panel_defs_fleury_migration_20260629`** (deferred) — future. Will consume `LayoutFile` + `get_layouts_dir()` from this track. ## Verification Criteria (Track Completion Gates) - [ ] All Phase 1-9 tasks committed (atomic per-task) - [ ] `tests/test_panels_visible_after_install.py` passes (Layer 1 sentinel) - [ ] `tests/test_visual_baseline_default.py` passes (Layer 2 pixel diff < 1%) - [ ] `tests/test_test_mode_env_vars.py` passes (Layer 3 env vars honored) - [ ] `tests/test_visual_baseline_catches_corrupt_ini.py` passes (FR8 negative test) - [ ] `scripts/check_visual_baseline.py --help` works; `--strict` mode exits 1 on diff > 1% - [ ] `scripts/run_tests_batched.py` includes the visual verification tests - [ ] `tests/artifacts/visual_baseline_default.png` is committed to master - [ ] `docs/guide_visual_verification.md` is committed; cross-referenced from `docs/Readme.md` - [ ] `conductor/tracks.md` schema updated to require `VERIFIED-` tag for `[x]`-completion of tracks touching `src/gui_2.py` - [ ] **MANUAL GATE**: user runs `uv run sloppy.py` from master, confirms panels render visibly. User commits the `VERIFIED-` tag. - [ ] `docs/reports/TRACK_COMPLETION_default_layout_extract_20260629.md` committed - [ ] Tier-2 branch status: marked for archival (user's responsibility per AGENTS.md "Inherited-Cruft") ## Scope Summary (per workflow.md "Tier 1 Track Initialization Rules") - **Scope**: 9 phases, ~36 tasks - **Files touched**: ~12 (3 new: `src/layouts.py`, `layouts/default.ini`, `tests/artifacts/visual_baseline_default.png`, `scripts/check_visual_baseline.py`, `docs/guide_visual_verification.md`; 6 modified: `src/gui_2.py`, `src/paths.py`, `src/commands.py`, `tests/test_layout_reorganization.py`, `tests/test_panels_visible_after_install.py` (new), `tests/test_visual_baseline_default.py` (new), `tests/test_test_mode_env_vars.py` (new), `tests/test_visual_baseline_catches_corrupt_ini.py` (new), `scripts/run_tests_batched.py`, `conductor/tracks.md`, `docs/Readme.md`) - **Sites modified**: ~15 (in `_post_init`, `App.run`, `_install_default_layout_*`, `_diag_layout_state`, etc.) - **Tasks**: ~36 ## Risk Register - **R1** — Win32 PrintWindow may fail for the imgui-bundle HelloImGui window (HWND lookup or print flags). **Mitigation**: pre-flight check `win32gui.IsWindow(hwnd)` before capture; fall back to `BitBlt` of the screen region. - **R2** — Pixel baseline may be too sensitive (font hinting, GPU driver variations). **Mitigation**: tolerance is 1%; if false positives appear, raise to 2% and document. - **R3** — Forced viewport env var may not work on multi-monitor systems. **Mitigation**: scope the env var to test fixtures only (`tests/conftest.py` sets it before spawning). - **R4** — Tier-2 sandbox has uncommitted edits that may conflict when cherry-picking. **Mitigation**: cherry-pick to master directly (master is clean); tier-2 archival is user's responsibility. - **R5** — User-visible panel rendering depends on `_install_default_layout_pre_run_result` firing BEFORE `immapp.run`. If the user's cwd already has a valid `manualslop_layout.ini`, the install is skipped. The pixel baseline test must run with cwd-deleted `manualslop_layout.ini` to exercise the install path. **Mitigation**: `live_gui` fixture already cleans cwd before spawning.