Private
Public Access
0
0

conductor(plan): initialize result_migration_gui_2_20260619 (sub-track 4)

Sub-track 4 of the 5-sub-track result_migration_20260616 umbrella.
Migrates src/gui_2.py (the largest source file at 260KB / 7282 lines;
the immediate-mode ImGui rendering layer) to the data-oriented
Result[T] convention.

Scope: 42 migration-target sites (38 V + 2 S + 2 UNCLEAR) + 6 infra
sites for the drain plane. Per the user's directive (2026-06-19),
the phase structure is EXTRA LONG (13 phases instead of the umbrella's
1-2) to give Tier 2 well-defined narrow scope per phase. No phase has
more than 10 migration sites. This is the anti-sliming protocol:
previous sub-tracks slimed when scope felt tight (sub-track 2 Phase 10
slimed 21/26 sites via 5 laundering heuristics; sub-track 3 Phase 3
slimed 8 sites via logging.debug bodies). The 13-phase structure with
per-phase audit gates prevents sliming.

The 13 phases:
  0. Setup + styleguide re-read (Tier 2 reads error_handling.md)
  1. Site inventory + classification (42 sites in PHASE1_SITE_INVENTORY.md)
  2. Drain plane wiring (3 new render functions: render_controller_error_modal,
     _render_worker_error_indicator, _render_last_request_errors_modal)
  3. INTERNAL_BROAD_CATCH Batch A (render-loop, <=10 sites)
  4. INTERNAL_BROAD_CATCH Batch B (modal/dialog, <=10 sites)
  5. INTERNAL_BROAD_CATCH Batch C (event handlers, <=10 sites)
  6. Signal handler sites (<=5 sites; Pattern 3 drain: sys.exit)
  7. Worker/background sites (<=5 sites; thread-safety via app._worker_errors_lock)
  8. Property setter/state sites (<=5 sites)
  9. Helper/utility sites (<=5 sites)
  10. INTERNAL_SILENT_SWALLOW (<=13 sites; CRITICAL anti-sliming phase;
      per user principle 'logging is NOT a drain')
  11. INTERNAL_RETHROW classification (<=2 sites; Pattern 1/2/3)
  12. UNCLEAR classification (<=2 sites)
  13. Audit gate + end-of-track report (--strict exits 0; 11/11 tiers PASS)

Anti-sliming protocol per phase:
  - Styleguide re-read at start of each phase (commit msg acknowledgment)
  - Per-site audit pre/post check (capture before + after in commit body)
  - Per-phase invariant test (test_phase_N_invariant_count_dropped)
  - Per-file atomic commits (1 site = 1 commit)
  - 'If a site resists migration: DO NOT invent a heuristic. Report.'

The data plane (8 controller state attributes added by sub-track 3
Phase 6: _last_request_errors, _worker_errors + lock,
_startup_timeline_errors, _signal_handler_error, _inject_preview_error,
_mcp_config_parse_error, _save_project_error, _model_fetch_errors) is
the source of truth. Sub-track 4 adds the drain plane (3 new render
functions in Phase 2) and migrates the 42 sites to feed their errors
into the data plane.

Files:
  - spec.md (323 lines, 11 sections)
  - plan.md (938 lines, 13 phases, 60+ atomic commits, anti-sliming protocol)
  - metadata.json (14 VCs, 8 risks, scope)
  - state.toml (14 phases, 102 tasks, 22 verification entries)
  - tracks.md (new row 6d-4 in Active Tracks table)

