Private
Public Access
0
0

conductor(track): add Phase 10 — full Result[T] migration for 27 SILENT_SWALLOW + 14 new UNCLEAR sites

This commit is contained in:
2026-06-17 22:14:59 -04:00
parent 134ed4fb1b
commit a160b753bb
4 changed files with 256 additions and 34 deletions
@@ -37,7 +37,7 @@ sites** across the codebase.
**5 sub-tracks with consistent `result_migration_*` prefix:**
1. `result_migration_review_pass` (T-shirt: S) — 57 sites (32 UNCLEAR + 25 INTERNAL_RETHROW); updates the audit's heuristics
2. `result_migration_small_files` (T-shirt: L) — 37 files (35 SMALL + 2 MEDIUM); **shipped 2026-06-17** with documented G4 deviation: 76 sites (62V + 10S + 4 UNCLEAR) → 49 migrated (6 full `Result[T]` + 43 exception narrowing) + 13 already compliant + 27 silent-swallow sites remain (follow-up sub-track planned)
2. `result_migration_small_files` (T-shirt: L) — 37 files (35 SMALL + 2 MEDIUM); **shipped 2026-06-17** with documented G4 deviation: 76 sites (62V + 10S + 4 UNCLEAR) → 49 migrated (6 full `Result[T]` + 43 exception narrowing) + 13 already compliant + 27 silent-swallow sites remain; **Phase 10 in progress** (full Result[T] migration for the 27 sites + 2-3 new audit heuristics for the 14 new UNCLEAR sites)
3. `result_migration_app_controller` (T-shirt: XL) — 56 sites (35 V + 3 S + 2 ? + 16 C; 13 FastAPI boundary stay as-is)
4. `result_migration_gui_2` (T-shirt: XL) — **55 sites** (37 V + 2 S + **14 ?** + 2 C; the 14 ? includes the +1 site from the review pass: `src/gui_2.py:1349`)
5. `result_migration_baseline_cleanup` (T-shirt: L) — 112 sites (77 V + 10 S + 6 ? + 19 C in the 3 refactored files)
@@ -57,11 +57,11 @@ sites** across the codebase.
> the audit script is now correct (3 bugs fixed in Phase 1 of that sub-track),
> and the 37 SMALL+MEDIUM files have been processed:
> - **49/76 sites migrated** (6 full `Result[T]` + 43 exception narrowing) + 13 already compliant
> - **27 sites remain `INTERNAL_SILENT_SWALLOW`** (narrow-catch + pass); follow-up sub-track planned
> - **Audit's UNCLEAR count: 7 → 21** (+14 sites) the narrowing created patterns the audit's heuristics don't recognize; follow-up sub-track will add 2-3 new heuristics
> - **27 sites remain `INTERNAL_SILENT_SWALLOW`** (narrow-catch + pass); **Phase 10 in progress** (full Result[T] migration; not narrowing, not logging-only, not silent recovery)
> - **Audit's UNCLEAR count: 7 → 21** (+14 sites) - the narrowing created patterns the audit's heuristics don't recognize; **Phase 10 in progress** (2-3 new heuristics)
> - **Bonus defensive fix:** `try/except (OSError, tomllib.TOMLDecodeError)` in `load_track_state` unblocked 7+ tests
> - **Test result:** all 11 test tiers PASS (tier-1-unit-comms, tier-1-unit-core, tier-1-unit-gui, tier-1-unit-headless, tier-1-unit-mma, tier-2-mock_app-comms, tier-2-mock_app-core, tier-2-mock_app-gui, tier-2-mock_app-headless, tier-2-mock_app-mma, tier-3-live_gui)
> - **Documented G4 deviation:** 27 silent-swallow sites remain. A follow-up sub-track `result_migration_silent_swallow_followup_<date>` is planned (TBD; see "Recommended Sequence" below for the new ordering)
> - **Documented G4 deviation:** 27 silent-swallow sites remain. **Phase 10 of this sub-track** (not a separate sub-track) does the full Result[T] migration; the user has directed that Result[T] is mandatory, not optional, given the project's heavy use of multi-threaded `io_pool` dispatch (Python has no wave-based preemptive thread pipelining, so every soft/hard failure point needs full context).
---
@@ -127,7 +127,7 @@ applied. Both feed into all later sub-tracks.
**Scope:** 37 files (the 35 SMALL + 2 MEDIUM from the `--by-size` bucket);
**76 sites (62V + 10S + 4 UNCLEAR) → 49 migrated + 13 already compliant + 27 silent-swallow remain.**
**T-shirt size:** L (batched; ~750 lines changed across 37 files + 1 audit script + 1 new test file).
**Status:** **shipped 2026-06-17** with documented G4 deviation (27 sites remain `INTERNAL_SILENT_SWALLOW`; follow-up sub-track planned).
**Status:** **shipped 2026-06-17** with documented G4 deviation (27 sites remain `INTERNAL_SILENT_SWALLOW`; **Phase 10 of this sub-track** does the full Result[T] migration per the user's explicit direction).
**Why second:** the small files are quick wins; they don't depend on
the orchestrator (app_controller) or the GUI. Some of them DO depend on
@@ -153,8 +153,8 @@ Phase 1 of this sub-track (audit-script bug fixes) unblocks sub-tracks
public API changes may be acceptable. Tier 2 chose narrowing for 43 sites to
avoid ~100+ caller updates. **Caveat:** narrowing without `logging.warning(...)`
is **silent recovery** (no trace). The 27 sites that remain `INTERNAL_SILENT_SWALLOW`
are documented in the track completion report; a follow-up sub-track is
planned to add logging or full Result migration to them.
are documented in the track completion report; **Phase 10 of this sub-track** is
planned to do the full Result[T] migration for them.
- **Phase 9: Verification** — all 11 test tiers PASS; per-site report + track
completion report written; state.toml + metadata.json marked completed.
- **Bonus defensive fix:** `try/except (OSError, tomllib.TOMLDecodeError)` in
@@ -174,7 +174,7 @@ pass or narrow-catch + return None). These are categorized as:
**Migration-target sites introduced by the narrowing:** the audit's UNCLEAR count
went **7 → 21** (+14 sites) because the narrowing created patterns the audit's
heuristics don't recognize. A follow-up sub-track is planned to add 2-3 new heuristics
heuristics don't recognize. **Phase 10 of this sub-track** adds 2-3 new heuristics
(heavily-narrowed `except` without logging; `except` returning Result in non-`*_result`
function) that reclassify these.
@@ -1,8 +1,8 @@
{
"id": "result_migration_small_files_20260617",
"title": "Result Migration Sub-Track 2 (Small Files + Audit-Script Bug Fixes)",
"title": "Result Migration Sub-Track 2 (Small Files + Audit-Script Bug Fixes + Phase 10 Result[T] Follow-up)",
"type": "refactor + audit-script maintenance",
"status": "completed",
"status": "active",
"priority": "A",
"created": "2026-06-17",
"owner": "tier2-tech-lead",
@@ -17,13 +17,18 @@
"small_files": 35,
"medium_files": 2,
"sites_to_migrate": 76,
"sites_migrated_phase_3_to_8": 49,
"sites_migrated_phase_10": 0,
"violation_sites": 62,
"suspicious_sites": 10,
"unclear_sites": 4,
"unclear_sites_outside_review_scope": 4,
"audit_script_lines_changed": "~60 (3 bug fixes; one per commit)",
"audit_script_heuristics_added": "0-2 (conditional on the 4 UNCLEAR patterns)",
"report_lines": "~200-300 (per-site decisions for 4 UNCLEAR + per-file summary + audit-script fix summary)"
"silent_swallow_sites_remaining_after_phase_8": 27,
"new_unclear_sites_from_narrowing": 14,
"io_pool_callback_sites_to_thread_result": 4,
"audit_script_lines_changed": "~60 (3 bug fixes; one per commit) + ~30 (2-3 new heuristics in Phase 10)",
"audit_script_heuristics_added": "0-2 (conditional on the 4 UNCLEAR patterns) + 2-3 (Phase 10)",
"report_lines": "~200-300 (per-site decisions for 4 UNCLEAR + per-file summary + audit-script fix summary) + ~100 (Phase 10 addendum)"
},
"depends_on": [
"result_migration_20260616 (umbrella)",
@@ -43,17 +48,21 @@
"scripts/audit_exception_handling.py has the 3 documented bugs fixed (visit_Try walker, render_json filter, render_json truncation)",
"Re-running the audit post-Phase-1: src/rag_engine.py:31 is in the findings; per-file list is complete; per-file list is not truncated to top 15",
"The 4 UNCLEAR sites in SMALL files are classified (compliant or migration-target); decisions recorded in the report",
"All 37 files (35 SMALL + 2 MEDIUM) are migrated to the convention",
"Re-running the audit post-Phase-9: 0 migration-target sites in the 37-file scope",
"All 37 files (35 SMALL + 2 MEDIUM) are migrated to the convention (49 sites in Phase 3-8 + 27 sites in Phase 10)",
"Phase 10: full Result[T] migration for the 27 INTERNAL_SILENT_SWALLOW sites; no narrowing, no logging-only, no silent recovery. Every site returns Result[T] with structured ErrorInfo. Callers check result.ok and result.errors",
"Phase 10: 2-3 new audit heuristics that reclassify the 14 new UNCLEAR sites (created by the narrowing in Phase 3-8) as INTERNAL_COMPLIANT or BOUNDARY_*",
"Phase 10: the 4 io_pool callback sites (warmup.py:139/215/249 + hot_reloader.py:58) thread the Result through the io_pool completion handler; the completion handler checks result.ok",
"Re-running the audit post-Phase-10: 0 INTERNAL_SILENT_SWALLOW + 0 UNCLEAR + 0 migration-target sites in the 37-file scope (G4 deviation resolved)",
"Full test pass count: all 11 test tiers PASS",
"Atomic commits per batch: spec, plan, metadata, state, 3 audit-script fix commits, 4 UNCLEAR classification commits, 35 SMALL migration commits (5-7 files per commit), 2 MEDIUM migration commits, completion commits"
"Atomic commits per batch: spec, plan, metadata, state, 3 audit-script fix commits, 4 UNCLEAR classification commits, 35 SMALL migration commits (5-7 files per commit), 2 MEDIUM migration commits, Phase 10 commits (27 Result[T] migrations + 2-3 new heuristics + verification + completion), completion commits"
],
"out_of_scope": [
"Migrating the 3 BASELINE files (mcp_client, ai_client, rag_engine) - sub-track 5",
"Migrating src/gui_2.py or src/app_controller.py - sub-tracks 4 and 3",
"The send_result -> send mass rename - separate work after this phase",
"Refactoring the audit script's overall architecture - Phase 1 fixes 3 specific bugs only",
"Adding new Result patterns to areas that don't have any - this track migrates EXISTING sites only"
"Refactoring the audit script's overall architecture - Phase 1 fixes 3 specific bugs only; Phase 10 adds 2-3 new heuristics only",
"Adding new Result patterns to areas that don't have any - this track migrates EXISTING sites only",
"The 'public API' concern - this is a 20K LOC Python project, not enterprise. The convention requires Result[T] everywhere it can fail; callers are updated to check result.ok"
],
"risks": [
{
@@ -85,19 +94,43 @@
"id": "R6",
"description": "The MEDIUM files (session_logger, warmup) have complex migrations that don't fit the Result pattern",
"mitigation": "Per the styleguide, some sites are legitimately BOUNDARY_*; those stay as-is; decision is documented"
},
{
"id": "R7 (Phase 10)",
"description": "A SILENT_SWALLOW site is actually a conditional capture that needs to inspect the exception (e.g., 'if e.specific_field == X: handle_gracefully()')",
"mitigation": "Full Result migration preserves the exception in result.errors[0].exception; the caller can inspect it. The Result migration is not destructive of the original logic"
},
{
"id": "R8 (Phase 10)",
"description": "Migrating Result[T] through io_pool callbacks (warmup.py) requires the io_pool's API to accept Result returns",
"mitigation": "The io_pool already uses callback-based dispatch; the Result is delivered to the completion handler as a parameter. No io_pool change needed; the caller is updated to check result.ok"
},
{
"id": "R9 (Phase 10)",
"description": "The 2-3 new audit heuristics misclassify sites that should be INTERNAL_BROAD_CATCH or INTERNAL_SILENT_SWALLOW",
"mitigation": "TDD: each heuristic has a failing test first; the test suite covers the canonical patterns. If a heuristic is too broad, narrow the conditions and re-test"
}
],
"estimated_effort": {
"method": "Scope + T-shirt size (per conductor/workflow.md section Tier 1 Track Initialization Rules). NO day estimates. The user / Tier 2 agent decides the actual pacing.",
"scope": "37 files (35 SMALL + 2 MEDIUM); 76 sites; 3 audit-script bug fixes; ~200-300 lines of report",
"tshirt_size": "L"
"method": "Scope (per conductor/workflow.md section Tier 1 Track Initialization Rules). NO day estimates. The user / Tier 2 agent decides the actual pacing.",
"scope": "37 files (35 SMALL + 2 MEDIUM); 76 sites total (49 migrated in Phase 3-8 + 27 to migrate in Phase 10); 3 audit-script bug fixes in Phase 1; 2-3 new audit heuristics in Phase 10; ~200-300 lines of report + ~100 lines of Phase 10 addendum"
},
"deferred_to_followup_tracks": [
{
"id": "result_migration_subsequent_subtracks",
"title": "Result Migration Sub-Tracks 3-5",
"description": "After this sub-track ships, sub-tracks 3 (app_controller), 4 (gui_2), and 5 (baseline_cleanup) pick up the migration work. Sub-track 3 and 4 depend on the audit being correct (Phase 1 of this sub-track fixes the 3 bugs).",
"track_status": "blocked by this sub-track"
"description": "After this sub-track's Phase 10 ships, sub-tracks 3 (app_controller), 4 (gui_2), and 5 (baseline_cleanup) pick up the migration work. Sub-tracks 3 and 4 depend on the audit being correct (Phase 1 of this sub-track fixes the 3 bugs; Phase 10 adds 2-3 new heuristics).",
"track_status": "blocked by this sub-track (after Phase 10 ships)"
}
]
],
"outcomes": {
"phase_3_to_8_sites_migrated": 49,
"phase_10_sites_migrated": 0,
"phase_10_pending": true,
"silent_swallow_sites_remaining_pre_phase_10": 27,
"new_unclear_sites_from_narrowing": 14,
"phase_10_heuristics_added": 0,
"phase_10_io_pool_callbacks_threaded": 0,
"phase_10_status": "pending; user-directed follow-up to resolve the G4 deviation (27 SILENT_SWALLOW + 14 new UNCLEAR sites)"
}
}
@@ -318,6 +318,156 @@ The 35 SMALL files are batched 5-7 per commit (per the umbrella spec). The 2 MED
---
## Phase 10: Complete the Result[T] Migration (the 27 SILENT_SWALLOW + 14 new UNCLEAR sites)
Sub-track 2 shipped with a documented G4 deviation: 27 sites remain `INTERNAL_SILENT_SWALLOW` (narrow-catch + pass) and 14 new `UNCLEAR` sites emerged from the narrowing strategy. The user has directed that **all 27 must be fully migrated to `Result[T]`** — not narrowed, not logged-and-returned, not narrowed-with-log. The `Result[T]` convention is mandatory: every `try/except` site that can fail returns `Result[T]` with structured `ErrorInfo`, and the caller decides what to do. The 14 new UNCLEAR sites are addressed by 2-3 new audit heuristics that recognize the post-migration patterns.
This is a codebase-hardening phase. The project uses `io_pool` for multi-threaded dispatch; Python has no wave-based preemptive thread pipelining, so every soft/hard failure point needs full context (category, message, source, exception) — not silent recovery.
### 10.1 — Enumerate the remaining sites
- [ ] **Task 10.1.1: Run the audit and extract the 27 SILENT_SWALLOW + 14 new UNCLEAR sites**
- WHERE: `scripts/audit_exception_handling.py` (already on the branch from Phase 1)
- WHAT: `uv run python scripts/audit_exception_handling.py --json > audit_pre_phase10.json`; parse the per-file findings; for each file in the 37-file scope, list the SILENT_SWALLOW and new-UNCLEAR sites with file:line
- HOW: read the JSON; filter by category and by file
- OUTPUT: per-site list with file:line + current snippet + context function name
- COMMIT: `docs(track): enumerate Phase 10 target sites (27 SILENT_SWALLOW + 14 UNCLEAR)`
- GIT NOTE: Per-site enumeration; file:line; the 5 known sites (startup_profiler.py:40, file_cache.py:98, outline_tool.py:90, warmup.py:139/215/249, hot_reloader.py:58) plus the others to be enumerated
### 10.2 — Per-file full Result[T] migration
For each of the 27 SILENT_SWALLOW sites:
1. Read the function's current signature and behavior
2. Change the return type to `Result[T]` (or `Result[None]` if the function returns `None`)
3. Add `Result` import if needed (from `src/result_types.py`)
4. In the except body, capture the exception and convert to `ErrorInfo`:
```python
except SomeError as e:
return Result(data=NIL_T, errors=[ErrorInfo(
category="<category>",
message=str(e),
source="<module>.<function>",
exception=e,
)])
```
- If the function has a sensible fallback value (e.g., `default_value`), use `Result(data=default_value, errors=[...])` instead of `NIL_T`. The caller still sees the error in `.errors` and decides what to do.
5. Update **all** callers to check `.ok` and `.errors`. The caller decides what to do (log, fall back, surface to UI, re-raise as a thread-pipeline failure). No caller should ignore `.errors` silently.
6. Add a test for the new Result-based API. Tests must cover:
- The success path: `assert result.ok and result.data == <expected>`
- The error path: `assert not result.ok and result.errors[0].category == <expected> and result.errors[0].exception is SomeError`
- Callers that previously ignored the return value must be updated to check `result.ok`
The migration is per-file. Group files into atomic commits (1-2 sites per commit, or all sites in a file in one commit if the file is small). The 5 known sites to start with (from the track completion report):
- [ ] **Task 10.2.1: Migrate `src/startup_profiler.py:40` to `Result[T]`** (remove the `stderr.write` log; return Result with the profile data and the captured exception)
- [ ] **Task 10.2.2: Migrate `src/file_cache.py:98` to `Result[T]`** (the mtime cache fallback; return Result with the default cache value and the captured exception)
- [ ] **Task 10.2.3: Migrate `src/outline_tool.py:90` to `Result[T]`** (the ast.unparse fallback; return Result with the empty outline and the captured exception)
- [ ] **Task 10.2.4: Migrate `src/warmup.py:139` (on_complete callback) to `Result[T]`** (the user-callback error path; the callback now returns Result; the warmup manager threads the Result to the io_pool completion handler)
- [ ] **Task 10.2.5: Migrate `src/warmup.py:215` (_record_success callback) to `Result[T]`**
- [ ] **Task 10.2.6: Migrate `src/warmup.py:249` (_record_failure callback) to `Result[T]`**
- [ ] **Task 10.2.7: Migrate `src/hot_reloader.py:58` (module reload) to `Result[T]`** (the reload error path; the hot-reloader manager threads the Result to the module-reload completion handler)
The other 20 sites: tier-2 enumerates from the audit JSON (Task 10.1.1) and migrates each. Each site gets its own task in this phase; the plan's per-task list is updated as sites are enumerated.
### 10.3 — Audit heuristics for the 14 new UNCLEAR sites
The narrowing in sub-track 2 created 14 new UNCLEAR sites that the audit doesn't recognize. After the full Result migration in 10.2:
- Some of these will be reclassified automatically by existing heuristics (e.g., `Result`-returning code triggers `BOUNDARY_SDK` or heuristic #19 patterns)
- The remaining need 2-3 new heuristics in `scripts/audit_exception_handling.py`:
- **Heuristic A**: `try/except SomeError: return Result(data=NIL_T, errors=[ErrorInfo(...)])` in a non-`*_result` function → `INTERNAL_COMPLIANT` (the canonical Result-based recovery pattern, even when the function name doesn't end in `_result`)
- **Heuristic B**: `try/except SomeError: return Result(data=default_value, errors=[ErrorInfo(...)])` where the function's success path returns `Result(data=...)` → `INTERNAL_COMPLIANT` (the Result-based fallback pattern)
- **Heuristic C** (if needed): `try/except SomeError: return default_value` where the function's annotated return type is `Result[T]` → `INTERNAL_COMPLIANT` (the Result-typed fallback)
- [ ] **Task 10.3.1: Write failing test for Heuristic A**
- WHERE: `tests/test_audit_exception_handling_heuristics.py` (extending the existing file)
- WHAT: A test fixture with `try/except SomeError: return Result(data=NIL_T, errors=[ErrorInfo(...)])` in a function whose name doesn't end in `_result`. Assert the audit classifies the except as `INTERNAL_COMPLIANT`.
- HOW: same `subprocess` + fixture pattern as the existing tests
- [ ] **Task 10.3.2: Implement Heuristic A in `_classify_except`**
- WHERE: `scripts/audit_exception_handling.py` (the `_try_compliant_pattern` helper or `_classify_except` directly)
- WHAT: Detect the pattern; return `INTERNAL_COMPLIANT`
- HOW: AST inspection of the except body's `Return` statement; check that it returns a `Call` to `Result(...)` with `data=` and `errors=` kwargs; check that the enclosing function name does NOT end in `_result`
- COMMIT: `feat(scripts): heuristic A — Result-returning recovery in non-*_result function`
- [ ] **Task 10.3.3: Write failing test for Heuristic B**
- WHERE: `tests/test_audit_exception_handling_heuristics.py`
- WHAT: A test fixture with `try/except SomeError: return Result(data=default, errors=[...])` where the function's success path also returns `Result(...)`. Assert `INTERNAL_COMPLIANT`.
- HOW: same pattern as 10.3.1
- [ ] **Task 10.3.4: Implement Heuristic B in `_classify_except`**
- WHERE: `scripts/audit_exception_handling.py`
- WHAT: Detect the pattern; return `INTERNAL_COMPLIANT`
- HOW: Check the except body's `Return` is a `Result(...)` call with both `data=` and `errors=` kwargs; check the function has a success path that also returns `Result(...)`
- COMMIT: `feat(scripts): heuristic B — Result-typed fallback pattern`
- [ ] **Task 10.3.5: Add Heuristic C if needed** (conditional on whether A+B cover the 14 sites)
- WHERE: `tests/test_audit_exception_handling_heuristics.py` + `scripts/audit_exception_handling.py`
- WHAT: Detect the pattern; return `INTERNAL_COMPLIANT`
- HOW: Check the function's annotated return type is `Result[T]` and the except body returns a non-Result value (the fallback)
- COMMIT: `feat(scripts): heuristic C — Result-typed return with non-Result fallback` (conditional)
- [ ] **Task 10.3.6: Verify the new heuristics reclassify the 14 UNCLEAR sites**
- WHERE: `scripts/audit_exception_handling.py`
- WHAT: Re-run the audit; assert the 14 sites are now `INTERNAL_COMPLIANT` or `BOUNDARY_*`
- HOW: parse the JSON; filter by the 14 file:line pairs
- COMMIT: rolled into 10.3.2 / 10.3.4 / 10.3.5 (whichever fires)
### 10.4 — Update the per-site report
- [ ] **Task 10.4.1: Extend the per-site report with the Phase 10 changes**
- WHERE: `docs/reports/RESULT_MIGRATION_SMALL_FILES_20260617.md`
- WHAT: Add a "Phase 10" section with:
- The full per-site table for the 27 SILENT_SWALLOW + 14 new UNCLEAR sites
- The new audit heuristics (per-site count delta)
- The Result-based API for each migrated function (what `.data` and `.errors` look like)
- The call-graph impact: which callers were updated; the threading model for warmup callbacks and hot-reloader (the Result now flows through the io_pool completion handler)
- HOW: append to the existing report; preserve the existing Phase 1-9 content
- COMMIT: `docs(report): add Phase 10 results to the per-site report`
- GIT NOTE: 27 SILENT_SWALLOW → 0; 14 new UNCLEAR → 0 (via the 2-3 new heuristics)
### 10.5 — Verification
- [ ] **Task 10.5.1: Run the audit post-Phase-10**
- WHERE: `scripts/audit_exception_handling.py`
- WHAT: `uv run python scripts/audit_exception_handling.py --json > audit_post_phase10.json`; verify:
- 0 `INTERNAL_SILENT_SWALLOW` sites in the 37-file scope
- 0 migration-target sites in the 37-file scope (G4 now met)
- 0 new `UNCLEAR` sites (the 14 are reclassified)
- HOW: parse the JSON; assert the 37 files have 0 V+S sites
- COMMIT: `docs(track): verify Phase 10 result migration complete (0 SILENT_SWALLOW; 0 UNCLEAR; 0 migration-target in 37-file scope)`
- [ ] **Task 10.5.2: Run the full test suite**
- WHERE: `tests/`
- WHAT: `uv run python scripts/run_tests_batched.py`; verify all 11 tiers PASS
- HOW: the batched runner
- COMMIT: rolled into 10.5.1
- [ ] **Task 10.5.3: Update the track completion report**
- WHERE: `docs/reports/TRACK_COMPLETION_result_migration_small_files_20260617.md`
- WHAT: Add a "Phase 10 Addendum" section with the per-site count delta, the new heuristics, the threading-model impact (Result flows through io_pool for the 4 callback sites), and the test pass count
- HOW: append to the existing report
- COMMIT: `docs(reports): TRACK_COMPLETION_result_migration_small_files_20260617 addendum (Phase 10)`
- GIT NOTE: G4 deviation now resolved; the 37-file scope has 0 migration-target sites
### 10.6 — Mark Phase 10 completed
- [ ] **Task 10.6.1: Update state.toml and metadata.json**
- WHERE: `conductor/tracks/result_migration_small_files_20260617/state.toml` + `metadata.json`, `conductor/tracks.md`
- WHAT: Mark all Phase 10 tasks completed with commit SHAs; update `status: active → completed`; `current_phase: 10 → "complete"`; update `outcomes` in metadata.json
- HOW: edit the files
- COMMIT: `conductor(track): mark result_migration_small_files_20260617 Phase 10 completed (G4 deviation resolved)`
- GIT NOTE: 27 SILENT_SWALLOW sites migrated to Result[T]; 14 new UNCLEAR sites reclassified via 2-3 new audit heuristics; G4 now met
- [ ] **Task 10.6.2: Update the umbrella spec to remove the follow-up note**
- WHERE: `conductor/tracks/result_migration_20260616/spec.md`
- WHAT: Change the "follow-up sub-track planned" line in the post-sub-track-2 callout to "Phase 10 of sub-track 2 complete; G4 deviation resolved"
- HOW: edit the spec
- COMMIT: `docs(track): update umbrella with sub-track 2 Phase 10 complete`
- GIT NOTE: 1-sentence note
---
## Risks at the Plan Level
| Risk | Mitigation |
@@ -329,6 +479,9 @@ The 35 SMALL files are batched 5-7 per commit (per the umbrella spec). The 2 MED
| New migration-target sites surface after the `visit_Try` fix | Task 1.4.1 verifies the count delta; the per-batch scope adjusts |
| The audit-script fix commit is too large (>500 lines) | Each bug gets its own commit (1.1.2, 1.2.2, 1.3.2 are separate) |
| The MEDIUM files (session_logger, warmup) have complex migrations that don't fit the Result pattern | Per the styleguide, some sites are legitimately `BOUNDARY_*`; those stay as-is. The decision is documented in the report |
| **Phase 10 R1:** A site that looks like a SILENT_SWALLOW fallback is actually a conditional capture that needs to inspect the exception to decide what to do | The full Result migration preserves the exception in `result.errors[0].exception`; the caller can inspect it. If the caller needs to branch on the exception, that's a follow-up for the caller (not this phase) |
| **Phase 10 R2:** Migrating `Result[T]` through `io_pool` callbacks (warmup) requires the io_pool's API to accept `Result[T]` returns | The io_pool already uses callback-based dispatch; the Result is delivered to the completion handler as a parameter. No io_pool change needed; the caller is updated to check `result.ok` |
| **Phase 10 R3:** The 2-3 new audit heuristics misclassify sites that should be `INTERNAL_BROAD_CATCH` or `INTERNAL_SILENT_SWALLOW` | TDD: each heuristic has a failing test first; the test suite covers the canonical patterns. If a heuristic is too broad, narrow the conditions and re-test |
---
@@ -339,8 +492,9 @@ After Phase 9, capture in `docs/reports/RESULT_MIGRATION_SMALL_FILES_20260617.md
- Audit pre-Phase-1: 76 sites (62V + 10S + 4?); 3 audit-script bugs documented
- Audit post-Phase-1: 0 audit-script bugs (the 3 bugs are fixed)
- Audit post-Phase-2: 4 UNCLEAR sites classified (decision count by category)
- Audit post-Phase-9: 0 migration-target sites in the 37-file scope
- Per-file migration summary (76 sites → 0; per-file counts)
- Audit post-Phase-9: 49/76 sites migrated; 27 SILENT_SWALLOW remain; 14 new UNCLEAR sites
- Audit post-Phase-10: 76/76 sites migrated (49 from Phase 3-8 + 27 from Phase 10); 0 SILENT_SWALLOW; 0 UNCLEAR (the 14 reclassified via 2-3 new heuristics)
- Per-file migration summary (76 sites → 0; per-file counts; per-site function signatures + ErrorInfo fields)
- Per-site decisions for the 4 UNCLEAR sites
- Audit-script bug-fix summary (3 bugs; per-bug description + fix)
- Test pass count: all 11 tiers PASS; new tests added (6-9 for the audit-script fixes + N for the migrations)
- Audit-script bug-fix summary (3 from Phase 1 + 2-3 from Phase 10; per-bug description + fix)
- Test pass count: all 11 tiers PASS; new tests added (4 for Phase 1 + N for Phase 10 heuristics + M for Phase 10 migrations)
@@ -4,8 +4,8 @@
[meta]
track_id = "result_migration_small_files_20260617"
name = "Result Migration Sub-Track 2 (Small Files + Audit-Script Bug Fixes)"
status = "completed"
current_phase = "complete"
status = "active"
current_phase = 10
last_updated = "2026-06-17"
[parent]
@@ -31,6 +31,7 @@ phase_6 = { status = "completed", checkpointsha = "f4a445bd", name = "Migrate Ph
phase_7 = { status = "completed", checkpointsha = "a5b40bcf", name = "Migrate Phase 7 Batch: Infrastructure + Hook + Utility (8 files)" }
phase_8 = { status = "completed", checkpointsha = "c329c869", name = "Migrate MEDIUM files (session_logger, warmup)" }
phase_9 = { status = "completed", checkpointsha = "34387b9f", name = "Verification (audit re-run + test pass count + report + completion)" }
phase_10 = { status = "in_progress", checkpointsha = "", name = "Complete the Result[T] migration (27 SILENT_SWALLOW + 14 new UNCLEAR sites)" }
[tasks]
# Phase 1: Audit-Script Bug Fixes
@@ -110,6 +111,29 @@ t9_4 = { status = "pending", commit_sha = "", description = "Update umbrella spe
t9_5 = { status = "pending", commit_sha = "", description = "Mark the track as completed (metadata + state + tracks.md)" }
t9_6 = { status = "pending", commit_sha = "", description = "Write docs/reports/TRACK_COMPLETION_result_migration_small_files_20260617.md" }
# Phase 10: Complete the Result[T] migration
t10_1_1 = { status = "pending", commit_sha = "", description = "Enumerate the 27 SILENT_SWALLOW + 14 new UNCLEAR sites from the audit JSON" }
t10_2_1 = { status = "pending", commit_sha = "", description = "Migrate src/startup_profiler.py:40 to Result[T] (remove stderr.write; capture exception in ErrorInfo)" }
t10_2_2 = { status = "pending", commit_sha = "", description = "Migrate src/file_cache.py:98 to Result[T] (mtime cache fallback; return Result with default + errors)" }
t10_2_3 = { status = "pending", commit_sha = "", description = "Migrate src/outline_tool.py:90 to Result[T] (ast.unparse fallback; return Result with empty outline + errors)" }
t10_2_4 = { status = "pending", commit_sha = "", description = "Migrate src/warmup.py:139 (on_complete callback) to Result[T]; update io_pool completion handler to check result.ok" }
t10_2_5 = { status = "pending", commit_sha = "", description = "Migrate src/warmup.py:215 (_record_success callback) to Result[T]" }
t10_2_6 = { status = "pending", commit_sha = "", description = "Migrate src/warmup.py:249 (_record_failure callback) to Result[T]" }
t10_2_7 = { status = "pending", commit_sha = "", description = "Migrate src/hot_reloader.py:58 (module reload) to Result[T]; update reload completion handler to check result.ok" }
# The remaining 20 SILENT_SWALLOW sites are enumerated in Task 10.1.1 and added as t10_2_8 through t10_2_27
t10_3_1 = { status = "pending", commit_sha = "", description = "Write failing test for audit Heuristic A (Result-returning recovery in non-*_result function)" }
t10_3_2 = { status = "pending", commit_sha = "", description = "Implement audit Heuristic A in _classify_except" }
t10_3_3 = { status = "pending", commit_sha = "", description = "Write failing test for audit Heuristic B (Result-typed fallback pattern)" }
t10_3_4 = { status = "pending", commit_sha = "", description = "Implement audit Heuristic B in _classify_except" }
t10_3_5 = { status = "pending", commit_sha = "", description = "Add audit Heuristic C if needed (Result-typed return with non-Result fallback)" }
t10_3_6 = { status = "pending", commit_sha = "", description = "Verify the new heuristics reclassify the 14 new UNCLEAR sites" }
t10_4_1 = { status = "pending", commit_sha = "", description = "Extend the per-site report with Phase 10 changes (per-site table + heuristics + threading-model impact)" }
t10_5_1 = { status = "pending", commit_sha = "", description = "Run audit post-Phase-10; verify 0 SILENT_SWALLOW + 0 UNCLEAR + 0 migration-target in 37-file scope" }
t10_5_2 = { status = "pending", commit_sha = "", description = "Run full test suite; verify all 11 tiers PASS" }
t10_5_3 = { status = "pending", commit_sha = "", description = "Update track completion report with Phase 10 addendum" }
t10_6_1 = { status = "pending", commit_sha = "", description = "Mark Phase 10 completed (state + metadata + tracks.md)" }
t10_6_2 = { status = "pending", commit_sha = "", description = "Update umbrella spec to remove the follow-up note (Phase 10 complete; G4 resolved)" }
[verification]
phase_1_audit_fixes_complete = true
phase_2_unclear_classification_complete = true
@@ -120,22 +144,33 @@ phase_6_provider_batch_complete = true
phase_7_infra_batch_complete = true
phase_8_medium_files_complete = true
phase_9_verification_complete = true
phase_10_result_migration_complete = false
report_exists = true
umbrella_spec_updated = true
audit_post_migration_zero_migration_target = false
test_pass_count_unchanged = true
metadata_json_status_completed = true
metadata_json_status_completed = false # back to false; will be true after Phase 10
silent_swallow_sites_migrated_to_result = 0
new_unclear_sites_reclassified = 0
new_audit_heuristics_added_phase_10 = 0
io_pool_callback_sites_threaded_result = 0
test_pass_count_unchanged = true
[scope_metrics]
files_target = 37
files_migrated = 24
files_audit_decision_only = 13
sites_target = 76
sites_migrated = 49
sites_migrated_phase_3_to_8 = 49
sites_migrated_phase_10 = 0
sites_compliant_no_migration = 13
sites_remaining_silent_swallow_pre_phase_10 = 27
unclear_sites_target = 4
unclear_sites_compliant = 2
unclear_sites_migration_target = 2
audit_bugs_fixed = 3
audit_heuristics_added = 0
new_unclear_sites_from_narrowing = 14
audit_bugs_fixed_phase_1 = 3
audit_heuristics_added_phase_1 = 0
audit_heuristics_added_phase_10 = 0
new_tests_added = 4
io_pool_callback_sites = 4 # warmup.py:139, 215, 249 + hot_reloader.py:58