Private
Public Access
0
0
Files
manual_slop/conductor/tracks/default_layout_install_20260629/metadata.json
T
ed 5ad062b13a conductor(track): init default_layout_install_20260629 (empty INI -> install default; layouts/ at root + src/layouts.py; reset_layout path cleanup)
Bug: when cwd/manualslop_layout.ini is missing/empty after first-run,
post-deletion, or post-corrupt-INI, the GUI panels are not visible
despite show_windows[name] = True. Root cause is structural: imgui.begin
without [Window][name] + DockId in the INI produces a floating window
that gets clipped by the full-screen dockspace. Empirically confirmed:
8s of running produces a 585-byte INI containing only [Window][Debug##Default].

Fix shape (4 phases):
  Phase 1: relocate tests/artifacts/manualslop_layout_default.ini ->
           layouts/default.ini (at repo root, parallel to themes/ per
           user directive 'no configs in src/'); add src/paths.py
           'layouts' field + SLOP_GLOBAL_LAYOUTS env override (mirror
           themes pattern at line 60/83/150/210-216); add src/layouts.py
           loader module (mirror src/theme_models.py + src/theme_2.py
           contract; LayoutFile = @dataclass(frozen=True, slots=True)
           per the C11/Odin/Jai-in-Python value-type mandate).
  Phase 2: install-on-empty-INI in App._post_init. _install_default_layout_if_empty
           helper + drain helper, called BEFORE _diag_layout_state and
           BEFORE immapp.run. logs '[GUI] installed default layout: <src> -> <dst>'.
  Phase 3: drop hardcoded 'tests/artifacts/live_gui_workspace/...' path
           from src/commands.py:reset_layout line 369-376 (dead code in
           production; violates 'production code defaults to immediate
           directory' directive 2026-06-29).
  Phase 4: 3-test regression suite in tests/test_default_layout_install.py
           + 1 unit test in tests/test_reset_layout.py; user manual verify
           (delete INI, run sloppy.py standalone, see panels).

TDD red-first per task. Atomic per-task commits with git notes (per
conductor/workflow.md §Task Workflow step 9-10). No day estimates per
conductor/workflow.md §Tier 1 Track Initialization Rules.

Out of scope (deferred): panel_defs_fleury_migration - migrate the ~40
render_x functions to declarative PanelDef records per Ryan Fleury's
raddbg 'type view' / 'lens' pattern. Spec §Eventual Normalization Target
documents the design sketch + the transcripts at docs/transcripts/.
This track sets up layouts/ at repo root + src/layouts.py as the typed
loader so the future migration has somewhere to land.

Tracks.md row will be added in Phase 4 (Task 4.6) when the track ships.
2026-06-29 14:02:41 -04:00

111 lines
9.8 KiB
JSON

{
"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: <src> -> <dst>` 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/<thing>.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."
}
]
}