Total: 5 files, 1327 lines added (excluding tracks.md).
Next: Tier 2 picks up Phase 0 (setup + styleguide re-read).
This commit is contained in:
2026-06-19 20:43:31 -04:00
parent 4fd79abcab
commit ac24b2f615
5 changed files with 2038 additions and 0 deletions
+1
View File
@@ -28,6 +28,7 @@ Tracks that are unblocked and ready to start. Ordered by **dependency** (blocked
| 6d-1 | A | [Result Migration Sub-Track 1: Review Pass](#track-result-migration-sub-track-1-review-pass-2026-06-17) | spec ✓, plan ✓, metadata ✓, state ✓; **shipped 2026-06-17** (43 sites classified: 23 compliant + 1 migration-target + 8 PATTERN_1/2 + 9 compliant + 1 audit-script-bug; 10 new heuristics added; 3 audit-script bugs documented) | `result_migration_20260616` (umbrella); `exception_handling_audit_20260616` (shipped 2026-06-16) | (**NEW 2026-06-17**; sub-track 1 of 5; 43 sites classified; no production code change; T-shirt S; per-site decisions feed sub-tracks 2-4; 3 audit-script bugs documented for sub-track 2 Phase 1) |
| 6d-2 | A | [Result Migration Sub-Track 2: Small Files + Audit-Script Bug Fixes](#track-result-migration-sub-track-2-small-files--audit-script-bug-fixes-2026-06-17) | spec ✓, plan ✓, metadata ✓, state ✓, **shipped 2026-06-18** (Phase 10 REJECTED for sliming 21 sites via 5 laundering heuristics; Phase 11 REDOES the 21 sites: 5 full Result migrations in warmup.py + 2 helper extracts + 14 documented; Phase 12 = ACTUAL full Result[T] migration: 16 sites in api_hooks.py + 27 sites in 16 small files; Heuristic #19 REMOVED; visit_Try bug FIXED; Heuristic D ADDED; Drain Points section in styleguide; **Phase 12 REJECTED for false test claim**; **Phase 13 = script crash fixed (UTF-8 reconfigure in run_tests_batched.py) + 3 failures investigated on parent commit (0 regressions) + 4 pre-existing Gemini 503 tests documented with @pytest.mark.skip + test_execution_sim_live switched from gemini_cli to gemini per user directive (STILL FAILS, reported for diff track); 11/11 tiers actually run; 9 PASS clean + 2 PASS with documented issues) | `result_migration_20260616` (umbrella); `result_migration_review_pass_20260617` (shipped 2026-06-17) | (**NEW 2026-06-17**; sub-track 2 of 5; 37 files (35 SMALL + 2 MEDIUM) with 76 sites; Phase 1 = 3 audit-script bugs fixed; Phases 3-8 = 49 sites migrated; Phase 10 = 26 SILENT_SWALLOW + 14 new UNCLEAR sites via full Result + 5 new heuristics; **Phase 10 REJECTED; Phase 11 = 5 full Result + 2 helper extracts + 14 documented; 5 laundering heuristics REVERTED; Heuristic A ADDED; Phase 12 = ACTUAL migration of all sites + styleguide Drain Points; Phase 13 = test count verification; 2 reported issues for diff tracks**) |
| 6d-3 | A | [Result Migration Sub-Track 3: App Controller](#track-result-migration-sub-track-3-app-controller-2026-06-18) | spec ✓, plan ✓, metadata ✓, state ✓, **active**; migrates 45 sites in `src/app_controller.py` to `Result[T]` (32 INTERNAL_BROAD_CATCH + 8 INTERNAL_SILENT_SWALLOW + 4 INTERNAL_RETHROW + 1 INTERNAL_OPTIONAL_RETURN); 22 sites stay as-is (15 BOUNDARY_FASTAPI + 2 BOUNDARY_SDK + 4 INTERNAL_COMPLIANT + 1 INTERNAL_PROGRAMMER_RAISE). **Phase 1 = fix the 2 known regressions** (test_tool_presets_execution::test_tool_ask_approval + test_extended_sims::test_execution_sim_live) caused by the half-migrated `session_logger.log_tool_call` call site in `_offload_entry_payload` (lines 3715, 3721). 5-file-commit pattern from `doeh_test_thinking_cleanup_20260615` (1 source + 1 test + 1 plan + 1 metadata + 1 state per task). 6 phases: (1) Setup + fix regressions; (2) 32 broad-catch → 4 bulk batches; (3) 8 silent-swallow → 2 batches with logging.debug per Heuristic #19; (4) 4 rethrow classified + 1 optional migrated; (5) Verify + audit + end-of-track report. | `result_migration_20260616` (umbrella); `result_migration_small_files_20260617` (shipped 2026-06-18) | (**NEW 2026-06-18**; sub-track 3 of 5; scope: 1 source file (src/app_controller.py) modified across 6 phases; 45 migration sites organized into 4 bulk batches + 3 single-site tasks; 1 new test file (test_app_controller_result.py) + 2 test files updated; 4 metadata/plan/state files; 1 end-of-track report; 18 atomic commits. **Scope larger than umbrella's T-shirt estimate** (45 migration + 22 stay = 67 total, not the estimated 22 + 34 = 56); the audit's per-category output is the source of truth, not the umbrella's T-shirt estimate**) |
| 6d-4 | A | [Result Migration Sub-Track 4: gui_2.py](#track-result-migration-sub-track-4-gui_2py-20260619) | spec ✓, plan ✓, metadata ✓, state ✓, **ready to start**; migrates 42 sites in `src/gui_2.py` (38 INTERNAL_BROAD_CATCH + 13 INTERNAL_SILENT_SWALLOW + 2 INTERNAL_RETHROW + 2 UNCLEAR); adds 3 new drain-plane render functions + 1 new test file. **Anti-sliming protocol: 13 phases cap each phase at <=10 sites with per-phase styleguide re-read + per-site audit pre/post check + per-phase invariant test.** | `result_migration_app_controller_20260618` (sub-track 3, SHIPPED 2026-06-19 with Phase 7; data plane ready) | (**NEW 2026-06-19**; sub-track 4 of 5; scope: 1 source file (src/gui_2.py) modified across 13 phases; 42 migration sites organized into 12 migration phases + 3 setup phases; 1 new test file (tests/test_gui_2_result.py) with 55+ tests; 4 metadata/plan/state/spec files; 1 end-of-track report; 60+ atomic commits. **Extra-long phase structure per user directive (2026-06-19) to prevent Tier 2 sliming.**) |
| 6e | A (meta-tooling) | [Tier 2 Autonomous Sandbox (unattended track execution)](#track-tier-2-autonomous-sandbox-new-2026-06-16) | spec ✓, plan ✓, **shipped 2026-06-16** (9 phases, 24 default-on tests + 4 opt-in tests + 1 smoke e2e) | (none — independent; **NEW 2026-06-16**; meta-tooling; eliminates the `permission: ask` bottleneck for well-regularized tracks via a 3-layer enforcement stack: OpenCode permission system + Windows restricted token + git hooks) |
| 7 | — | [UI Polish (Five Issues)](#track-ui-polish-five-issues) | spec ✓, plan ✓, ready to start (Phases 1/4/5 shipped; Phases 2/3 code shipped but tests broken — fixed by track 6a) | (none — independent) |
| 7a | B | [SQLite-Granularity Inline Docs for gui_2.py](#track-sqlite-granularity-inline-docs-for-gui_2py) | spec ✓, plan ✓, complete | (none — independent) |
@@ -0,0 +1,106 @@
{
"id": "result_migration_gui_2_20260619",
"name": "Result Migration - Sub-Track 4 (gui_2.py)",
"date": "2026-06-19",
"type": "refactor",
"priority": "A",
"spec": "conductor/tracks/result_migration_gui_2_20260619/spec.md",
"plan": "conductor/tracks/result_migration_gui_2_20260619/plan.md",
"status": "active",
"umbrella": "result_migration_20260616",
"sub_track_index": 4,
"blocked_by": {
"result_migration_app_controller_20260618": "shipped 2026-06-19 (with Phase 7); the data plane (8 controller state attributes) is ready"
},
"blocks": {
"result_migration_baseline_cleanup": "blocked by this track; date TBD when this track ships"
},
"scope": {
"new_files": [
"tests/test_gui_2_result.py",
"docs/reports/TRACK_COMPLETION_result_migration_gui_2_20260619.md",
"tests/artifacts/PHASE1_SITE_INVENTORY.md"
],
"modified_files": [
"src/gui_2.py",
"conductor/tracks.md",
"conductor/tracks/result_migration_gui_2_20260619/state.toml",
"conductor/tracks/result_migration_gui_2_20260619/metadata.json",
"conductor/tracks/result_migration_gui_2_20260619/plan.md",
"conductor/tracks/result_migration_gui_2_20260619/spec.md",
"conductor/tracks/result_migration_20260616/spec.md"
],
"deleted_files": []
},
"verification_criteria": [
"src/gui_2.py has zero INTERNAL_BROAD_CATCH sites (38 migrated across Phases 3, 4, 5)",
"src/gui_2.py has zero INTERNAL_SILENT_SWALLOW sites (13 migrated in Phase 10; per error_handling.md:530 logging is NOT a drain)",
"src/gui_2.py has zero INTERNAL_RETHROW sites (2 classified or migrated in Phase 11 per Pattern 1/2/3)",
"src/gui_2.py has zero UNCLEAR sites (2 classified in Phase 12)",
"src/gui_2.py has the 3 new drain-plane render functions: render_controller_error_modal, _render_worker_error_indicator, _render_last_request_errors_modal (Phase 2)",
"tests/test_gui_2_result.py has 55+ tests (42 site tests + 13 invariant tests), all pass",
"uv run python scripts/audit_exception_handling.py --src src/gui_2.py --strict exits 0",
"11-tier batched test suite passes with no new regressions",
"Per-phase audit gates verified: each phase's invariant test confirms the expected count drop",
"TIER-2 READ styleguide acknowledged in commit message at start of every phase (13 styleguide-ack commits)",
"Git history shows 60+ atomic commits (42 site migrations + 13 phase setup commits + 3 infra commits + 2 docs commits)",
"docs/reports/TRACK_COMPLETION_result_migration_gui_2_20260619.md covers all 13 phases",
"conductor/tracks.md row updated to 'shipped 2026-06-XX'",
"umbrella spec count updated to reflect actual scope (42 migration + 6 infra = 48 sites in this sub-track)"
],
"regressions_and_pre_existing_failures": [],
"pre_existing_failures_remaining": [],
"deferred_to_followup_tracks": [
{
"title": "Sub-track 5: result_migration_baseline_cleanup",
"description": "Close the remaining 77 violations in the 3 refactored baseline files (mcp_client.py, ai_client.py, rag_engine.py). Per umbrella sub-track 5.",
"track_status": "planned (blocked by this track)"
}
],
"estimated_effort": {
"method": "scope (per workflow.md Tier 1 Track Initialization Rules). NO day estimates.",
"scope": "1 source file (src/gui_2.py) modified across 13 phases; 42 migration sites + 6 infra sites organized into 12 migration phases (3-12) + 1 setup phase (0) + 1 inventory phase (1) + 1 drain-plane phase (2) + 1 verification phase (13); 1 new test file (tests/test_gui_2_result.py) with 55+ tests; 4 metadata/plan/state/spec files; 1 end-of-track report; 1 site inventory doc. 60+ atomic commits."
},
"risk_register": [
{
"risk": "Tier 2 invents a laundering heuristic for the 2 UNCLEAR sites (L1349 from sub-track 1's review pass)",
"likelihood": "medium",
"mitigation": "Phase 12 forces explicit classification with comment per site; the Phase 7 heuristic (sub-track 3) already classifies correctly; 5 regression-guard tests in tests/test_audit_heuristics.py lock the heuristic"
},
{
"risk": "Tier 2 doesn't migrate INTERNAL_SILENT_SWALLOW sites that 'look like' logging-only but aren't actually drained (the sliming pattern)",
"likelihood": "medium",
"mitigation": "Phase 1 inventory forces explicit classification per site BEFORE coding (tests/artifacts/PHASE1_SITE_INVENTORY.md); Phase 10's audit gate enforces 0 INTERNAL_SILENT_SWALLOW; styleguide re-read at start of Phase 10 explicitly calls out the sliming risk"
},
{
"risk": "gui_2.py's render loop changes break the immediate-mode frame",
"likelihood": "medium",
"mitigation": "Render-loop sites are isolated in Phase 3 (Batch A); visual verification via live_gui tests; per-site unit tests verify success-path output is identical"
},
{
"risk": "Scope grows as Tier 2 finds more sites mid-migration",
"likelihood": "low",
"mitigation": "Phase 1 inventory freezes the 42-site list; new sites discovered mid-migration are tracked but NOT migrated in this track (added to a follow-up)"
},
{
"risk": "User's principle ('logging is NOT a drain') is misapplied",
"likelihood": "low",
"mitigation": "Styleguide re-read at start of each phase; commit-message acknowledgment ('TIER-2 READ ...'); 13 invariant tests verify per-phase progress"
},
{
"risk": "Thread-safety violation in worker sites (Phase 7)",
"likelihood": "low",
"mitigation": "app._worker_errors_lock is already in place (sub-track 3 Phase 6); multi-thread unit test (test_worker_<site>_thread_safe_under_concurrent_appends) verifies"
},
{
"risk": "11-tier batched suite times out before all tiers run (per result_migration_small_files_20260617 Phase 12->13 incident)",
"likelihood": "medium",
"mitigation": "Phase 13 uses uv run python scripts/run_tests_batched.py (the fixed script from sub-track 2 Phase 13.1); if it times out, Tier 2 reports and the user decides"
},
{
"risk": "Per-phase audit gate shows wrong count (heuristic misclassification)",
"likelihood": "low",
"mitigation": "The audit heuristic was verified by 5 regression-guard tests in sub-track 3 Phase 7; if a count is wrong, Tier 2 reports"
}
]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,452 @@
# Track Specification: Result Migration — Sub-Track 4 (gui_2.py)
**Track ID:** `result_migration_gui_2_20260619`
**Status:** Active (spec approved 2026-06-19)
**Priority:** A (completes the data-oriented error handling convention for the largest source file)
**Owner:** Tier 2 Tech Lead
**Type:** refactor (13 phases; anti-sliming protocol enforced per phase)
**Scope:** 54 sites across 1 source file (`src/gui_2.py`, 260KB / 7282 lines) + 1 new test file + 3 new render functions
**Parent tracks:** `result_migration_20260616` (umbrella), `result_migration_app_controller_20260618` (sub-track 3, SHIPPED 2026-06-19 with Phase 7), `result_migration_small_files_20260617` (sub-track 2, SHIPPED 2026-06-18), `result_migration_review_pass_20260617` (sub-track 1, SHIPPED 2026-06-17), `data_oriented_error_handling_20260606` (convention ancestor, SHIPPED 2026-06-12)
> **Note on effort estimates:** per Tier 1 rules (see `conductor/workflow.md` §"Tier 1 Track Initialization Rules"), this spec does NOT include day estimates. Effort is measured by scope (N files, M sites, N phases). The user / Tier 2 agent decides the actual pacing.
---
## 0. TL;DR
This is sub-track 4 of the 5-sub-track `result_migration_20260616` umbrella. It migrates `src/gui_2.py` (the largest source file in the codebase; the immediate-mode ImGui rendering layer) to the data-oriented `Result[T]` convention. The umbrella originally estimated 55 sites at T-shirt XL; the current audit shows 54 sites (38 V + 2 S + 2 UNCLEAR + 12 C) — the UNCLEAR count dropped 14→2 after sub-track 1's review pass and sub-track 3 Phase 7's heuristic tightening reclassified them.
**Why 13 phases (not the umbrella's "1-2 phases"):** per the user's directive (2026-06-19), this track uses an **anti-sliming protocol** with extra phases to give Tier 2 well-defined, narrow scope per phase. The previous sub-tracks slimed when scope felt tight (sub-track 2 Phase 10 slimed 21 of 26 sites via 5 laundering heuristics; sub-track 3 Phase 3 slimed 8 sites via logging.debug bodies). The 13-phase structure caps each phase at ~10 sites with explicit per-phase audit gates.
**What this track consumes from sub-track 3:** 8 controller state attributes added by Phase 6 (`_last_request_errors`, `_worker_errors` + lock, `_startup_timeline_errors`, `_signal_handler_error`, `_inject_preview_error`, `_mcp_config_parse_error`, `_save_project_error`, `_model_fetch_errors`). These are the **data plane**; sub-track 4 adds the **drain plane** (3 new render functions) and migrates the 42 migration-target sites to feed their errors into the data plane.
**What this track enables:** sub-track 5 (`result_migration_baseline_cleanup`) which closes the 77 violations in the 3 refactored baseline files (mcp_client.py, ai_client.py, rag_engine.py). Once gui_2.py is migrated, the data-oriented convention is **fully applied** to all 65 src/ files except the baseline.
---
## 1. Overview
### 1.1 The State Before This Track (as of 2026-06-19)
Per `uv run python scripts/audit_exception_handling.py --src src/gui_2.py`:
```
src/gui_2.py (V=38, S=2, ?=2, C=12, total=54)
INTERNAL_BROAD_CATCH 25
INTERNAL_SILENT_SWALLOW 13
UNCLEAR 2
INTERNAL_RETHROW 2
INTERNAL_COMPLIANT 12
```
**Migration target: 38 V + 2 S + 2 UNCLEAR = 42 sites.** The 12 INTERNAL_COMPLIANT sites stay as-is. The 38 broad-catches are the bulk; the 13 silent-swallows are the sliming-prone ones.
### 1.2 The Goal
Migrate all 42 migration-target sites to the data-oriented convention, using the 8 controller state attributes as the data plane and adding 3 new render functions as the drain plane. After this track ships:
- 0 `INTERNAL_SILENT_SWALLOW` in `src/gui_2.py` (every logging-only except body is replaced with Result propagation).
- 0 `INTERNAL_BROAD_CATCH` in `src/gui_2.py` (every `except Exception` is converted to a `_result` helper + caller checks `.ok`).
- 0 `UNCLEAR` in `src/gui_2.py` (the 2 remaining sites are classified compliant or migrated).
- 0 `INTERNAL_RETHROW` (the 2 re-raise sites are classified as Pattern 1/2/3 from `error_handling.md` or migrated).
- `audit_exception_handling.py --src src/gui_2.py --strict` exits 0.
- 11-tier batched test suite passes with no new regressions.
### 1.3 The 13-Phase Structure (Anti-Sliming Protocol)
The umbrella estimated "1-2 phases" for sub-track 4. The user's directive (2026-06-19) is to use **extra phases** so Tier 2 has narrow, well-defined scope per phase. **No phase has more than 10 migration sites.** Every phase has a per-phase audit gate. Every phase starts with a styleguide re-read.
| Phase | Sites | Tests | Audit gate |
|---|---|---|---|
| 0. Setup + styleguide re-read | 0 | 0 | n/a |
| 1. Site inventory + classification | 0 | 0 | inventory doc complete |
| 2. Drain plane wiring (3 new render functions) | 0 | 3 | render functions render without crash |
| 3. INTERNAL_BROAD_CATCH batch A (render-loop) | ≤10 | ≤10 | INTERNAL_BROAD_CATCH count drops by batch A count |
| 4. INTERNAL_BROAD_CATCH batch B (modal/dialog) | ≤10 | ≤10 | count drops by batch B |
| 5. INTERNAL_BROAD_CATCH batch C (event handlers) | ≤10 | ≤10 | count drops by batch C |
| 6. Signal handler sites | ≤5 | ≤5 | drain verified (Pattern 3 from styleguide) |
| 7. Worker / background sites | ≤5 | ≤5 | thread-safety verified |
| 8. Property setter / state sites | ≤5 | ≤5 | side-effect chain verified |
| 9. Helper / utility sites | ≤5 | ≤5 | stateless verified |
| 10. INTERNAL_SILENT_SWALLOW migrations | ≤13 | ≤13 | count drops to 0 |
| 11. INTERNAL_RETHROW classification | ≤2 | ≤2 | all classified per Pattern 1/2/3 |
| 12. UNCLEAR classification | ≤2 | ≤2 | count drops to 0 |
| 13. Audit gate + end-of-track report | 0 | 1 invariant test | `--strict` exits 0; 11/11 tiers PASS |
**Total: ~42 migration sites + 6 infra sites + 55+ tests + 1 report, in 13 phases.**
---
## 2. Current State Audit (as of commit `f2fef7d2`)
### 2.1 Already Implemented (DO NOT re-implement)
These are the conventions and infrastructure already in place. Sub-track 4 MUST use them; sub-track 4 MUST NOT recreate them.
| Item | Location | What it does |
|---|---|---|
| `Result[T]` dataclass | `src/result_types.py:91-105` | The data-oriented container |
| `ErrorInfo` dataclass + `ErrorKind` enum | `src/result_types.py:117-130` | The canonical error type |
| `audit_exception_handling.py --strict` gate | `scripts/audit_exception_handling.py:1-1100` | The CI gate |
| `_is_fastapi_handler` heuristic (Phase 7 tightening) | `scripts/audit_exception_handling.py:318-460` | BOUNDARY_FASTAPI only when except body raises HTTPException or returns Result |
| `_except_body_drains_via_http_exception_or_result` | `scripts/audit_exception_handling.py:333` | Drain point detection |
| `_except_body_has_logging` | `scripts/audit_exception_handling.py:365` | Logging body detection |
| 5 regression-guard tests | `tests/test_audit_heuristics.py` | Lock the heuristic |
| `_last_request_errors` attribute | `src/app_controller.py:862` | Per-request error accumulator |
| `_worker_errors` + `_worker_errors_lock` | `src/app_controller.py` (Phase 6 Group 6.5) | Worker error accumulator |
| `_startup_timeline_errors` | `src/app_controller.py` (Phase 6 Group 6.2) | Startup error accumulator |
| `_signal_handler_error` | `src/app_controller.py` (Phase 6 Group 6.1) | Signal handler error |
| `_inject_preview_error` | `src/app_controller.py` (Phase 6 Group 6.3) | Inject preview error |
| `_mcp_config_parse_error` | `src/app_controller.py` (Phase 6 Group 6.3) | MCP config parse error |
| `_save_project_error` | `src/app_controller.py` (Phase 6 Group 6.3) | Project save error |
| `_model_fetch_errors` | `src/app_controller.py` (Phase 6 Group 6.4) | Per-provider model fetch errors |
| `_report_worker_error` helper | `src/app_controller.py` (Phase 6 Group 6.5) | Worker error drain |
| `_rag_search_result` helper | `src/app_controller.py:3475` | RAG search returns Result |
| `_symbol_resolution_result` helper | `src/app_controller.py` (Phase 6 Group 6.6) | Symbol resolution returns Result |
| `_execute_gui_task_result` helper | `src/app_controller.py` (Phase 6 Group 6.6) | GUI task returns Result |
| `error_handling.md` Drain Points section | `conductor/code_styleguides/error_handling.md:356-516` | The 5 drain patterns + heuristic D |
| `error_handling.md` Broad-Except table | `conductor/code_styleguides/error_handling.md:520-540` | `narrow + log = INTERNAL_SILENT_SWALLOW` (the rule) |
### 2.2 Gaps to Fill (This Track's Scope)
The umbrella originally estimated 55 sites; the current audit shows 54. The migration target is **42 sites** (38 V + 2 S + 2 UNCLEAR). Plus 6 infra sites for the drain plane.
**Per-file breakdown (gui_2.py only):**
- 25 INTERNAL_BROAD_CATCH (the bulk; render-loop + modal + event-handler batches)
- 13 INTERNAL_SILENT_SWALLOW (logging-only except bodies — the sliming-prone ones per the user's principle)
- 2 UNCLEAR (need manual classification in Phase 12)
- 2 INTERNAL_RETHROW (need Pattern 1/2/3 classification in Phase 11)
**Infrastructure gaps:**
- 3 new render functions for the drain plane (error modal consumer, worker error indicator, last-request errors modal)
- 1 new test file (`tests/test_gui_2_result.py`) with ≥55 tests
- 1 new invariant test per phase (13 total) to lock per-phase progress
---
## 3. Goals
### 3.1 Primary Goal
Migrate all 42 migration-target sites in `src/gui_2.py` to the data-oriented `Result[T]` convention, with each site's error either accumulating in one of the 8 controller state attributes (the data plane) OR triggering a drain modal immediately.
### 3.2 Secondary Goals
1. **Establish the drain plane** in gui_2.py: 3 new render functions (`render_error_tint_modal` consumer, `_render_worker_error_indicator`, `_render_last_request_errors_modal`) that read from the controller's data plane.
2. **Verify per-phase audit gates**: each phase's audit command shows the expected count drop.
3. **No new regressions**: 11/11 batched test tiers PASS at track end.
4. **Per-site unit tests**: 1 test per migrated site (≥42) + 1 invariant test per phase (13).
5. **No sliming**: per-phase protocol with styleguide re-read + audit gate.
### 3.3 Non-Goals
- Adding new error sites (this track migrates EXISTING `try/except`, not adds new ones).
- Changing the audit heuristic (sub-track 3 Phase 7 already tightened it; this track uses the existing heuristic).
- Migrating `tests/` files (the `public_api_migration_and_ui_polish_20260615` track already migrated 22 test files; the remaining tests are out of scope).
- Migrating `src/gui_2.py:1349` (the +1 site from sub-track 1's review pass) — that's already correctly classified by the Phase 7 heuristic; verify in Phase 12.
- Sub-track 5 (baseline cleanup) — separate track after this one ships.
---
## 4. Functional Requirements
### 4.1 Drain Plane Infrastructure (Phase 2)
**FR-DP-1** `src/gui_2.py` adds a new render function `render_controller_error_modal(app: App)` that:
- Reads `app._last_request_errors`, `app._worker_errors`, `app._startup_timeline_errors`, `app._signal_handler_error`, `app._inject_preview_error`, `app._mcp_config_parse_error`, `app._save_project_error`, `app._model_fetch_errors`.
- For each non-empty attribute, opens an `imgui.open_popup(f"Error: {attr_name}")` with the errors displayed.
- Returns nothing (drain point per `error_handling.md:396-407` Pattern 2).
**FR-DP-2** `src/gui_2.py` adds `_render_worker_error_indicator(app: App)` that:
- Renders a small status-bar widget (e.g., `[!] 3 worker errors`).
- Click opens `render_controller_error_modal`.
- Visible only when `app._worker_errors` is non-empty.
**FR-DP-3** `src/gui_2.py` adds `_render_last_request_errors_modal(app: App)` that:
- Reads `app._last_request_errors` and shows per-request errors.
- Called from `_handle_generate_send` after each AI request completes.
- Modal opens only if errors accumulated during the request.
### 4.2 INTERNAL_BROAD_CATCH Migrations (Phases 3, 4, 5)
**FR-BC-1** For each of the 25 INTERNAL_BROAD_CATCH sites, the migration follows this pattern:
1. Extract a `_render_<feature>_result(app, ...)` helper that returns `Result[T]` (T = the data the caller needs: `bool`, `dict`, `str`, `None`, etc.).
2. The helper's except body returns `Result(data=<zero-value>, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="gui_2.<helper>", original=e)])`.
3. The caller checks `.ok` and `.errors`. On error, the caller either accumulates in the appropriate controller attribute OR triggers `render_controller_error_modal` immediately.
**FR-BC-2** Batch A (Phase 3, render-loop sites): the ~10 broad-catch sites inside `render_*` functions called every frame. Failures here cannot crash the render loop; the migration must guarantee `try/finally` cleanup or `Result` propagation that doesn't propagate to the outer render frame.
**FR-BC-3** Batch B (Phase 4, modal/dialog sites): the ~8 broad-catch sites inside modal functions (e.g., `render_approve_script_modal`, `render_patch_modal`). Failures here CAN trigger `imgui.open_popup` to show the error inline (Pattern 2).
**FR-BC-4** Batch C (Phase 5, event handler sites): the ~7 broad-catch sites inside event handlers (e.g., `_handle_approve_ask`, `_handle_save_anyway_click`). Failures here accumulate in `app._last_request_errors` or a similar per-event accumulator.
### 4.3 Signal Handler Sites (Phase 6)
**FR-SH-1** The 2 INTERNAL_RETHROW sites in signal handlers (`_init_actions` + similar) are migrated to Pattern 3 from `error_handling.md:409-419`: `sys.stderr.write(...) + sys.exit(1)` IS the drain. The except body MUST NOT swallow the error; it MUST terminate the app or trigger an intentional drain.
### 4.4 Worker / Background Sites (Phase 7)
**FR-WB-1** The ~5 broad-catch sites in worker closures (callbacks invoked from `_io_pool`) use `app._report_worker_error(op_name, result)` helper (added in sub-track 3 Phase 6 Group 6.5) to drain errors to `app._worker_errors`. Thread-safety: `app._worker_errors_lock` is acquired on every append.
### 4.5 Property Setter / State Sites (Phase 8)
**FR-PS-1** The ~3 broad-catch sites in property setters / state mutations: each setter extracts a `_set_<attr>_result(app, value) -> Result[None]` helper; the legacy setter calls `_report_worker_error` on failure (per sub-track 3 Phase 6 Group 6.3 pattern for `_save_active_project`).
### 4.6 Helper / Utility Sites (Phase 9)
**FR-HU-1** The ~3 broad-catch sites in module-level helpers (e.g., `_check_auto_refresh_context_preview`): each helper returns `Result[T]`; callers check `.ok` and accumulate in the appropriate controller attribute.
### 4.7 INTERNAL_SILENT_SWALLOW Migrations (Phase 10)
**FR-SS-1** The 13 INTERNAL_SILENT_SWALLOW sites (logging-only except bodies) are the sliming-prone ones. Per the user's principle (2026-06-17) and `error_handling.md:530`, **logging is NOT a drain**. Each site MUST be migrated to `Result[T]` propagation. No narrowing + logging; no pass after logging; no "intentional silent recovery."
### 4.8 INTERNAL_RETHROW Classification (Phase 11)
**FR-RT-1** The 2 INTERNAL_RETHROW sites are classified per the 3 legitimate patterns from `error_handling.md:625-690`:
- Pattern 1: Catch + convert + raise as different type (compliant if convert is meaningful).
- Pattern 2: Catch + log + re-raise (compliant if log provides value beyond re-raise).
- Pattern 3: Catch + cleanup + re-raise via `try/finally` (compliant; canonical cleanup pattern).
If a site does not fit any pattern, it is migrated to Result[T] (NOT classified as "suspicious" — sliming).
### 4.9 UNCLEAR Classification (Phase 12)
**FR-UC-1** The 2 UNCLEAR sites are read individually; each is classified compliant (with a comment explaining why) or migrated. The audit script's heuristic should already classify them; verify the classification is correct per the Phase 7 heuristic (`_is_fastapi_handler` + drain detection).
### 4.10 Tests (per phase)
**FR-T-1** Every migration site has a unit test in `tests/test_gui_2_result.py` that verifies:
- The helper returns `Result[T]` with `data=<expected>` on success.
- The helper returns `Result[T]` with `errors=[ErrorInfo(...)]` on failure (mock the inner call to raise).
- The caller checks `.ok` and either accumulates or triggers a drain.
**FR-T-2** Every phase has 1 invariant test in `tests/test_gui_2_result.py` named `test_phase_N_<phase_name>_invariant` that verifies the per-phase audit gate (e.g., `test_phase_3_invariant_broad_catch_batch_a_dropped`).
---
## 5. Non-Functional Requirements
**NFR-1** `audit_exception_handling.py --src src/gui_2.py --strict` exits 0 at end of Phase 13.
**NFR-2** 11-tier batched test suite passes with no new regressions at end of Phase 13.
**NFR-3** All new code uses 1-space indentation per `conductor/product-guidelines.md` "AI-Optimized Compact Style."
**NFR-4** Per-file atomic commits (1 site = 1 commit) per `conductor/workflow.md`.
**NFR-5** Every migration phase's commit message includes "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase N" per the AI Agent Checklist.
**NFR-6** No diagnostic noise in production code (no `[X_DIAG] sys.stderr.write(...)` lines left uncommitted).
**NFR-7** No `@pytest.mark.skip` markers added (per `conductor/workflow.md` Skip-Marker Policy).
**NFR-8** No new `Optional[T]` return types (the convention's `Result[T]` ban in refactored files).
**NFR-9** No new `try/except` sites added that have logging-only except bodies (the sliming pattern).
**NFR-10** Hot reload is NOT used for verification (per `live_gui_test_fixes_20260618` findings; hot reload is fragile). Use live_gui tests instead.
---
## 6. Architecture Reference
- `conductor/code_styleguides/error_handling.md` — the canonical convention. **READ END-TO-END** at start of each phase.
- `conductor/code_styleguides/error_handling.md:356-516` — Drain Points section (5 patterns + Heuristic D).
- `conductor/code_styleguides/error_handling.md:462-476` — "What is NOT a drain point" (logging is NOT a drain).
- `conductor/code_styleguides/error_handling.md:520-540` — Broad-Except Distinction table.
- `conductor/code_styleguides/error_handling.md:809-940` — AI Agent Checklist (5 MUST-DO + 7 MUST-NOT-DO).
- `conductor/tracks/result_migration_app_controller_20260618/spec.md` §12-§21 — sub-track 3's Phase 6 addendum (the pattern this track mirrors).
- `conductor/tracks/result_migration_small_files_20260617/spec.md` — sub-track 2's sliming precedent (Phase 10→11 redo).
- `conductor/tracks/result_migration_review_pass_20260617/spec.md` — sub-track 1's UNCLEAR classification pattern.
- `docs/guide_gui_2.md` — gui_2.py architecture guide (the App class lifecycle, render function delegation pattern).
- `docs/guide_app_controller.md` — AppController + state attributes (the data plane this track consumes).
- `scripts/audit_exception_handling.py:318-460` — the Phase 7 audit heuristic (5 regression-guard tests in `tests/test_audit_heuristics.py` lock the behavior).
---
## 7. Per-Phase Migration Strategy
Each phase follows the **anti-sliming protocol**:
1. **Pre-phase styleguide re-read** (commits 1 of the phase): Tier 2 reads `error_handling.md` end-to-end. Commit message: "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase N."
2. **Site inventory check** (only Phase 1): Tier 2 walks the audit's JSON output for the phase's sites, classifies each (current code, target migration, drain point), writes the classification to `tests/artifacts/PHASE<N>_SITE_INVENTORY.md`.
3. **Red** (1 commit per site): Write the unit test in `tests/test_gui_2_result.py`. Run test — must FAIL.
4. **Audit pre-check** (no commit): `uv run python scripts/audit_exception_handling.py --src src/gui_2.py 2>&1 | grep "<pattern>"` to confirm the site's category BEFORE migration.
5. **Green** (1 commit per site): Migrate the site. Use a `_result` helper + the appropriate controller attribute OR a drain modal. Run test — must PASS.
6. **Audit post-check** (no commit): Same command. Confirm the site moved out of the violation category.
7. **Phase invariant test** (1 commit at end of phase): `test_phase_N_<phase>_invariant` verifies the per-phase count drop.
8. **Per-file atomic commit** per `workflow.md`.
If a site "resists migration" in any phase, Tier 2 MUST report (per `workflow.md` "Per-Task Decision Protocol") — not invent a heuristic. The user (Tier 1) decides whether to fix forward or defer.
### 7.1 Phase 0: Setup + Styleguide Re-Read
**Tasks:**
- Create track directory (already exists: `conductor/tracks/result_migration_gui_2_20260619/`)
- Update `conductor/tracks.md` with new row
- Tier 2 reads `conductor/code_styleguides/error_handling.md` end-to-end
- Acknowledge in commit message
**Verify:** No code; verification is the commit message.
### 7.2 Phase 1: Site Inventory + Classification
**Tasks:**
- Run `uv run python scripts/audit_exception_handling.py --src src/gui_2.py --json > tests/artifacts/PHASE1_AUDIT.json`
- Walk every finding; for the 42 migration-target sites, record: line, category, current code, target migration pattern, drain point
- Write `tests/artifacts/PHASE1_SITE_INVENTORY.md` (markdown table)
**Verify:** The inventory doc has 42 rows + is committed.
### 7.3 Phase 2: Drain Plane Wiring
**Tasks:**
- Add `render_controller_error_modal(app: App)` (read all 8 controller attributes; drain to imgui popup)
- Add `_render_worker_error_indicator(app: App)` (status-bar widget)
- Add `_render_last_request_errors_modal(app: App)` (per-request error modal)
- Wire each render function into the appropriate existing call sites
- 3 unit tests verifying each render function renders without crash when attributes are populated / empty
**Verify:** The 3 render functions exist; the 3 tests pass; `audit --strict` still passes (no new violations introduced).
### 7.4 Phase 3: INTERNAL_BROAD_CATCH Batch A (Render-Loop)
**Scope:** The ~10 broad-catch sites in render-loop functions (sites called every frame from `render_main_interface`).
**Migration pattern:**
- Each `_render_<feature>` function extracts a `_render_<feature>_result(app, ...) -> Result[bool]` helper.
- The helper's except body returns `Result(data=False, errors=[ErrorInfo(...)])`.
- The caller checks `.ok`; if False, the helper's caller logs to `app._last_request_errors` (or a render-loop-specific accumulator).
**Verify:** `--strict` exits 0 for the batch A sites; 10 unit tests pass; render-loop output is identical for success paths.
### 7.5 Phase 4: INTERNAL_BROAD_CATCH Batch B (Modal/Dialog)
**Scope:** The ~8 broad-catch sites in modal functions (`render_approve_script_modal`, `render_patch_modal`, etc.).
**Migration pattern:**
- Each modal extracts a `<modal>_<action>_result(app, ...) -> Result[bool]` helper.
- On error, the caller triggers `render_controller_error_modal` immediately (Pattern 2 drain).
**Verify:** 8 unit tests pass; modal error messages render correctly when triggered.
### 7.6 Phase 5: INTERNAL_BROAD_CATCH Batch C (Event Handlers)
**Scope:** The ~7 broad-catch sites in event handlers (`_handle_approve_ask`, etc.).
**Migration pattern:**
- Each handler extracts a `_handle_<event>_result(app, ...) -> Result[bool]` helper.
- On error, the caller accumulates in `app._last_request_errors` (the data plane).
**Verify:** 7 unit tests pass; the per-event accumulator is populated correctly.
### 7.7 Phase 6: Signal Handler Sites
**Scope:** The 2 INTERNAL_RETHROW sites in `_init_actions` + similar.
**Migration pattern:** Pattern 3 from styleguide: `sys.stderr.write(...) + sys.exit(1)` is the drain. The migration extracts a `_install_<signal>_result() -> Result[None]` helper; on failure, the helper writes to stderr + calls `sys.exit(1)`.
**Verify:** 2 unit tests pass; app termination is triggered correctly (use a test fixture that captures `sys.exit`).
### 7.8 Phase 7: Worker / Background Sites
**Scope:** The ~5 broad-catch sites in worker closures.
**Migration pattern:** Use `app._report_worker_error(op_name, result)` helper (added in sub-track 3 Phase 6 Group 6.5). Thread-safety: `app._worker_errors_lock` is acquired on every append.
**Verify:** 5 unit tests pass; thread-safety is verified with a multi-thread test that appends concurrently.
### 7.9 Phase 8: Property Setter / State Sites
**Scope:** The ~3 broad-catch sites in property setters / state mutations.
**Migration pattern:** Per sub-track 3 Phase 6 Group 6.3 pattern: extract `_set_<attr>_result(app, value) -> Result[None]`; legacy setter calls `_report_worker_error` on failure.
**Verify:** 3 unit tests pass.
### 7.10 Phase 9: Helper / Utility Sites
**Scope:** The ~3 broad-catch sites in module-level helpers.
**Migration pattern:** Each helper returns `Result[T]`; callers check `.ok` and accumulate in the appropriate controller attribute.
**Verify:** 3 unit tests pass.
### 7.11 Phase 10: INTERNAL_SILENT_SWALLOW Migrations
**Scope:** The 13 INTERNAL_SILENT_SWALLOW sites (logging-only except bodies).
**Migration pattern:** Per the user's principle (logging is NOT a drain). Each site extracts a `_<feature>_result(app, ...) -> Result[T]` helper; the except body returns `Result(data=<zero>, errors=[ErrorInfo(original=e)])`. No narrowing + logging; no pass after logging.
**Verify:** 13 unit tests pass; `--strict` audit shows 0 INTERNAL_SILENT_SWALLOW.
### 7.12 Phase 11: INTERNAL_RETHROW Classification
**Scope:** The 2 INTERNAL_RETHROW sites.
**Migration pattern:** Classify per Pattern 1/2/3 from `error_handling.md:625-690`. If a site does not fit any pattern, migrate to `Result[T]` (NOT classified as "suspicious").
**Verify:** 2 unit tests pass; the 2 sites are either classified compliant or migrated to Result.
### 7.13 Phase 12: UNCLEAR Classification
**Scope:** The 2 UNCLEAR sites.
**Migration pattern:** Read each site individually; classify compliant (with comment) or migrate. Verify the Phase 7 heuristic classifies correctly.
**Verify:** 2 unit tests pass; `--strict` audit shows 0 UNCLEAR.
### 7.14 Phase 13: Audit Gate + End-of-Track Report
**Tasks:**
- Run `uv run python scripts/audit_exception_handling.py --src src/gui_2.py --strict` — verify exit 0
- Run `uv run python scripts/run_tests_batched.py` — verify 11/11 tiers PASS
- Run `uv run python -m pytest tests/test_gui_2_result.py -v` — verify all tests pass
- Write `docs/reports/TRACK_COMPLETION_result_migration_gui_2_20260619.md`
- Update `conductor/tracks.md` row to "shipped"
- Update umbrella spec count
- Phase 13 checkpoint commit with git note
**Verify:** `--strict` exits 0; 11/11 tiers PASS; report is committed; tracks.md updated.
---
## 8. Verification Criteria
The track is "complete" when ALL of the following hold:
- **VC-1** `audit_exception_handling.py --src src/gui_2.py --strict` exits 0.
- **VC-2** 0 INTERNAL_BROAD_CATCH sites in `src/gui_2.py` (25 → 0).
- **VC-3** 0 INTERNAL_SILENT_SWALLOW sites in `src/gui_2.py` (13 → 0).
- **VC-4** 0 UNCLEAR sites in `src/gui_2.py` (2 → 0).
- **VC-5** 0 INTERNAL_RETHROW sites in `src/gui_2.py` (2 → 0 or classified compliant).
- **VC-6** 3 new render functions exist: `render_controller_error_modal`, `_render_worker_error_indicator`, `_render_last_request_errors_modal`.
- **VC-7** `tests/test_gui_2_result.py` exists with ≥55 tests (42 site tests + 13 invariant tests), all pass.
- **VC-8** 11-tier batched test suite passes with no new regressions.
- **VC-9** Per-phase audit gates verified (each phase's commit shows the expected count drop in the audit output).
- **VC-10** Tier 2 acknowledged styleguide re-read at start of each phase (commit message contains "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end").
- **VC-11** Git history shows ≥60 atomic commits (42 site migrations + 13 phase setup commits + 3 infra commits + 2 docs commits).
- **VC-12** End-of-track report at `docs/reports/TRACK_COMPLETION_result_migration_gui_2_20260619.md` covers all 13 phases.
- **VC-13** `conductor/tracks.md` row updated to "shipped 2026-06-XX."
- **VC-14** Umbrella spec count updated to reflect actual scope (42 migration sites + 6 infra sites = 48 sites in this sub-track; umbrella total now ~272 sites across all 5 sub-tracks).
---
## 9. Out of Scope
- **Sub-track 5** (`result_migration_baseline_cleanup`) — separate track; this track's shipping is the dependency.
- **Migrating `tests/` files** — out of scope per `conductor/tracks/data_oriented_error_handling_20260606/spec.md`.
- **Adding new `try/except` sites** — this track migrates EXISTING sites only.
- **Changing the audit heuristic** — sub-track 3 Phase 7 already tightened it; this track uses the existing heuristic.
- **Hot reload verification** — fragile per `live_gui_test_fixes_20260618`; use live_gui tests instead.
- **Removing the legacy wrappers** — when extracting `_result` helpers, the legacy wrappers are preserved (per sub-track 3 Phase 6 Group 6.3 pattern for `_save_active_project`); a follow-up track can migrate callers to the `_result` variants.
- **Wire-up of the 8 controller state attributes** — sub-track 3 Phase 6 already added the attributes; this track only consumes them.
---
## 10. Risks
| ID | Risk | Likelihood | Mitigation |
|---|---|---|---|
| R4-1 | Tier 2 invents a laundering heuristic for the 2 UNCLEAR sites at gui_2.py:1349 | medium | Phase 12 forces explicit classification with comment; the Phase 7 heuristic already classifies it; 5 regression-guard tests in `tests/test_audit_heuristics.py` lock the behavior |
| R4-2 | Tier 2 doesn't migrate INTERNAL_SILENT_SWALLOW sites that "look like" logging-only but aren't drained | medium | Phase 1 inventory forces explicit classification per site BEFORE coding; Phase 10's audit gate enforces 0 silent-swallow |
| R4-3 | gui_2.py's render loop changes break the immediate-mode frame | medium | Render-loop sites are isolated in Phase 3; visual verification via live_gui tests; per-site unit tests verify success-path output is identical |
| R4-4 | Scope grows as Tier 2 finds more sites mid-migration | low | Phase 1 inventory freezes the 42-site list; if new sites are discovered, they're tracked but NOT migrated in this track (added to a follow-up) |
| R4-5 | The user's principle ("logging is NOT a drain") is misapplied | low | Styleguide re-read at start of each phase; commit-message acknowledgment; 13 invariant tests verify per-phase progress |
| R4-6 | Thread-safety violation in worker sites (Phase 7) | low | `app._worker_errors_lock` is already in place (sub-track 3 Phase 6); multi-thread unit test verifies |
| R4-7 | The 11-tier batched suite times out before all tiers run (per `result_migration_small_files_20260617` Phase 12→13 incident) | medium | Phase 13 uses `uv run python scripts/run_tests_batched.py` (the fixed script from sub-track 2 Phase 13.1); if it times out, Tier 2 reports and the user decides |
| R4-8 | Per-phase audit gate shows wrong count (heuristic misclassification) | low | The audit heuristic was verified by 5 regression-guard tests in sub-track 3 Phase 7; if a count is wrong, Tier 2 reports |
---
## 11. See Also
- `conductor/code_styleguides/error_handling.md` — the canonical convention (READ at start of each phase)
- `conductor/code_styleguides/data_oriented_design.md` — the canonical DOD reference
- `docs/AGENTS.md` §"The 4 memory dimensions" — the cross-cutting lens
- `docs/guide_gui_2.md` — gui_2.py architecture guide
- `docs/guide_app_controller.md` — AppController state attributes (the data plane)
- `conductor/tracks/result_migration_20260616/spec.md` — the umbrella spec
- `conductor/tracks/result_migration_app_controller_20260618/spec.md` — sub-track 3 (the data plane source)
- `conductor/tracks/result_migration_small_files_20260617/spec.md` — sub-track 2 (the sliming precedent)
- `conductor/tracks/result_migration_review_pass_20260617/spec.md` — sub-track 1 (the UNCLEAR classification precedent)
- `conductor/tracks/live_gui_test_fixes_20260618/spec.md` — the hot-reload fragility findings (do NOT use hot reload)
- `scripts/audit_exception_handling.py` — the audit script (the gate)
- `tests/test_audit_heuristics.py` — the heuristic regression-guard tests
@@ -0,0 +1,189 @@
# Track state for result_migration_gui_2_20260619
# Updated by Tier 2 Tech Lead as tasks complete
[meta]
track_id = "result_migration_gui_2_20260619"
name = "Result Migration - Sub-Track 4 (gui_2.py)"
status = "active"
current_phase = 0
last_updated = "2026-06-19"
umbrella = "result_migration_20260616"
sub_track_index = 4
anti_sliming_protocol = "ENABLED — per-phase styleguide re-read + per-site audit pre/post check + per-phase invariant test; 13 phases cap each phase at <=10 sites"
[blocked_by]
result_migration_app_controller_20260618 = "shipped 2026-06-19 (with Phase 7); data plane ready"
[blocks]
result_migration_baseline_cleanup = "blocked by this track; date TBD when this track ships"
[phases]
phase_0 = { status = "pending", checkpointsha = "", name = "Setup + styleguide re-read (3 tasks)" }
phase_1 = { status = "pending", checkpointsha = "", name = "Site inventory + classification (3 tasks; 42 sites in PHASE1_SITE_INVENTORY.md)" }
phase_2 = { status = "pending", checkpointsha = "", name = "Drain plane wiring (4 tasks; 3 new render functions + 2 invariant tests)" }
phase_3 = { status = "pending", checkpointsha = "", name = "INTERNAL_BROAD_CATCH Batch A — render-loop sites (<=10 sites)" }
phase_4 = { status = "pending", checkpointsha = "", name = "INTERNAL_BROAD_CATCH Batch B — modal/dialog sites (<=10 sites)" }
phase_5 = { status = "pending", checkpointsha = "", name = "INTERNAL_BROAD_CATCH Batch C — event handler sites (<=10 sites)" }
phase_6 = { status = "pending", checkpointsha = "", name = "Signal handler sites (<=5 sites; Pattern 3 drain)" }
phase_7 = { status = "pending", checkpointsha = "", name = "Worker / background sites (<=5 sites; thread-safety)" }
phase_8 = { status = "pending", checkpointsha = "", name = "Property setter / state sites (<=5 sites)" }
phase_9 = { status = "pending", checkpointsha = "", name = "Helper / utility sites (<=5 sites)" }
phase_10 = { status = "pending", checkpointsha = "", name = "INTERNAL_SILENT_SWALLOW migrations (<=13 sites; logging NOT a drain)" }
phase_11 = { status = "pending", checkpointsha = "", name = "INTERNAL_RETHROW classification (<=2 sites; Pattern 1/2/3)" }
phase_12 = { status = "pending", checkpointsha = "", name = "UNCLEAR classification (<=2 sites)" }
phase_13 = { status = "pending", checkpointsha = "", name = "Audit gate + end-of-track report (5 tasks; --strict exits 0; 11/11 tiers PASS)" }
[tasks]
# Phase 0: Setup + styleguide re-read (3 tasks)
t0_1 = { status = "pending", commit_sha = "", description = "Update conductor/tracks.md with the new track row" }
t0_2 = { status = "pending", commit_sha = "", description = "Tier 2 reads conductor/code_styleguides/error_handling.md end-to-end; acknowledge in commit message" }
t0_3 = { status = "pending", commit_sha = "", description = "Phase 0 checkpoint commit; update state.toml Phase 0 status" }
# Phase 1: Site inventory + classification (3 tasks)
t1_1 = { status = "pending", commit_sha = "", description = "Run audit --src src/gui_2.py --json > tests/artifacts/PHASE1_AUDIT.json" }
t1_2 = { status = "pending", commit_sha = "", description = "Walk the audit + write tests/artifacts/PHASE1_SITE_INVENTORY.md (42 rows)" }
t1_3 = { status = "pending", commit_sha = "", description = "Create tests/test_gui_2_result.py with 2 Phase 1 invariant tests; Phase 1 checkpoint" }
# Phase 2: Drain plane wiring (4 tasks)
t2_1 = { status = "pending", commit_sha = "", description = "Add render_controller_error_modal(app) — reads 8 controller attributes; renders popups" }
t2_2 = { status = "pending", commit_sha = "", description = "Add _render_worker_error_indicator(app) — status bar widget with click-to-expand modal" }
t2_3 = { status = "pending", commit_sha = "", description = "Add _render_last_request_errors_modal(app) — per-request error modal" }
t2_4 = { status = "pending", commit_sha = "", description = "Add 2 Phase 2 invariant tests; Phase 2 checkpoint" }
# Phase 3: INTERNAL_BROAD_CATCH Batch A — render-loop sites (<=10)
t3_0 = { status = "pending", commit_sha = "", description = "Phase 3 styleguide re-read (Pattern 2 lines 396-407) + ack commit" }
t3_1 = { status = "pending", commit_sha = "", description = "Migrate first Batch A site (representative example with full code in plan.md)" }
t3_2 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 2" }
t3_3 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 3" }
t3_4 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 4" }
t3_5 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 5" }
t3_6 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 6" }
t3_7 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 7" }
t3_8 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 8" }
t3_9 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 9" }
t3_10 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 10 (if present)" }
t3_11 = { status = "pending", commit_sha = "", description = "Add Phase 3 invariant test (batch_a_count_dropped); Phase 3 checkpoint" }
# Phase 4: INTERNAL_BROAD_CATCH Batch B — modal/dialog sites (<=10)
t4_0 = { status = "pending", commit_sha = "", description = "Phase 4 styleguide re-read (Pattern 2) + ack commit" }
t4_1 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 1 (modal pattern: legacy wrapper triggers imgui.open_popup on failure)" }
t4_2 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 2" }
t4_3 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 3" }
t4_4 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 4" }
t4_5 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 5" }
t4_6 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 6" }
t4_7 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 7" }
t4_8 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 8" }
t4_9 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 9 (if present)" }
t4_10 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 10 (if present)" }
t4_11 = { status = "pending", commit_sha = "", description = "Add Phase 4 invariant test; Phase 4 checkpoint" }
# Phase 5: INTERNAL_BROAD_CATCH Batch C — event handler sites (<=10)
t5_0 = { status = "pending", commit_sha = "", description = "Phase 5 styleguide re-read + ack commit" }
t5_1 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 1 (event handler pattern: legacy wrapper appends to app._last_request_errors)" }
t5_2 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 2" }
t5_3 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 3" }
t5_4 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 4" }
t5_5 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 5" }
t5_6 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 6" }
t5_7 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 7" }
t5_8 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 8 (if present)" }
t5_9 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 9 (if present)" }
t5_10 = { status = "pending", commit_sha = "", description = "Migrate Batch C site 10 (if present)" }
t5_11 = { status = "pending", commit_sha = "", description = "Add Phase 5 invariant test; Phase 5 checkpoint" }
# Phase 6: Signal handler sites (<=5)
t6_0 = { status = "pending", commit_sha = "", description = "Phase 6 styleguide re-read (Pattern 3 lines 409-419) + ack commit" }
t6_1 = { status = "pending", commit_sha = "", description = "Migrate signal handler site 1 (Pattern 3: sys.stderr.write + sys.exit(1))" }
t6_2 = { status = "pending", commit_sha = "", description = "Migrate signal handler site 2" }
t6_3 = { status = "pending", commit_sha = "", description = "Migrate signal handler site 3 (if present)" }
t6_4 = { status = "pending", commit_sha = "", description = "Migrate signal handler site 4 (if present)" }
t6_5 = { status = "pending", commit_sha = "", description = "Migrate signal handler site 5 (if present)" }
t6_6 = { status = "pending", commit_sha = "", description = "Add Phase 6 invariant test; Phase 6 checkpoint" }
# Phase 7: Worker / background sites (<=5)
t7_0 = { status = "pending", commit_sha = "", description = "Phase 7 styleguide re-read + ack commit" }
t7_1 = { status = "pending", commit_sha = "", description = "Migrate worker site 1 (use app._report_worker_error; thread-safety via lock)" }
t7_2 = { status = "pending", commit_sha = "", description = "Migrate worker site 2" }
t7_3 = { status = "pending", commit_sha = "", description = "Migrate worker site 3" }
t7_4 = { status = "pending", commit_sha = "", description = "Migrate worker site 4" }
t7_5 = { status = "pending", commit_sha = "", description = "Migrate worker site 5" }
t7_6 = { status = "pending", commit_sha = "", description = "Add Phase 7 invariant test + thread-safety test; Phase 7 checkpoint" }
# Phase 8: Property setter / state sites (<=5)
t8_0 = { status = "pending", commit_sha = "", description = "Phase 8 styleguide re-read + ack commit" }
t8_1 = { status = "pending", commit_sha = "", description = "Migrate setter site 1 (per sub-track 3 Phase 6 Group 6.3 pattern)" }
t8_2 = { status = "pending", commit_sha = "", description = "Migrate setter site 2" }
t8_3 = { status = "pending", commit_sha = "", description = "Migrate setter site 3" }
t8_4 = { status = "pending", commit_sha = "", description = "Migrate setter site 4 (if present)" }
t8_5 = { status = "pending", commit_sha = "", description = "Migrate setter site 5 (if present)" }
t8_6 = { status = "pending", commit_sha = "", description = "Add Phase 8 invariant test; Phase 8 checkpoint" }
# Phase 9: Helper / utility sites (<=5)
t9_0 = { status = "pending", commit_sha = "", description = "Phase 9 styleguide re-read + ack commit" }
t9_1 = { status = "pending", commit_sha = "", description = "Migrate helper site 1" }
t9_2 = { status = "pending", commit_sha = "", description = "Migrate helper site 2" }
t9_3 = { status = "pending", commit_sha = "", description = "Migrate helper site 3" }
t9_4 = { status = "pending", commit_sha = "", description = "Migrate helper site 4 (if present)" }
t9_5 = { status = "pending", commit_sha = "", description = "Migrate helper site 5 (if present)" }
t9_6 = { status = "pending", commit_sha = "", description = "Add Phase 9 invariant test; Phase 9 checkpoint" }
# Phase 10: INTERNAL_SILENT_SWALLOW migrations (<=13) — CRITICAL anti-sliming phase
t10_0 = { status = "pending", commit_sha = "", description = "Phase 10 styleguide re-read (lines 462-540 logging NOT a drain) + ack commit (explicit sliming risk)" }
t10_1 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 1 (NO narrowing+logging; full Result[T] propagation)" }
t10_2 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 2" }
t10_3 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 3" }
t10_4 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 4" }
t10_5 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 5" }
t10_6 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 6" }
t10_7 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 7" }
t10_8 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 8" }
t10_9 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 9" }
t10_10 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 10" }
t10_11 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 11" }
t10_12 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 12" }
t10_13 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 13" }
t10_14 = { status = "pending", commit_sha = "", description = "Add Phase 10 invariant test (silent_swallow_count_zero); Phase 10 checkpoint" }
# Phase 11: INTERNAL_RETHROW classification (<=2)
t11_0 = { status = "pending", commit_sha = "", description = "Phase 11 styleguide re-read (Re-Raise Patterns lines 625-690) + ack commit" }
t11_1 = { status = "pending", commit_sha = "", description = "Classify INTERNAL_RETHROW site 1 per Pattern 1/2/3 or migrate to Result[T]" }
t11_2 = { status = "pending", commit_sha = "", description = "Classify INTERNAL_RETHROW site 2" }
t11_3 = { status = "pending", commit_sha = "", description = "Add Phase 11 invariant test; Phase 11 checkpoint" }
# Phase 12: UNCLEAR classification (<=2)
t12_0 = { status = "pending", commit_sha = "", description = "Phase 12 styleguide re-read + ack commit" }
t12_1 = { status = "pending", commit_sha = "", description = "Classify UNCLEAR site 1 (or migrate if non-compliant)" }
t12_2 = { status = "pending", commit_sha = "", description = "Classify UNCLEAR site 2" }
t12_3 = { status = "pending", commit_sha = "", description = "Add Phase 12 invariant test; Phase 12 checkpoint" }
# Phase 13: Audit gate + end-of-track report (5 tasks)
t13_1 = { status = "pending", commit_sha = "", description = "Run audit --src src/gui_2.py --strict; verify exit 0" }
t13_2 = { status = "pending", commit_sha = "", description = "Run tests/test_gui_2_result.py -v; verify all PASSED" }
t13_3 = { status = "pending", commit_sha = "", description = "Run scripts/run_tests_batched.py; verify 11/11 tiers PASS" }
t13_4 = { status = "pending", commit_sha = "", description = "Write docs/reports/TRACK_COMPLETION_result_migration_gui_2_20260619.md" }
t13_5 = { status = "pending", commit_sha = "", description = "Final checkpoint + tracks.md update + umbrella count update" }
[verification]
phase_0_complete = false
phase_1_complete = false
phase_2_complete = false
phase_3_complete = false
phase_4_complete = false
phase_5_complete = false
phase_6_complete = false
phase_7_complete = false
phase_8_complete = false
phase_9_complete = false
phase_10_complete = false
phase_11_complete = false
phase_12_complete = false
phase_13_complete = false
audit_strict_exits_0 = false
batched_suite_11_of_11_pass = false
site_inventory_has_42_rows = false
drain_plane_render_functions_exist = false
silent_swallow_count_zero = false
rethrow_count_zero = false
unclear_count_zero = false
broad_catch_count_zero = false