{ "track_id": "default_layout_install_20260629", "name": "Default Layout Install + Hardcoded Path Cleanup + layouts/ Stack", "status": "active", "branch": "tier2/post_module_taxonomy_de_cruft_20260627", "created": "2026-06-29", "owner": "Tier 1 (initialized); implementation delegated to Tier 2/3.", "blocked_by": [], "blocks": [], "scope": { "new_files": [ "layouts/default.ini", "src/layouts.py", "tests/test_default_layout_install.py", "tests/test_reset_layout.py" ], "modified_files": [ "src/paths.py (add `layouts: Path` field + SLOP_GLOBAL_LAYOUTS env override + get_layouts_dir() accessor, mirror themes pattern at line 60/83/150/210-216)", "src/gui_2.py (App._post_init install hook + drain helper `_install_default_layout_if_empty_result`, mirror the existing `_post_init_callback_result` and `_diag_layout_state_ini_text_result` drain pattern at line 1448+)", "src/commands.py (drop hardcoded tests/artifacts/... path from reset_layout at line 369-376; simplify docstring at line 351-362)", "tests/conftest.py:709 (path update from tests/artifacts/manualslop_layout_default.ini to layouts/default.ini)", "conductor/tracks.md (add row at end of Active Tracks)", "conductor/chronology.md (prepend row)" ], "deleted_files": [], "relocated_files": [ "tests/artifacts/manualslop_layout_default.ini -> layouts/default.ini (git mv preserves history; same content; new parallel-to-themes/ home at repo root per user directive 2026-06-29)" ] }, "estimated_effort": { "method": "scope (per workflow.md Tier 1 Track Initialization Rules. NO day estimates.)", "phase_1": "10 tasks: 1 audit + 1 git mv + 1 conftest path update + 4 src/paths.py layouts-field edits + 1 src/layouts.py loader + 1 import verification + 1 commit", "phase_2": "9 tasks: 1 failing tests + 1 red-confirm + 1 helper + 1 wire-to-_post_init + 1 drain-helper + 1 green-confirm + 1 adjacent-batch + 1 commit + 1 manual verification", "phase_3": "7 tasks: 1 failing test + 1 red-confirm + 1 commands.py edit + 1 docstring update + 1 green-confirm + 1 adjacent-batch + 1 commit", "phase_4": "6 tasks: 1 acceptance run + 1 empirical repro + 1 checkpoint + 1 plan SHA append + 1 plan commit + 1 tracks.md row" }, "verification_criteria": [ "G1: when cwd/manualslop_layout.ini is missing or <1000 bytes or has 0 [Window][ entries, App._post_init installs layouts/default.ini (resolved via src/layouts.py + src/paths.py:get_layouts_dir()) to cwd/manualslop_layout.ini BEFORE immapp.run; log line `[GUI] installed default layout: -> ` is emitted", "G2: after install, the merged show_windows state has the 8 default-true windows (Project Settings, Files & Media, AI Settings, Discussion Hub, Operations Hub, Theme, Log Management, Diagnostics) set to True even if config.toml previously pinned them to False", "G3: src/commands.py:reset_layout has only 1 path in layout_paths list (cwd-relative); the tests/artifacts/live_gui_workspace/manualslop_layout.ini reference is gone (verified via inspect.getsource assertion in tests/test_reset_layout.py)", "G4: tests/test_default_layout_install.py exists and has 3+ tests, all passing: test_default_layout_installed_when_ini_missing, test_default_layout_installed_when_ini_empty, test_default_layout_NOT_installed_when_layout_present", "G5: layouts/default.ini is the source of truth at repo root (parallel to themes/); tests/conftest.py:709 reads from the new path; the old tests/artifacts/manualslop_layout_default.ini is gone (git mv relocated it)", "G6: src/paths.py declares a `layouts: Path` field (mirror of themes line 60); resolves layouts = root_dir / 'layouts' (mirror line 83); supports SLOP_GLOBAL_LAYOUTS env + config-file override (mirror line 150); exposes get_layouts_dir() accessor (mirror line 210-216)", "G7: src/layouts.py exists with LayoutFile @dataclass(frozen=True, slots=True) + load_layouts_from_dir(path, scope) + load_layouts_from_disk() consumer (mirror src/theme_models.py:181-225 + src/theme_2.py:340-346; uses Result[T] per data-oriented convention)", "G8: tests/conftest.py:709 reads from layouts/default.ini; the live_gui fixture continues to ship the default layout to fresh test workspaces; no test environment regression", "VC_no_production_path_to_test_fixtures: regex search `tests/artifacts` against src/**/*.py returns 0 matches (the prior false positive at src/commands.py:371 is gone)", "VC_no_configs_in_src: regex search `\\.ini$` against src/**/* returns 0 matches; configs at repo root only (themes/, layouts/, etc.)" ], "regressions_and_pre_existing_failures": [], "pre_existing_failures_remaining": [], "deferred_to_followup_tracks": [ { "title": "panel_defs_fleury_migration", "description": "Migrate the ~40 imperative render_x functions and `_render_window_if_open(name, lambda: render_x(app))` call sites in src/gui_2.py into declarative PanelDef records (name, render_callable, dock_target, default_visible, pops_out) per Ryan Fleury's raddbg 'type view' / 'lens' pattern (talk transcripts at docs/transcripts/rcJwvx2CTZY_ryan_fleury_raddbg_codebase_intro.json and docs/transcripts/_9_bK_WjuYY_ryan_fleury_raddbg_walkthrough.json). The render loop becomes `for panel in PANELS: if app.show_windows.get(panel.name): panel.render(app)`. Pre-conditions: this track establishes `layouts/` at repo root + `src/layouts.py` as the typed loader so the future migration has somewhere to land.", "track_status": "not yet initialized; deferred per user directive 2026-06-29 ('I don't need to full on convert the gui definitions in the codebase to this way of defining them but just something to keep in mind')" }, { "title": "test_engine_integration_20260627 (separate ongoing track)", "description": "Bridge the imgui test engine so visual regression can verify 'panels are visible' rather than relying on the INI-content proxy this track uses. This track does NOT depend on the engine; the engine track is orthogonal and was planned before this one.", "track_status": "active (separate track; not blocked by this one)" }, { "title": "Visual-regression coverage of empty-INI recovery", "description": "After test_engine_integration ships, replace the INI-content assertion (G4) with `ctx.capture_screenshot_window('Project Settings')` + baseline PNG diff. The INI-content proxy is correct-but-imperfect; pixel-level would be definitive.", "track_status": "not yet initialized; follows test_engine_integration Track 3" }, { "title": "Multiple bundled layouts", "description": "After the default layout lands, optionally add `layouts/compact.ini` (small-screen), `layouts/wide.ini` (wide-screen), etc. so users can pick via WorkspaceProfile. Defer until user asks.", "track_status": "not yet initialized; opportunistic follow-up" } ], "risk_register": [ { "id": "R1", "description": "Install runs in _post_init (main thread) BEFORE immapp.run reads the INI; if HelloImGui caches the INI filename and resolves it on a different thread, the install may be too late", "likelihood": "low", "impact": "install runs but panels still invisible on first render", "mitigation": "_post_init is the canonical post-init callback wired in src/gui_2.py:685-687; it runs synchronously before the GL/window loop starts. ImGui reads the INI inside immapp.run() during startup. Order is deterministic. Empirical verification via Task 2.9 (user launches sloppy.py standalone with deleted INI; confirms panels visible)." }, { "id": "R2", "description": "shutil.copy2 overwrites a user-customized INI silently; users who intentionally crafted a tiny stub INI to suppress dock saves lose their work", "likelihood": "low", "impact": "data loss for power users", "mitigation": "The empty-INI heuristic is 'file missing OR size < 1000 bytes OR zero [Window][ entries'. Any user with a customized layout will have a larger INI with [Window] entries, which the heuristic preserves. Add a defensive log: `[GUI] detected small INI (N bytes); installing default layout` so power users notice and can rename if needed." }, { "id": "R3", "description": "layouts/default.ini is not in the wheel (git mv's content is fine but a future wheel-build pipeline might exclude it)", "likelihood": "low", "impact": "RuntimeError or FileNotFoundError on first launch for end users", "mitigation": "src/layouts.py catches FileNotFoundError and drains to _startup_timeline_errors. The themes/ pattern at src/theme_2.py:340-346 already handles this precedent. Pre-flight check via Task 4.1 (acceptance run from a fresh wheel-less dev install) catches this." }, { "id": "R4", "description": "Default-true windows in the bundled INI diverge from _default_windows in src/app_controller.py:2086-2108 (e.g., a window renamed but only one of the two got updated)", "likelihood": "medium", "impact": "visually inconsistent — some panels docked, some not", "mitigation": "The bundled INI is intentionally narrower than _default_windows (it omits MMA Dashboard, Task DAG, Tier 1-4, Message, Tool Calls, Text Viewer, etc. — those start hidden per user preference 'I don't want mma to be visible by default' documented at tests/artifacts/manualslop_layout_default.ini:20-22). The convergence assertion is in Task 4.1: 7+ of 9 default-true windows must appear in the saved INI." }, { "id": "R5", "description": "src/layouts.py is a new file; per the file-naming HARD RULE in AGENTS.md ('New src/.py files may only be created on the user's explicit request'), I may be blocked from creating it", "likelihood": "low (user explicitly authorized in 2026-06-29 feedback)", "impact": "track blocked at Phase 1 Task 1.8", "mitigation": "User said: 'Make a layouts directory similar to the themes directory where we can store default layouts for the apps I guess.' This is explicit authorization for the parallel pattern. src/layouts.py mirrors src/theme_2.py/src/theme_models.py exactly." } ] }