Private
Public Access
0
0

conductor(plan): initialize result_migration_baseline_cleanup_20260620 (sub-track 5)

Sub-track 5 of the 5-sub-track result_migration_20260616 umbrella.
Migrates the 3 baseline files (the convention reference) to be 100%
compliant with the data-oriented Result[T] convention. Completes the
campaign.

Scope: 88 migration-target sites across 3 source files (mcp_client.py
46 + ai_client.py 33 + rag_engine.py 9; total 231KB / 5917 lines).
41 sites stay as-is: 4 BOUNDARY_SDK (vendor SDK boundaries in ai_client),
9 INTERNAL_PROGRAMMER_RAISE (5 rag_engine + 4 ai_client, per sub-track 4
Phase 11 dunder-method heuristic), 28 INTERNAL_COMPLIANT.

Per the user directive (2026-06-20), this track uses the same anti-sliming
template as sub-track 4 (which was 'the first to ship without error
correction'). 14 phases cap each phase at <=9 migration sites with
explicit per-phase audit gates. The sliming-prone phases (Phase 8
mcp_client silent-swallow, Phase 11 ai_client silent-swallow, Phase 12
ai_client rethrow) explicitly forbid narrowing+logging and classify-
as-suspicious laundering.

The 14 phases:
  0. Setup + styleguide re-read (Tier 2 reads error_handling.md)
  1. 3-file inventory + classification (88 sites in 3 inventory docs)
  2. Audit gate baseline (3 baseline invariant tests)
  3-7. mcp_client Batches A-E (40 broad-catches, 5 batches of <=8 each)
  8. mcp_client silent-swallow + UNCLEAR (5 + 1 = 6 sites; anti-sliming)
  9-10. ai_client Batches A-B (17 broad-catches, 2 batches)
  11. ai_client silent-swallow (9 sites; anti-sliming)
  12. ai_client rethrow classification (7 sites; Pattern 1/2/3 or migrate)
  13. rag_engine migration (1 SS + 5 BC + 3 RETHROW = 9 sites)
  14. Audit gate + end-of-track report (campaign 100% complete)

Anti-sliming protocol per phase (same as sub-track 4):
  - Styleguide re-read at start of each phase (commit msg acknowledgment)
  - Per-site audit pre-check (capture before migration)
  - Red -> Green (1 commit per site)
  - Per-site audit post-check (capture after migration)
  - Phase invariant test (1 commit per phase)
  - 'If a site resists migration: DO NOT invent a heuristic. Report.'

The 3 baseline files are the convention reference; after this track,
the data-oriented Result[T] convention is fully applied to all 65
src/ files.

Files:
  - spec.md (263 lines, 11 sections; 22 VCs; 6 risks)
  - plan.md (562 lines, 14 phases, 121 tasks, 110+ atomic commits,
    anti-sliming protocol identical to sub-track 4)
  - metadata.json (22 VCs, 6 risks, scope)
  - state.toml (15 phases, 121 tasks, 29 verification entries)
  - tracks.md (new row 6d-5 in Active Tracks table)

Total: 5 files, ~2400 lines added (excluding tracks.md).
Next: Tier 2 picks up Phase 0 (setup + styleguide re-read) per the
task list in state.toml. Campaign 100% ready once this track ships.
This commit is contained in:
2026-06-20 07:48:15 -04:00
parent 9224be7ac3
commit e90167494e
5 changed files with 1462 additions and 0 deletions
+1
View File
@@ -29,6 +29,7 @@ Tracks that are unblocked and ready to start. Ordered by **dependency** (blocked
| 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 ✓, **shipped 2026-06-20**; migrated 42 sites in `src/gui_2.py` (25 INTERNAL_BROAD_CATCH + 13 INTERNAL_SILENT_SWALLOW + 2 INTERNAL_RETHROW + 2 UNCLEAR) to `Result[T]`; added 3 new drain-plane render functions + 1 new test file + 2 new audit heuristics (Phase 11 dunder raise + Phase 12 lazy-loading fallback). **Audit: V=0, S=0, ?=0 for gui_2.py.** 81 atomic commits across 13 phases; 114 tests pass; Tier 1+2 batched: 10/10 PASS; Tier 3: 1 known issue (FPS 28.46 vs 30 threshold; documented in TRACK_COMPLETION). **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 114 tests; 1 modified test file (tests/test_audit_heuristics.py) with 8 regression tests; 4 metadata/plan/state/spec files; 1 end-of-track report; 81 atomic commits. **Extra-long phase structure per user directive (2026-06-19) to prevent Tier 2 sliming.**) |
| 6d-5 | A | [Result Migration Sub-Track 5: Baseline Cleanup](#track-result-migration-baseline-cleanup-20260620) | spec ✓, plan ✓, metadata ✓, state ✓, **ready to start**; migrates 88 sites across 3 baseline files (`src/mcp_client.py` 46 + `src/ai_client.py` 33 + `src/rag_engine.py` 9) to make the convention reference 100% compliant. **Same anti-sliming protocol as sub-track 4: 14 phases cap each phase at <=9 sites with per-phase styleguide re-read + per-site audit pre/post check + per-phase invariant test.** | `result_migration_gui_2_20260619` (sub-track 4, SHIPPED 2026-06-20; first to ship without error correction per user) | (**NEW 2026-06-20**; sub-track 5 of 5; scope: 3 source files (mcp_client.py + ai_client.py + rag_engine.py = 231KB / 5917 lines) modified across 14 phases; 88 migration sites organized into 12 migration phases + 3 setup phases; 1 new test file (tests/test_baseline_result.py) with 102+ tests; 3 inventory docs (1 per file); 4 metadata/plan/state/spec files; 1 end-of-track report; 110+ atomic commits. **Same anti-sliming template as sub-track 4 per user directive (2026-06-20); completes the 5-sub-track campaign — 100% Result[T] convention coverage across all 65 src/ files.**) |
| 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) |
| 6f | A (meta-tooling) | [Tier 2 Sandbox File Leak Prevention (revert + 3-layer defense)](#track-tier-2-sandbox-file-leak-prevention-new-2026-06-20) | spec ✓, plan ✓, metadata ✓, state ✓, **shipped 2026-06-20**; selectively reverted the 4 user-named files from offender commit `00e5a3f2` (`.opencode/agents/tier2-autonomous.md`, `.opencode/commands/tier-2-auto-execute.md`, `opencode.json`, `mcp_paths.toml`); added 3-layer defense: pre-commit hook at `conductor/tier2/githooks/pre-commit` (auto-unstages forbidden files at commit boundary; 12 tests), `scripts/audit_tier2_leaks.py` (working-tree audit with `--strict` CI gate; 13 tests), wired hook installation into `scripts/tier2/setup_tier2_clone.ps1`. 25 default-on + 4 opt-in tests pass; 4 atomic commits (`fab2e55b` + `81e1fd7b` + `f5d8ea04` + `8f54deda`); user-driven response to a one-off incident (per user directive: tier-2 must NEVER commit those files again; **NOT via gitignore**). **DEFERRED**: CI wiring of audit `--strict` mode; rebase of stale tier-2 branches (`tier2/result_migration_app_controller_phase6_20260619`, `tier2/test_sandbox_hardening_20260619`) on `origin/master@8f54deda` to drop `00e5a3f2` (user action). | (none — independent; **NEW 2026-06-20**; meta-tooling fix; selective revert of 4 of 9 changes in offender commit `00e5a3f2`) |
| 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) |
@@ -0,0 +1,102 @@
{
"id": "result_migration_baseline_cleanup_20260620",
"name": "Result Migration - Sub-Track 5 (Baseline Cleanup)",
"date": "2026-06-20",
"type": "refactor",
"priority": "A",
"spec": "conductor/tracks/result_migration_baseline_cleanup_20260620/spec.md",
"plan": "conductor/tracks/result_migration_baseline_cleanup_20260620/plan.md",
"status": "active",
"umbrella": "result_migration_20260616",
"sub_track_index": 5,
"blocked_by": {
"result_migration_gui_2_20260619": "shipped 2026-06-20 (sub-track 4; first sub-track to ship without error correction per user)"
},
"blocks": {},
"scope": {
"new_files": [
"tests/test_baseline_result.py",
"docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md",
"tests/artifacts/PHASE1_AUDIT_BASELINE.json",
"tests/artifacts/PHASE1_SITE_INVENTORY_mcp_client.md",
"tests/artifacts/PHASE1_SITE_INVENTORY_ai_client.md",
"tests/artifacts/PHASE1_SITE_INVENTORY_rag_engine.md"
],
"modified_files": [
"src/mcp_client.py",
"src/ai_client.py",
"src/rag_engine.py",
"conductor/tracks.md",
"conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml",
"conductor/tracks/result_migration_baseline_cleanup_20260620/metadata.json",
"conductor/tracks/result_migration_baseline_cleanup_20260620/plan.md",
"conductor/tracks/result_migration_baseline_cleanup_20260620/spec.md",
"conductor/tracks/result_migration_20260616/spec.md",
"docs/reports/RESULT_MIGRATION_CAMPAIGN_STATUS_20260619.md"
],
"deleted_files": []
},
"verification_criteria": [
"src/mcp_client.py has zero INTERNAL_BROAD_CATCH sites (40 migrated across Phases 3-7)",
"src/mcp_client.py has zero INTERNAL_SILENT_SWALLOW sites (5 migrated in Phase 8; per error_handling.md:530 logging is NOT a drain)",
"src/mcp_client.py has zero UNCLEAR sites (1 classified or migrated in Phase 8)",
"src/ai_client.py has zero INTERNAL_BROAD_CATCH sites (17 migrated across Phases 9-10)",
"src/ai_client.py has zero INTERNAL_SILENT_SWALLOW sites (9 migrated in Phase 11)",
"src/ai_client.py has zero INTERNAL_RETHROW sites (7 classified per Pattern 1/2/3 in Phase 12 or migrated)",
"src/rag_engine.py has zero INTERNAL_BROAD_CATCH sites (5 migrated in Phase 13)",
"src/rag_engine.py has zero INTERNAL_SILENT_SWALLOW sites (1 migrated in Phase 13)",
"src/rag_engine.py has zero INTERNAL_RETHROW sites (3 classified per Pattern 1/2/3 in Phase 13 or migrated)",
"src/ai_client.py preserves 4 BOUNDARY_SDK sites (vendor SDK boundaries; legitimate)",
"src/ai_client.py preserves 4 INTERNAL_PROGRAMMER_RAISE sites (per sub-track 4 Phase 11 dunder-method heuristic)",
"src/rag_engine.py preserves 5 INTERNAL_PROGRAMMER_RAISE sites (per sub-track 4 Phase 11 dunder-method heuristic)",
"tests/test_baseline_result.py has 102+ tests (88 site + 14 invariant), all pass",
"uv run python scripts/audit_exception_handling.py --include-baseline --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 (14 styleguide-ack commits)",
"Git history shows 110+ atomic commits (88 site migrations + 14 phase setup + 5 infra + 2 docs)",
"docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md covers all 14 phases",
"conductor/tracks.md row updated to 'shipped 2026-06-XX'",
"umbrella spec count updated; campaign 100% complete (all 5 sub-tracks shipped)",
"RESULT_MIGRATION_CAMPAIGN_STATUS_20260619.md updated to mark sub-track 5 shipped"
],
"regressions_and_pre_existing_failures": [],
"pre_existing_failures_remaining": [],
"deferred_to_followup_tracks": [],
"estimated_effort": {
"method": "scope (per workflow.md Tier 1 Track Initialization Rules). NO day estimates.",
"scope": "3 source files (mcp_client.py + ai_client.py + rag_engine.py) modified across 14 phases; 88 migration sites (62 BC + 15 SS + 10 RETHROW + 1 UNCLEAR) organized into 12 migration phases (3-13) + 1 setup phase (0) + 1 inventory phase (1) + 1 audit-gate phase (2) + 1 verification phase (14); 1 new test file (tests/test_baseline_result.py) with 102+ tests; 5 metadata/plan/state/spec files + 3 inventory docs; 1 end-of-track report. 110+ atomic commits."
},
"risk_register": [
{
"risk": "ai_client.py's multi-provider _send_<vendor>_result helpers are partially in place; the 33 remaining sites include some already-_result and some still-broad-catch",
"likelihood": "low",
"mitigation": "Phase 1 inventory forces explicit per-site classification"
},
{
"risk": "mcp_client.py's 45 tool functions: each tool is a small surface; per-tool _result helper follows the established convention",
"likelihood": "low",
"mitigation": "Per-phase audit gate; if a batch fails, the phase stops"
},
{
"risk": "rag_engine.py's 9 sites include 3 INTERNAL_RETHROW that may need Pattern 1/2/3 classification",
"likelihood": "medium",
"mitigation": "Phase 13 includes classification step"
},
{
"risk": "Per-site Result[T] migration in 3 large files could regress the existing 41 compliant sites",
"likelihood": "low",
"mitigation": "Per-phase audit gate; if compliant count drops, the phase fails"
},
{
"risk": "The 9 INTERNAL_PROGRAMMER_RAISE + 4 BOUNDARY_SDK sites may be incorrectly classified (code may have changed since the heuristic was added)",
"likelihood": "low",
"mitigation": "Phase 1 inventory forces explicit per-site classification; misclassifications reported to user"
},
{
"risk": "Tier 2 invents a laundering heuristic (the sliming pattern from sub-tracks 2/3)",
"likelihood": "medium",
"mitigation": "Anti-sliming protocol enforced per phase; 'If a site resists migration: DO NOT invent a heuristic. Report.'"
}
]
}
@@ -0,0 +1,798 @@
# Result Migration — Sub-Track 5 (Baseline Cleanup) Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `mma-tier3-worker` (recommended) or `mma-tier2-tech-lead` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Migrate all 88 migration-target sites across the 3 baseline files (`mcp_client.py`, `ai_client.py`, `rag_engine.py`) to the data-oriented `Result[T]` convention, making the baseline 100% convention-compliant.
**Architecture:** Per-site `_result` helper convention (matches sub-track 3 Phase 2 and sub-track 4 patterns). The 3 baseline files are backend services; the drain is the caller (MMA worker, mcp_client tool invocation, API hook). No new render functions needed. The existing `Result[T]` return type is the data plane.
**Tech Stack:** Python 3.11+, pytest, pydantic. Existing infrastructure: `Result[T]` from `src/result_types.py:91-105`, audit script at `scripts/audit_exception_handling.py` (with 5 regression-guard tests at `tests/test_audit_heuristics.py`).
---
## Anti-Sliming Protocol (MANDATORY for every phase)
This is the same template as sub-track 4 (which was "the first to not need error correction" per the user). Every phase:
1. **Pre-phase styleguide re-read** (commit 1 of the phase): Read `conductor/code_styleguides/error_handling.md` end-to-end. Commit message MUST include "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase N."
2. **Audit pre-check** (per site, before migration): Capture the site's category BEFORE migration. Capture in commit body.
3. **Red** (1 commit per site): Write the unit test in `tests/test_baseline_result.py`. Run test — MUST FAIL. Commit.
4. **Green** (1 commit per site): Migrate the site. Use the `_result` helper convention. Run test — MUST PASS. Commit.
5. **Audit post-check** (per site, after migration): Same command. Confirm the site moved out of the violation category. Capture in commit body.
6. **Phase invariant test** (1 commit at end of phase): `test_phase_N_<file>_<phase>_invariant` verifies the per-phase count drop.
7. **If a site "resists migration":** DO NOT invent a heuristic. Report to the user (Tier 1). The user decides whether to fix forward or defer.
8. **Per-file atomic commits:** 1 site = 1 commit (per `workflow.md` "ATOMIC PER-TASK COMMITS").
---
## File Structure
**Files modified (3):**
- `src/mcp_client.py` — 46 migration sites (40 broad-catch + 5 silent-swallow + 1 UNCLEAR)
- `src/ai_client.py` — 33 migration sites (17 broad-catch + 9 silent-swallow + 7 rethrow)
- `src/rag_engine.py` — 9 migration sites (5 broad-catch + 1 silent-swallow + 3 rethrow)
- `conductor/tracks.md` — new track row (Phase 0)
- `conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml` — task statuses
**Files created (5):**
- `tests/test_baseline_result.py` — 88 site tests + 14 invariant tests = ≥102 tests
- `docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md` — end-of-track report (Phase 14)
- `tests/artifacts/PHASE1_AUDIT_BASELINE.json` — baseline audit JSON
- `tests/artifacts/PHASE1_SITE_INVENTORY_mcp_client.md` — 46-row inventory
- `tests/artifacts/PHASE1_SITE_INVENTORY_ai_client.md` — 33-row inventory
- `tests/artifacts/PHASE1_SITE_INVENTORY_rag_engine.md` — 9-row inventory
**Files NOT modified:**
- `scripts/audit_exception_handling.py` — the audit heuristic is correct (sub-track 3 Phase 7 + sub-track 4 Phase 11/12); do not change
- `tests/test_audit_heuristics.py` — the 8 regression-guard tests are correct; do not change
- `src/result_types.py` — the `Result[T]` dataclass is the convention reference; do not change
- `src/app_controller.py` — the data plane is correct from sub-track 3 Phase 6; this track only consumes the convention
---
## Migration Pattern (used by Phases 3-13)
Every migration follows this pattern. The `_result` helper convention (matches mcp_client + ai_client + rag_engine existing style):
```python
# BEFORE (in src/mcp_client.py, src/ai_client.py, or src/rag_engine.py)
def _do_x(...):
try:
result = do_something()
return result
except Exception as e:
sys.stderr.write(f"Error: {e}\n") # SLIMING: logging-only, NOT a drain
return None # or return default
# AFTER
def _do_x_result(...) -> Result[T]:
"""Drain-aware variant of _do_x. Returns Result[T] so caller can check .ok."""
try:
result = do_something()
return Result(data=result)
except Exception as e:
return Result(data=<zero-value>, errors=[ErrorInfo(
kind=ErrorKind.INTERNAL, message=str(e),
source="<file>._do_x_result", original=e,
)])
def _do_x(...):
"""Legacy wrapper. Checks .ok; caller decides how to handle the error."""
result = _do_x_result(...)
if not result.ok:
# Caller-specific error handling:
# - mcp_client tools: return the error in the tool's result
# - ai_client providers: return Result(data=fallback) or propagate
# - rag_engine: append to controller's _last_request_errors or similar
return <caller-specific-fallback>
return result.data
```
The unit test pattern:
```python
def test_<site>_returns_result_on_success():
"""Migrated helper returns Result.ok=True on success."""
from src.<file> import _<site>_result
# Build mock inputs that make the inner call succeed
result = _<site>_result(<args>)
assert result.ok
assert result.data == <expected>
assert result.errors == []
def test_<site>_returns_result_with_error_on_failure():
"""Migrated helper returns Result.ok=False with ErrorInfo on failure."""
from src.<file> import _<site>_result
# Build mock inputs that make the inner call fail
result = _<site>_result(<args>)
assert not result.ok
assert result.errors
assert result.errors[0].kind == ErrorKind.INTERNAL
assert result.errors[0].source == "<file>._<site>_result"
def test_<site>_legacy_wrapper_handles_error():
"""Legacy wrapper handles Result.ok=False correctly."""
from src.<file> import _<site>
result = _<site>(<args>)
# Assert the wrapper returns the expected fallback (or propagates the error)
assert result == <expected_fallback_or_None>
```
---
## Phase 0: Setup + Styleguide Re-Read (3 tasks)
**Focus:** Initialize the track, update tracks.md, Tier 2 reads the styleguide end-to-end, acknowledge in commit message.
### Task 0.1: Update `conductor/tracks.md`
**Files:**
- Modify: `conductor/tracks.md` (add new row after sub-track 4 row 6d-4)
- [ ] **Step 1: Find the sub-track 4 row**
```bash
grep -n "result_migration_gui_2_20260619" conductor/tracks.md | head -3
```
- [ ] **Step 2: Add the new row after sub-track 4**
Insert in the "Active Tracks (Current Queue)" table (between row 6d-4 and row 6e):
```
| 6d-5 | A | [Result Migration Sub-Track 5: Baseline Cleanup](#track-result-migration-baseline-cleanup-20260620) | spec ✓, plan pending, **ready to start** | `result_migration_gui_2_20260619` (sub-track 4, SHIPPED 2026-06-20) |
```
- [ ] **Step 3: Commit**
```bash
git add conductor/tracks.md
git commit -m "conductor(tracks): add result_migration_baseline_cleanup_20260620 row"
```
### Task 0.2: Tier 2 reads the styleguide end-to-end
**Files:** (no file changes; verification is the commit message)
- [ ] **Step 1: Read `conductor/code_styleguides/error_handling.md` end-to-end** (989 lines)
All sections: 5 Patterns + Data Model + Decision Tree + Anti-Patterns + Examples + Hard Rules + When to Use + Boundary Types + **Drain Points (lines 356-516)** + Broad-Except Distinction (lines 520-540) + Constructors Can Raise + **Re-Raise Patterns (lines 625-690)** + Audit Script + Migration Playbook + AI Agent Checklist (lines 809-940).
- [ ] **Step 2: Acknowledge the read in an empty commit**
```bash
git commit --allow-empty -m "chore: TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 0"
```
### Task 0.3: Phase 0 checkpoint
- [ ] **Step 1: Create empty commit marking Phase 0 complete**
```bash
git commit --allow-empty -m "conductor(plan): mark Phase 0 complete (setup + styleguide re-read)"
```
- [ ] **Step 2: Update state.toml Phase 0 status** (created in metadata task at end of track init; for now just leave as pending)
- [ ] **Step 3: Commit the state.toml + tracks.md changes together at end of track initialization**
---
## Phase 1: 3-File Inventory + Classification (4 tasks)
**Focus:** Run the audit on all 3 baseline files; walk every finding; classify each of the 88 migration-target sites into 3 inventory docs.
### Task 1.1: Run the audit + capture JSON
- [ ] **Step 1: Run the audit and save JSON**
```bash
uv run python scripts/audit_exception_handling.py --include-baseline --json > tests/artifacts/PHASE1_AUDIT_BASELINE.json
```
- [ ] **Step 2: Verify the JSON was generated and the counts match the spec**
```bash
uv run python -c "
import json
data = json.load(open('tests/artifacts/PHASE1_AUDIT_BASELINE.json'))
for f in data['files']:
if 'mcp_client' in f.get('filename', ''):
print(f'mcp_client.py: V={f[\"violation_count\"]} S={f[\"suspicious_count\"]} ?={f[\"unclear_count\"]}')
elif 'ai_client' in f.get('filename', ''):
print(f'ai_client.py: V={f[\"violation_count\"]} S={f[\"suspicious_count\"]} ?={f[\"unclear_count\"]}')
elif 'rag_engine' in f.get('filename', ''):
print(f'rag_engine.py: V={f[\"violation_count\"]} S={f[\"suspicious_count\"]} ?={f[\"unclear_count\"]}')
"
```
Expected: `mcp_client.py: V=45 S=0 ?=1` / `ai_client.py: V=26 S=7 ?=0` / `rag_engine.py: V=6 S=3 ?=0`
### Task 1.2: Walk the audit + write the 3 inventory docs
**Files:**
- Create: `tests/artifacts/PHASE1_SITE_INVENTORY_mcp_client.md`
- Create: `tests/artifacts/PHASE1_SITE_INVENTORY_ai_client.md`
- Create: `tests/artifacts/PHASE1_SITE_INVENTORY_rag_engine.md`
- [ ] **Step 1: Extract migration-target sites per file**
```bash
uv run python -c "
import json
data = json.load(open('tests/artifacts/PHASE1_AUDIT_BASELINE.json'))
for fname in ['mcp_client', 'ai_client', 'rag_engine']:
f = next((x for x in data['files'] if fname in x.get('filename', '')), None)
if not f: continue
findings = f['findings']
migration = [x for x in findings if x.get('category') in ('INTERNAL_BROAD_CATCH', 'INTERNAL_SILENT_SWALLOW', 'INTERNAL_RETHROW', 'UNCLEAR')]
print(f'=== {fname}.py: {len(migration)} migration targets ===')
for m in migration:
print(f\"L{m['line']}: [{m['category']}]\")
" > tests/artifacts/PHASE1_MIGRATION_TARGETS.txt
```
- [ ] **Step 2: Verify the counts are 46 + 33 + 9 = 88**
```bash
grep "migration targets" tests/artifacts/PHASE1_MIGRATION_TARGETS.txt
```
Expected: 3 lines with counts 46, 33, 9.
- [ ] **Step 3: For each file, write the inventory entry**
For each migration-target site, read the code around the line and write to the per-file inventory doc. Use the format:
```markdown
# Phase 1 Site Inventory — mcp_client.py
# (or ai_client.py / rag_engine.py)
| Line | Category | Current code (5 lines around) | Target migration | Drain point |
|---|---|---|---|---|
| L<line> | <category> | <code excerpt> | <pattern> | <caller> |
| ... |
```
For "Target migration", reference the per-phase pattern (e.g., "Batch A tool broad-catch" for Phase 3-7 sites, "silent-swallow → Result[T]" for Phase 8/11 sites, "Pattern 1/2/3 classification or migrate" for Phase 12 sites).
For "Drain point" (backend services), specify the caller:
- `MMA worker` (multi-agent conductor)
- `mcp_client tool caller` (MCP tool invocation)
- `AI client SDK boundary` (the vendor SDK's caller)
- `RAG engine caller` (the controller's RAG state)
- [ ] **Step 4: Commit the inventory**
```bash
git add tests/artifacts/PHASE1_AUDIT_BASELINE.json tests/artifacts/PHASE1_MIGRATION_TARGETS.txt tests/artifacts/PHASE1_SITE_INVENTORY_*.md
git commit -m "conductor(plan): Phase 1 site inventory — 88 migration-target sites classified across 3 baseline files"
```
### Task 1.3: Phase 1 invariant test + checkpoint
**Files:**
- Create: `tests/test_baseline_result.py` (initial creation; will be extended each phase)
- Modify: `conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml`
- [ ] **Step 1: Create the test file with Phase 1 invariant tests**
```python
"""Tests for baseline Result[T] migration (sub-track 5 of result_migration_20260616).
Per the anti-sliming protocol, each phase has an invariant test that locks
the per-phase progress. Per-site tests are added per phase.
"""
import json
import subprocess
from pathlib import Path
def _load_baseline_audit() -> dict:
"""Re-run the audit and return the baseline findings."""
audit_json = Path("tests/artifacts/PHASE1_AUDIT_BASELINE.json")
if not audit_json.exists():
subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py",
"--include-baseline", "--json"],
check=True, capture_output=True,
)
return json.loads(audit_json.read_text())
def test_phase_1_invariant_mcp_client_inventory_has_46_rows():
"""Phase 1 invariant: the mcp_client inventory file has 46 rows."""
inventory = Path("tests/artifacts/PHASE1_SITE_INVENTORY_mcp_client.md")
assert inventory.exists(), "PHASE1_SITE_INVENTORY_mcp_client.md must exist"
content = inventory.read_text()
import re
row_count = len(re.findall(r"^\| L\d+", content, re.MULTILINE))
assert row_count == 46, f"Expected 46 sites in mcp_client inventory, found {row_count}"
def test_phase_1_invariant_ai_client_inventory_has_33_rows():
"""Phase 1 invariant: the ai_client inventory file has 33 rows."""
inventory = Path("tests/artifacts/PHASE1_SITE_INVENTORY_ai_client.md")
assert inventory.exists(), "PHASE1_SITE_INVENTORY_ai_client.md must exist"
content = inventory.read_text()
import re
row_count = len(re.findall(r"^\| L\d+", content, re.MULTILINE))
assert row_count == 33, f"Expected 33 sites in ai_client inventory, found {row_count}"
def test_phase_1_invariant_rag_engine_inventory_has_9_rows():
"""Phase 1 invariant: the rag_engine inventory file has 9 rows."""
inventory = Path("tests/artifacts/PHASE1_SITE_INVENTORY_rag_engine.md")
assert inventory.exists(), "PHASE1_SITE_INVENTORY_rag_engine.md must exist"
content = inventory.read_text()
import re
row_count = len(re.findall(r"^\| L\d+", content, re.MULTILINE))
assert row_count == 9, f"Expected 9 sites in rag_engine inventory, found {row_count}"
def test_phase_1_invariant_baseline_counts_captured():
"""Phase 1 invariant: the audit JSON captures the expected baseline counts."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
mcp = files.get("src\\mcp_client.py") or files.get("src/mcp_client.py")
assert mcp and mcp["violation_count"] + mcp["suspicious_count"] + mcp["unclear_count"] >= 46
ai = files.get("src\\ai_client.py") or files.get("src/ai_client.py")
assert ai and ai["violation_count"] + ai["suspicious_count"] + ai["unclear_count"] >= 33
rag = files.get("src\\rag_engine.py") or files.get("src/rag_engine.py")
assert rag and rag["violation_count"] + rag["suspicious_count"] + rag["unclear_count"] >= 9
```
- [ ] **Step 2: Run the test — it should PASS (the inventory was committed in Task 1.2)**
```bash
uv run python -m pytest tests/test_baseline_result.py -v
```
Expected: 4 PASSED
- [ ] **Step 3: Update state.toml Phase 1**
```toml
phase_1 = { status = "completed", checkpointsha = "<commit_sha>", name = "3-file inventory + classification (88 sites)" }
```
- [ ] **Step 4: Commit**
```bash
git add tests/test_baseline_result.py conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml
git commit -m "conductor(plan): mark Phase 1 complete (88-site inventory + 4 invariant tests)"
```
---
## Phase 2: Audit Gate Baseline (2 tasks)
**Focus:** Capture the baseline audit counts in 3 Phase 2 invariant tests. These tests will be REUSED (with relaxed assertions) in each phase to verify the per-phase count drop.
### Task 2.1: Add Phase 2 invariant tests (baseline count capture)
**Files:**
- Modify: `tests/test_baseline_result.py`
- [ ] **Step 1: Append Phase 2 invariant tests**
```python
def test_phase_2_invariant_mcp_client_baseline_captured():
"""Phase 2 invariant: mcp_client baseline violation count is captured (>= 45 V + 0 S + 1 ?)."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
mcp = files.get("src\\mcp_client.py") or files.get("src/mcp_client.py")
assert mcp["violation_count"] >= 45, f"mcp_client baseline V should be >= 45, got {mcp['violation_count']}"
def test_phase_2_invariant_ai_client_baseline_captured():
"""Phase 2 invariant: ai_client baseline violation count is captured (>= 26 V + 7 S + 0 ?)."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
ai = files.get("src\\ai_client.py") or files.get("src/ai_client.py")
assert ai["violation_count"] >= 26, f"ai_client baseline V should be >= 26, got {ai['violation_count']}"
assert ai["suspicious_count"] >= 7, f"ai_client baseline S should be >= 7, got {ai['suspicious_count']}"
def test_phase_2_invariant_rag_engine_baseline_captured():
"""Phase 2 invariant: rag_engine baseline violation count is captured (>= 6 V + 3 S)."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
rag = files.get("src\\rag_engine.py") or files.get("src/rag_engine.py")
assert rag["violation_count"] >= 6, f"rag_engine baseline V should be >= 6, got {rag['violation_count']}"
assert rag["suspicious_count"] >= 3, f"rag_engine baseline S should be >= 3, got {rag['suspicious_count']}"
```
- [ ] **Step 2: Run all tests (Phase 1 + Phase 2)**
```bash
uv run python -m pytest tests/test_baseline_result.py -v
```
Expected: 7 PASSED
- [ ] **Step 3: Update state.toml Phase 2**
```toml
phase_2 = { status = "completed", checkpointsha = "<commit_sha>", name = "Audit gate baseline (3 files; counts captured)" }
```
- [ ] **Step 4: Commit**
```bash
git add tests/test_baseline_result.py conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml
git commit -m "conductor(plan): mark Phase 2 complete (audit gate baseline + 3 invariant tests)"
```
---
## Phases 3-7: mcp_client.py Batches A-E (40 broad-catches, 5 batches × ≤8 sites)
**Focus:** Each batch migrates ≤8 mcp_client.py broad-catch sites using the standard `_result` helper pattern. Use the Phase 1 inventory to find the line numbers.
### Task 3.0: Phase 3 styleguide re-read + ack
- [ ] **Step 1: Re-read `error_handling.md` lines 462-540 (logging NOT a drain + Broad-Except table)**
- [ ] **Step 2: Ack commit**
```bash
git commit --allow-empty -m "chore: TIER-2 READ conductor/code_styleguides/error_handling.md lines 462-540 (logging NOT a drain) before Phase 3"
```
### Task 3.1-3.8: Migrate Batch A sites (≤8 mcp_client broad-catch sites)
For each site in the batch (use the Phase 1 inventory for line numbers):
- [ ] **Step 1: Write failing test** (with site name + line number; see migration pattern above)
- [ ] **Step 2: Run test, verify FAIL**
- [ ] **Step 3: Migrate** (extract `_result` helper + legacy wrapper per the migration pattern)
- [ ] **Step 4: Run test, verify PASS**
- [ ] **Step 5: Audit pre/post check** (capture in commit body)
- [ ] **Step 6: Commit** (one per site; format: `refactor(mcp_client): migrate L<line> _<feature> to Result[T] (Phase 3)`)
If a batch has fewer than 8 sites, the remaining tasks are skipped (not "filled in" with made-up sites).
### Task 3.9: Phase 3 invariant test + checkpoint
- [ ] **Step 1: Add Phase 3 invariant test** (Batch A mcp_client broad-catch count dropped)
```python
def test_phase_3_invariant_mcp_client_batch_a_dropped():
"""Phase 3 invariant: Batch A sites moved out of INTERNAL_BROAD_CATCH in mcp_client."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
mcp = files.get("src\\mcp_client.py") or files.get("src/mcp_client.py")
# Replace <BATCH_A_LINES> with the actual list (e.g., [123, 456, 789])
batch_a_lines = <BATCH_A_LINES>
remaining_in_v = [
f for f in mcp["findings"]
if f.get("line") in batch_a_lines and f.get("category") == "INTERNAL_BROAD_CATCH"
]
assert not remaining_in_v, (
f"Phase 3 Batch A sites still in INTERNAL_BROAD_CATCH: {[(f['line'], f['category']) for f in remaining_in_v]}"
)
```
- [ ] **Step 2: Update state.toml Phase 3 + commit**
```toml
phase_3 = { status = "completed", checkpointsha = "<commit_sha>", name = "mcp_client Batch A (<=8 sites)" }
```
```bash
git add tests/test_baseline_result.py conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml
git commit -m "conductor(plan): mark Phase 3 complete (mcp_client Batch A)"
```
### Tasks 4.0-4.9 / 5.0-5.9 / 6.0-6.9 / 7.0-7.9: Phases 4-7 (Batches B-E)
Same structure as Phase 3. Each phase:
- Styleguide re-read (ack commit)
- ≤8 site migrations (per-site: test, migrate, audit, commit)
- Phase invariant test
- Phase checkpoint
---
## Phase 8: mcp_client.py Silent-Swallow + UNCLEAR (5 + 1 = ≤6 sites)
**Focus:** The 5 INTERNAL_SILENT_SWALLOW sites (logging-only except bodies) and 1 UNCLEAR site. Per the user's principle (2026-06-17), logging is NOT a drain. NO narrowing+logging; full `Result[T]` propagation.
### Task 8.0: Phase 8 styleguide re-read (CRITICAL anti-sliming)
- [ ] **Step 1: Re-read `error_handling.md` lines 462-540 + lines 809-940 (AI Agent Checklist)**
- [ ] **Step 2: Ack commit (explicitly call out the sliming risk)**
```bash
git commit --allow-empty -m "chore: TIER-2 READ conductor/code_styleguides/error_handling.md lines 462-940 before Phase 8 — NO silent recovery, NO narrowing+logging"
```
### Tasks 8.1-8.6: Migrate sites
For each of the 6 sites (5 silent-swallow + 1 UNCLEAR):
- Same migration pattern (test, migrate, audit, commit)
- The except body MUST return `Result(data=<zero>, errors=[ErrorInfo(original=e)])`
- NO `logging.error(...)` in except body
- NO `sys.stderr.write(...)` in except body
- NO `pass` in except body
### Task 8.7: Phase 8 invariant + checkpoint
```python
def test_phase_8_invariant_mcp_client_silent_swallow_zero():
"""Phase 8 invariant: 0 INTERNAL_SILENT_SWALLOW sites in mcp_client."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
mcp = files.get("src\\mcp_client.py") or files.get("src/mcp_client.py")
silent = [f for f in mcp["findings"] if f.get("category") == "INTERNAL_SILENT_SWALLOW"]
assert not silent, f"Expected 0 INTERNAL_SILENT_SWALLOW, found {len(silent)}: {[f['line'] for f in silent]}"
unclear = [f for f in mcp["findings"] if f.get("category") == "UNCLEAR"]
assert not unclear, f"Expected 0 UNCLEAR, found {len(unclear)}: {[f['line'] for f in unclear]}"
```
---
## Phases 9-10: ai_client.py Batches A-B (17 broad-catches, 2 batches)
Same structure as Phases 3-7 (mcp_client batches). Per-site: test, migrate, audit, commit. Per-phase: invariant test + checkpoint.
### Task 9.0: Phase 9 styleguide re-read + ack
### Tasks 9.1-9.8: Migrate Batch A (≤8 sites)
### Task 9.9: Phase 9 invariant + checkpoint
### Task 10.0: Phase 10 styleguide re-read + ack
### Tasks 10.1-10.8: Migrate Batch B (≤8 sites; some may be silent-swallow or rethrow — see Phase 1 inventory)
### Task 10.9: Phase 10 invariant + checkpoint
---
## Phase 11: ai_client.py Silent-Swallow (9 sites)
**Focus:** The 9 INTERNAL_SILENT_SWALLOW sites in ai_client. Per the user's principle (logging NOT a drain), NO narrowing+logging; full `Result[T]` propagation.
### Task 11.0: Phase 11 styleguide re-read (CRITICAL anti-sliming)
### Tasks 11.1-11.9: Migrate 9 sites
### Task 11.10: Phase 11 invariant + checkpoint
```python
def test_phase_11_invariant_ai_client_silent_swallow_zero():
"""Phase 11 invariant: 0 INTERNAL_SILENT_SWALLOW sites in ai_client."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
ai = files.get("src\\ai_client.py") or files.get("src/ai_client.py")
silent = [f for f in ai["findings"] if f.get("category") == "INTERNAL_SILENT_SWALLOW"]
assert not silent, f"Expected 0 INTERNAL_SILENT_SWALLOW, found {len(silent)}: {[f['line'] for f in silent]}"
```
---
## Phase 12: ai_client.py Rethrow Classification (7 sites)
**Focus:** The 7 INTERNAL_RETHROW sites. Classify per Pattern 1/2/3 from `error_handling.md:625-690`. If a site does not fit any pattern, MIGRATE to `Result[T]`. Do NOT classify as "suspicious" (= sliming).
### Task 12.0: Phase 12 styleguide re-read (Re-Raise Patterns lines 625-690) + ack
### Tasks 12.1-12.7: Classify each rethrow site (or migrate)
For each site:
- Read the site code
- Determine which of the 3 patterns it fits (or "does not fit → migrate")
- If compliant: add a comment explaining which pattern
- If not compliant: use the standard migration pattern
- Per-site: test (if migrated), commit
### Task 12.8: Phase 12 invariant + checkpoint
```python
def test_phase_12_invariant_ai_client_rethrow_zero():
"""Phase 12 invariant: 0 INTERNAL_RETHROW sites in ai_client."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
ai = files.get("src\\ai_client.py") or files.get("src/ai_client.py")
rethrow = [f for f in ai["findings"] if f.get("category") == "INTERNAL_RETHROW"]
assert not rethrow, f"Expected 0 INTERNAL_RETHROW, found {len(rethrow)}: {[f['line'] for f in rethrow]}"
```
---
## Phase 13: rag_engine.py Migration (1 silent-swallow + 5 broad-catch + 3 rethrow = 9 sites)
**Focus:** The 9 sites in rag_engine (the smallest baseline file). Single phase since 9 sites fit comfortably.
### Task 13.0: Phase 13 styleguide re-read + ack
### Tasks 13.1-13.9: Migrate all 9 sites
For each site:
- The 5 broad-catch: standard `_result` helper pattern
- The 1 silent-swallow: full `Result[T]` propagation (NO narrowing+logging)
- The 3 rethrow: classify per Pattern 1/2/3 or migrate
### Task 13.10: Phase 13 invariant + checkpoint
```python
def test_phase_13_invariant_rag_engine_zero_violations():
"""Phase 13 invariant: 0 migration-target violations in rag_engine."""
data = _load_baseline_audit()
files = {f["filename"]: f for f in data["files"]}
rag = files.get("src\\rag_engine.py") or files.get("src/rag_engine.py")
migration = [f for f in rag["findings"] if f.get("category") in (
"INTERNAL_BROAD_CATCH", "INTERNAL_SILENT_SWALLOW", "INTERNAL_RETHROW", "UNCLEAR"
)]
assert not migration, f"Expected 0 migration-target sites, found {len(migration)}: {[(f['line'], f['category']) for f in migration]}"
```
---
## Phase 14: Audit Gate + End-of-Track Report (5 tasks)
**Focus:** Verify all gates, run the full batched suite, write the report, mark the track complete, update umbrella.
### Task 14.1: Run the strict audit gate
- [ ] **Step 1: Run the strict audit**
```bash
uv run python scripts/audit_exception_handling.py --include-baseline --strict
```
Expected: exit 0; 0 violations across the 3 baseline files
### Task 14.2: Run the unit tests
- [ ] **Step 1: Run all baseline tests**
```bash
uv run python -m pytest tests/test_baseline_result.py -v
```
Expected: ≥102 tests PASSED (88 site + 14 invariant)
### Task 14.3: Run the 11-tier batched suite
- [ ] **Step 1: Run the fixed batched script**
```bash
uv run python scripts/run_tests_batched.py
```
Expected: 11/11 tiers PASS
- [ ] **Step 2: If any tier fails, save the log to `tests/artifacts/PHASE14_TEST_RUN_<timestamp>.log` and report**
### Task 14.4: Write the end-of-track report
**Files:**
- Create: `docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md`
- [ ] **Step 1: Write the report (template below)**
```markdown
# Track Completion: Result Migration — Sub-Track 5 (Baseline Cleanup)
**Track ID:** `result_migration_baseline_cleanup_20260620`
**Date:** <YYYY-MM-DD>
**Status:** SHIPPED
## 1. Header / Scope Summary
<1-2 sentence summary>
## 2. Phase-by-Phase Summary
<14 sections, one per phase, with audit count delta>
## 3. Audit Results (Pre vs Post)
| Category | Pre-Phase-0 | Post-Phase-14 |
|---|---|---|
| mcp_client INTERNAL_BROAD_CATCH | 40 | 0 |
| mcp_client INTERNAL_SILENT_SWALLOW | 5 | 0 |
| mcp_client UNCLEAR | 1 | 0 |
| ai_client INTERNAL_BROAD_CATCH | 17 | 0 |
| ai_client INTERNAL_SILENT_SWALLOW | 9 | 0 |
| ai_client INTERNAL_RETHROW | 7 | 0 |
| rag_engine INTERNAL_BROAD_CATCH | 5 | 0 |
| rag_engine INTERNAL_SILENT_SWALLOW | 1 | 0 |
| rag_engine INTERNAL_RETHROW | 3 | 0 |
| BOUNDARY_SDK (preserved) | 4 | 4 |
| INTERNAL_PROGRAMMER_RAISE (preserved) | 9 | 9 |
| INTERNAL_COMPLIANT (preserved) | 28 | <new count> |
## 4. Last 3 Failures Encountered
<1-2 sentences per failure>
## 5. Files Modified
| Path | Sites | Description |
|---|---|---|
## 6. Git State
<commit count; first/last commit hashes; branch>
## 7. Recommendation
Campaign 100% complete. All 5 sub-tracks shipped. The data-oriented
`Result[T]` convention is now fully applied to all 65 src/ files.
## 8. Post-Completion Fixes (if any)
```
- [ ] **Step 2: Commit the report**
```bash
git add docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md
git commit -m "docs(reports): TRACK_COMPLETION_result_migration_baseline_cleanup_20260620 (14 phases complete)"
```
### Task 14.5: Final checkpoint + tracks.md update + umbrella count
- [ ] **Step 1: Phase 14 checkpoint commit**
```bash
git commit --allow-empty -m "conductor(checkpoint): Phase 14 complete — sub-track 5 SHIPPED; campaign 100% complete"
```
- [ ] **Step 2: Update `conductor/tracks.md` row to "shipped 2026-06-XX"**
- [ ] **Step 3: Update umbrella spec count** (campaign 100% complete; all 5 sub-tracks shipped)
```bash
# Edit conductor/tracks/result_migration_20260616/spec.md
# Update the sub-track table: sub-track 5 = 88 migration sites; campaign 100% complete
```
- [ ] **Step 4: Update campaign status report** (`docs/reports/RESULT_MIGRATION_CAMPAIGN_STATUS_20260619.md`) to mark sub-track 5 shipped
- [ ] **Step 5: Final commit**
```bash
git add conductor/tracks.md conductor/tracks/result_migration_20260616/spec.md docs/reports/RESULT_MIGRATION_CAMPAIGN_STATUS_20260619.md conductor/tracks/result_migration_baseline_cleanup_20260620/state.toml conductor/tracks/result_migration_baseline_cleanup_20260620/metadata.json
git commit -m "conductor(plan): sub-track 5 SHIPPED — campaign 100% complete; tracks.md + umbrella + status updated"
```
---
## Summary
**14 phases, ~120 atomic commits, 88 migration sites + 6 stay-as-is + 9 INTERNAL_PROGRAMMER_RAISE + 4 BOUNDARY_SDK + 28 INTERNAL_COMPLIANT, 102+ tests, 1 report.**
| Dimension | Count |
|---|---|
| Source files modified | 3 (mcp_client, ai_client, rag_engine) |
| Migration sites | 88 (62 BC + 15 SS + 10 RETHROW + 1 UNCLEAR) |
| Stay-as-is sites | 41 (4 BOUNDARY_SDK + 9 INTERNAL_PROGRAMMER_RAISE + 28 INTERNAL_COMPLIANT) |
| Tests | ≥102 (88 site + 14 invariant) |
| Phases | 14 |
| Atomic commits | ≥110 |
---
## Self-Review
**1. Spec coverage:** All 15 VCs in spec.md §8 are covered by tasks in this plan. VC-1 (audit --strict) is Task 14.1. VC-2 (0 INTERNAL_BROAD_CATCH) is Phases 3-7 + 9-10 + 13. VC-3 (0 INTERNAL_SILENT_SWALLOW) is Phases 8 + 11 + 13. VC-4 (0 INTERNAL_RETHROW) is Phases 12 + 13. VC-5 (0 UNCLEAR) is Phase 8. VC-6 (4 BOUNDARY_SDK preserved) — no action needed; verify in Phase 14 invariant. VC-7 (9 INTERNAL_PROGRAMMER_RAISE preserved) — no action needed; verify in Phase 14. VC-8 (≥102 tests) is per-phase test additions. VC-9 (11/11 tiers) is Task 14.3. VC-10 (per-phase audit gates) is per-phase invariant tests. VC-11 (14 styleguide-ack commits) is per-phase Task 0. VC-12 (≥110 commits) is per-site commits. VC-13 (report) is Task 14.4. VC-14 (tracks.md) is Task 14.5. VC-15 (umbrella count) is Task 14.5.
**2. Placeholder scan:** No "TBD", "TODO", "implement later", "fill in details" in this plan. All migration patterns show concrete code. All tasks show concrete commands. The `<BATCH_A_LINES>` placeholder in Task 3.9 is a list that gets populated by the inventory (not a code-level placeholder).
**3. Type consistency:** `Result[bool]` / `Result[None]` / `Result[T]` used consistently across all migration tasks. `ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source=..., original=e)` consistent with the convention. `tests/test_baseline_result.py` test names consistent with the per-phase pattern.
**4. Anti-sliming protocol:** Enforced via (a) styleguide re-read at start of every phase, (b) per-site audit pre/post check, (c) per-phase invariant test, (d) per-file atomic commits, (e) explicit instruction in Phase 8 (mcp_client silent-swallow) and Phase 11 (ai_client silent-swallow) that narrowing+logging is forbidden, (f) explicit instruction in Phase 12 (ai_client rethrow) that classify-as-suspicious is forbidden.
**5. Migration pattern consistency:** All migration tasks use the same `_result` helper pattern shown in the "Migration Pattern" section. This matches the existing convention in mcp_client + ai_client + rag_engine (per `data_oriented_error_handling_20260606`).
---
@@ -0,0 +1,343 @@
# Track Specification: Result Migration — Sub-Track 5 (Baseline Cleanup)
**Track ID:** `result_migration_baseline_cleanup_20260620`
**Status:** Active (spec approved 2026-06-20)
**Priority:** A (closes the gaps in the convention reference; makes the baseline 100% convention-compliant)
**Owner:** Tier 2 Tech Lead
**Type:** refactor (14 phases; anti-sliming protocol enforced per phase — same template as sub-track 4)
**Scope:** 88 migration sites across 3 source files (`mcp_client.py` 83KB, `ai_client.py` 137KB, `rag_engine.py` 11KB) + 1 new test file
**Parent tracks:** `result_migration_20260616` (umbrella), `result_migration_gui_2_20260619` (sub-track 4, SHIPPED 2026-06-20), `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 5 of the 5-sub-track `result_migration_20260616` umbrella. It migrates the 3 baseline files (`mcp_client.py`, `ai_client.py`, `rag_engine.py`) — the convention reference files — to be 100% convention-compliant. The umbrella originally estimated 112 sites at T-shirt L; the current audit shows 88 migration-target sites (45 V + 26 V + 6 V; 5 S + 9 S + 3 S; 1 UNCLEAR) across the 3 files. 41 sites stay as-is (4 BOUNDARY_SDK + 9 INTERNAL_PROGRAMMER_RAISE + 28 INTERNAL_COMPLIANT).
**Why 14 phases (vs the umbrella's "1-2 phases"):** per the user's directive (2026-06-20), this track uses the **same anti-sliming template as sub-track 4** (which was the first sub-track to ship without error correction). The 14-phase structure caps each phase at ≤9 migration sites with explicit per-phase audit gates. Sub-track 4 shipped 42 sites in 13 phases with 0 sliming; sub-track 5 scales the same template to 88 sites in 3 files across 14 phases.
**What this track consumes from sub-tracks 1-4:**
- Sub-track 1's review pass: the 10 new audit heuristics (correctly classify most sites)
- Sub-track 3 Phase 7: the tightened `_is_fastapi_handler` BOUNDARY_FASTAPI heuristic
- Sub-track 4 Phase 11: the dunder-method bare-raise heuristic (5 INTERNAL_PROGRAMMER_RAISE reclassifications)
- Sub-track 4 Phase 12: the lazy-loading sentinel fallback heuristic (1 UNCLEAR reclassification possible)
**What this track enables:** completion of the 5-sub-track campaign. After this track, the data-oriented `Result[T]` convention is **fully applied** to all 65 src/ files. The 3 baseline files become the **pure** convention reference.
---
## 1. Overview
### 1.1 The State Before This Track (as of 2026-06-20)
Per `uv run python scripts/audit_exception_handling.py --include-baseline`:
```
src/mcp_client.py: V=45 S=0 ?=1 C=9 total=55
Categories: INTERNAL_COMPLIANT: 9, INTERNAL_SILENT_SWALLOW: 5, INTERNAL_BROAD_CATCH: 40, UNCLEAR: 1
src/ai_client.py: V=26 S=7 ?=0 C=26 total=59
Categories: BOUNDARY_SDK: 4, INTERNAL_RETHROW: 7, INTERNAL_SILENT_SWALLOW: 9, INTERNAL_BROAD_CATCH: 17,
INTERNAL_COMPLIANT: 17, INTERNAL_PROGRAMMER_RAISE: 4, BOUNDARY_CONVERSION: 1
src/rag_engine.py: V=6 S=3 ?=0 C=6 total=15
Categories: INTERNAL_RETHROW: 3, INTERNAL_PROGRAMMER_RAISE: 5, INTERNAL_BROAD_CATCH: 5,
INTERNAL_COMPLIANT: 1, INTERNAL_SILENT_SWALLOW: 1
```
**Migration target: 88 sites** (62 INTERNAL_BROAD_CATCH + 15 INTERNAL_SILENT_SWALLOW + 10 INTERNAL_RETHROW + 1 UNCLEAR; V=77 includes both broad-catch + silent-swallow per audit classification, S=10 is rethrow, ?=1 is unclear). 41 sites stay as-is: 4 BOUNDARY_SDK (ai_client's vendor SDK boundaries), 9 INTERNAL_PROGRAMMER_RAISE (5 in rag_engine from sub-track 4 Phase 11 dunder-method heuristic + 4 in ai_client), 28 INTERNAL_COMPLIANT.
### 1.2 The Goal
Migrate all 88 migration-target sites to the data-oriented `Result[T]` convention, using the established `_result` helper convention. After this track ships:
- 0 `INTERNAL_BROAD_CATCH` in the 3 baseline files (was 62: 40 + 17 + 5).
- 0 `INTERNAL_SILENT_SWALLOW` in the 3 baseline files (was 15: 5 + 9 + 1).
- 0 `INTERNAL_RETHROW` in the 3 baseline files (was 10: 0 + 7 + 3) — classified per Pattern 1/2/3 from `error_handling.md`.
- 0 `UNCLEAR` in the 3 baseline files (was 1: 1 + 0 + 0) — classified or migrated.
- `audit_exception_handling.py --include-baseline --strict` exits 0.
- 11-tier batched test suite passes with no new regressions.
### 1.3 The 14-Phase Structure (Anti-Sliming Protocol)
| Phase | Scope | Sites | Tests | Audit gate |
|---|---|---|---|---|
| 0 | Setup + styleguide re-read | 0 | 0 | n/a |
| 1 | 3-file inventory + classification | 0 | 0 (3 inventory docs) | 3 inventory docs committed |
| 2 | Audit gate baseline capture | 0 | 3 (1 invariant per file) | baseline counts captured |
| 3 | mcp_client Batch A (tool broad-catches) | ≤8 | ≤8 | mcp_client V drops by batch A |
| 4 | mcp_client Batch B (tool broad-catches) | ≤8 | ≤8 | mcp_client V drops by batch B |
| 5 | mcp_client Batch C (tool broad-catches) | ≤8 | ≤8 | mcp_client V drops by batch C |
| 6 | mcp_client Batch D (tool broad-catches) | ≤8 | ≤8 | mcp_client V drops by batch D |
| 7 | mcp_client Batch E (tool broad-catches) | ≤8 | ≤8 | mcp_client V drops by batch E |
| 8 | mcp_client silent-swallow + UNCLEAR (5 + 1) | ≤6 | ≤6 | mcp_client S + ? drops to 0 |
| 9 | ai_client Batch A (broad-catch) | ≤8 | ≤8 | ai_client V drops by batch A |
| 10 | ai_client Batch B (broad-catch) | ≤8 | ≤8 | ai_client V drops by batch B |
| 11 | ai_client silent-swallow (9) | ≤9 | ≤9 | ai_client S drops by 9 |
| 12 | ai_client rethrow classification (7) | ≤7 | ≤7 | ai_client S drops to 0 |
| 13 | rag_engine migration (1 silent-swallow + 5 broad-catch + 3 rethrow) | ≤9 | ≤9 | rag_engine V + S → 0 |
| 14 | Audit gate + end-of-track report | 0 | 1 invariant | `--include-baseline --strict` exits 0; 11/11 tiers PASS |
**Total: 14 phases, 88 migration sites + 14 invariant tests + 88+ site tests + 3 inventory docs + 1 report.**
**No phase has more than 9 migration sites.** The sliming-prone phases are:
- Phase 8 (mcp_client silent-swallow + UNCLEAR) — per user principle (logging NOT a drain)
- Phase 11 (ai_client silent-swallow) — same
- Phase 12 (ai_client rethrow) — if a site doesn't fit Pattern 1/2/3, MIGRATE not classify
---
## 2. Current State Audit (as of 2026-06-20)
### 2.1 Already Implemented (DO NOT re-implement)
| Item | Location | What it does |
|---|---|---|
| `Result[T]` dataclass | `src/result_types.py:91-105` | The data-oriented container |
| `ErrorInfo` + `ErrorKind` | `src/result_types.py:117-130` | The canonical error type |
| Audit script + 5 drain-point heuristics | `scripts/audit_exception_handling.py:1-1100` | The gate (incl. sub-track 3 Phase 7 + sub-track 4 Phase 11/12 heuristics) |
| 45+ tool function `_result` helpers (incomplete) | `src/mcp_client.py` (partial) | Tool functions return `Result[T]` (per `data_oriented_error_handling_20260606`) |
| `_send_<vendor>_result` helpers (incomplete) | `src/ai_client.py` (partial) | Vendor SDK boundaries (per the convention) |
| `_validate_collection_dim_result`, `is_empty_result`, `add_documents_result` | `src/rag_engine.py` (partial) | RAG engine (per the convention) |
| 5 dunder-method regression-guard tests | `tests/test_audit_heuristics.py` | Lock Phase 11 heuristic |
| 3 lazy-loading regression-guard tests | `tests/test_audit_heuristics.py` | Lock Phase 12 heuristic |
| 4 BOUNDARY_SDK sites in `ai_client.py` | `src/ai_client.py` | Vendor SDK boundaries (legitimate) |
| 9 INTERNAL_PROGRAMMER_RAISE sites | `src/ai_client.py` (4) + `src/rag_engine.py` (5) | Bare raises in dunder methods (legitimate per Phase 11 heuristic) |
| `error_handling.md` Drain Points + Broad-Except table | `conductor/code_styleguides/error_handling.md:356-540` | The 5 drain patterns + the logging-NOT-drain rule |
| `error_handling.md` AI Agent Checklist | `conductor/code_styleguides/error_handling.md:809-940` | 5 MUST-DO + 7 MUST-NOT-DO rules |
### 2.2 Gaps to Fill (This Track's Scope)
**88 migration-target sites across 3 files:**
- **mcp_client.py (46 sites):** 40 INTERNAL_BROAD_CATCH (tool function broad-catches per umbrella "Path C deferred work") + 5 INTERNAL_SILENT_SWALLOW (logging-only except bodies) + 1 UNCLEAR (needs classification)
- **ai_client.py (33 sites):** 17 INTERNAL_BROAD_CATCH (multi-provider broad-catches) + 9 INTERNAL_SILENT_SWALLOW (logging-only) + 7 INTERNAL_RETHROW (need Pattern 1/2/3 classification)
- **rag_engine.py (9 sites):** 5 INTERNAL_BROAD_CATCH + 1 INTERNAL_SILENT_SWALLOW + 3 INTERNAL_RETHROW
**Infrastructure gaps:** 0 (the 3 baseline files are backend services; no new render functions needed; the existing `_result` helper convention is the data plane).
**Test gaps:** 1 new test file `tests/test_baseline_result.py` with 88+ site tests + 14 invariant tests.
---
## 3. Goals
### 3.1 Primary Goal
Migrate all 88 migration-target sites across the 3 baseline files to the data-oriented `Result[T]` convention, using the established `_result` helper convention (per `data_oriented_error_handling_20260606`).
### 3.2 Secondary Goals
1. **Verify per-phase audit gates**: each phase's invariant test shows the expected count drop.
2. **No new regressions**: 11/11 batched test tiers PASS; existing baseline tests (`test_mcp_client_whitelist_enforcement.py`, `test_ai_client.py`, `test_rag_engine.py`) continue to pass.
3. **Per-site unit tests**: 1 test per migrated site (≥88) + 1 invariant test per phase (14).
4. **No sliming**: per-phase protocol with styleguide re-read + audit gate (same as sub-track 4).
5. **Classify don't classify-as-suspicious**: the 10 INTERNAL_RETHROW sites must be classified per Pattern 1/2/3 from `error_handling.md:625-690` or migrated to `Result[T]`.
### 3.3 Non-Goals
- Adding new error sites (this track migrates EXISTING sites only).
- Changing the audit heuristic (sub-track 3 Phase 7 + sub-track 4 Phase 11/12 heuristics are correct).
- Removing the legacy wrappers (the sub-track 3 Phase 6 Group 6.3 pattern preserves them).
- Migrating the 41 sites that stay as-is (4 BOUNDARY_SDK + 9 INTERNAL_PROGRAMMER_RAISE + 28 INTERNAL_COMPLIANT).
- Sub-track 4's drain plane (gui_2.py) — separate track, already shipped.
---
## 4. Functional Requirements
### 4.1 Phase 0 (Setup)
**FR0-1** Tier 2 reads `conductor/code_styleguides/error_handling.md` end-to-end.
**FR0-2** Tier 2 acknowledges in commit message: "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 0."
**FR0-3** `conductor/tracks.md` updated with new track row.
### 4.2 Phase 1 (Inventory)
**FR1-1** Run `uv run python scripts/audit_exception_handling.py --include-baseline --json > tests/artifacts/PHASE1_AUDIT_BASELINE.json`.
**FR1-2** Walk every finding; for the 88 migration-target sites, write 3 inventory docs:
- `tests/artifacts/PHASE1_SITE_INVENTORY_mcp_client.md` (46 rows)
- `tests/artifacts/PHASE1_SITE_INVENTORY_ai_client.md` (33 rows)
- `tests/artifacts/PHASE1_SITE_INVENTORY_rag_engine.md` (9 rows)
**FR1-3** Each row: line, category, current code (5 lines around), target migration, drain point.
**FR1-4** "Drain point" for backend services: the caller (MMA worker, mcp_client tool invocation, API hook).
### 4.3 Phase 2 (Audit Gate Baseline)
**FR2-1** Create `tests/test_baseline_result.py` with 3 Phase 2 invariant tests (one per file).
**FR2-2** Each invariant test asserts the baseline audit count for that file matches the pre-track numbers.
### 4.4 Phases 3-8 (mcp_client.py Migrations)
**FR3-FR8-1** For each of the 46 mcp_client.py sites, extract a `_<feature>_result(...) -> Result[T]` helper (per the mcp_client convention; e.g., `read_file_result`, `list_directory_result`).
**FR3-FR8-2** The except body returns `Result(data=<zero-value>, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="mcp_client._<feature>_result", original=e)])`.
**FR3-FR8-3** The legacy wrapper checks `.ok` and either propagates the error or returns the data.
**FR3-FR8-4** No `logging.*` in except bodies (per user principle 2026-06-17).
**FR3-FR8-5** Per-site unit test in `tests/test_baseline_result.py` verifies the helper returns `Result.ok=True` on success and `Result.ok=False` with `ErrorInfo` on failure.
### 4.5 Phases 9-12 (ai_client.py Migrations)
**FR9-FR12-1** For each of the 33 ai_client.py sites, follow the same pattern as 4.4 but use the `_send_<vendor>_result` naming convention.
**FR9-FR12-2** The 4 BOUNDARY_SDK sites (vendor SDK boundaries) stay as-is.
**FR9-FR12-3** The 4 INTERNAL_PROGRAMMER_RAISE sites stay as-is.
**FR9-FR12-4** For the 7 INTERNAL_RETHROW sites (Phase 12), classify per Pattern 1/2/3:
- Pattern 1: catch + convert + raise as different type (compliant if convert is meaningful)
- Pattern 2: catch + log + re-raise (compliant if log provides value)
- Pattern 3: catch + cleanup + re-raise via try/finally (compliant)
**FR9-FR12-5** If a site does not fit any pattern, MIGRATE to `Result[T]`. Do NOT classify as "suspicious" (= sliming).
### 4.6 Phase 13 (rag_engine.py Migrations)
**FR13-1** For each of the 9 rag_engine.py sites, follow the same pattern as 4.4 but use the rag_engine convention (`is_empty_result`, `_validate_collection_dim_result`, etc.).
**FR13-2** The 5 INTERNAL_PROGRAMMER_RAISE sites stay as-is (per sub-track 4 Phase 11 heuristic).
**FR13-3** The 3 INTERNAL_RETHROW sites classified per Pattern 1/2/3 (same as 4.5.4).
### 4.7 Phase 14 (Audit Gate + Report)
**FR14-1** Run `uv run python scripts/audit_exception_handling.py --include-baseline --strict` — verify exit 0.
**FR14-2** Run `uv run python -m pytest tests/test_baseline_result.py -v` — verify all pass.
**FR14-3** Run `uv run python scripts/run_tests_batched.py` — verify 11/11 tiers PASS.
**FR14-4** Write `docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md`.
**FR14-5** Update `conductor/tracks.md` row to "shipped".
**FR14-6** Update umbrella spec count (campaign 100% complete).
---
## 5. Non-Functional Requirements
- **NFR-1** `audit_exception_handling.py --include-baseline --strict` exits 0 at end of Phase 14.
- **NFR-2** 11-tier batched test suite passes with no new regressions.
- **NFR-3** All new code uses 1-space indentation per `product-guidelines.md`.
- **NFR-4** Per-file atomic commits (1 site = 1 commit) per `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.
- **NFR-7** No `@pytest.mark.skip` markers added.
- **NFR-8** No new `Optional[T]` return types (the convention's `Result[T]` ban).
- **NFR-9** No new `try/except` sites with logging-only except bodies (the sliming pattern).
---
## 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 (5 patterns + Heuristic D).
- `conductor/code_styleguides/error_handling.md:462-476` — "What is NOT a drain point" (logging NOT a drain).
- `conductor/code_styleguides/error_handling.md:520-540` — Broad-Except Distinction table.
- `conductor/code_styleguides/error_handling.md:584-624` — Constructors Can Raise.
- `conductor/code_styleguides/error_handling.md:625-690` — Re-Raise Patterns (1/2/3).
- `conductor/code_styleguides/error_handling.md:809-940` — AI Agent Checklist.
- `conductor/tracks/result_migration_20260616/spec.md` — umbrella.
- `conductor/tracks/result_migration_gui_2_20260619/spec.md` — sub-track 4 (the anti-sliming template this track follows).
- `conductor/tracks/result_migration_app_controller_20260618/spec.md` — sub-track 3 (data plane + heuristic tightening).
- `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.
- `docs/guide_mcp_client.md` — mcp_client.py architecture (45 tools, 3-layer security, ExternalMCPManager).
- `docs/guide_ai_client.md` — ai_client.py architecture (multi-provider, caching, thread-local source tier).
- `docs/guide_rag.md` — rag_engine.py architecture (ChromaDB, embedding providers, chunking).
- `scripts/audit_exception_handling.py:318-460` — Phase 7 heuristic + Phase 11/12 heuristics.
- `tests/test_audit_heuristics.py` — 8 regression-guard tests (5 dunder + 3 lazy-loading).
---
## 7. Per-Phase Migration Strategy
The same anti-sliming protocol as sub-track 4 (which the user praised as "the first to not need error correction"):
1. **Pre-phase styleguide re-read** (commit 1 of the phase): Read `error_handling.md` end-to-end. Commit message: "TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase N."
2. **Audit pre-check** (per site, before migration): Run the audit JSON; confirm the site's category BEFORE migration. Capture in commit body.
3. **Red** (1 commit per site): Write the unit test in `tests/test_baseline_result.py`. Run test — must FAIL. Commit.
4. **Green** (1 commit per site): Migrate the site. Use the `_result` helper convention. Run test — must PASS. Commit.
5. **Audit post-check** (per site, after migration): Same command. Confirm the site moved out of the violation category. Capture in commit body.
6. **Phase invariant test** (1 commit at end of phase): `test_phase_N_<file>_<phase>_invariant` verifies the per-phase count drop.
7. **Per-file atomic commits:** 1 site = 1 commit.
If a site "resists migration" in any phase, Tier 2 MUST report — not invent a heuristic.
### 7.1 Phase 0: Setup + Styleguide Re-Read
3 tasks: tracks.md update; styleguide read + ack commit; Phase 0 checkpoint.
### 7.2 Phase 1: 3-File Inventory
3 tasks: run audit; write 3 inventory docs; commit.
### 7.3 Phase 2: Audit Gate Baseline
2 tasks: create test file with 3 Phase 2 invariants; Phase 2 checkpoint.
### 7.4 Phases 3-7: mcp_client.py Batches A-E (40 broad-catches, 5 batches × ≤8 sites)
For each batch:
- Styleguide re-read (ack commit)
- Per-site: write test, run fail, migrate, run pass, audit pre/post, commit
- Phase invariant test (e.g., `test_phase_3_invariant_mcp_client_batch_a_dropped`)
- Phase checkpoint
### 7.5 Phase 8: mcp_client.py Silent-Swallow + UNCLEAR (6 sites)
5 INTERNAL_SILENT_SWALLOW + 1 UNCLEAR. Per user principle (logging NOT a drain), NO narrowing+logging; full `Result[T]` propagation.
### 7.6 Phases 9-10: ai_client.py Batches A-B (17 broad-catches, 2 batches)
Same pattern as 7.4.
### 7.7 Phase 11: ai_client.py Silent-Swallow (9 sites)
Same pattern as 7.5. CRITICAL anti-sliming phase.
### 7.8 Phase 12: ai_client.py Rethrow Classification (7 sites)
Classify per Pattern 1/2/3 or MIGRATE. NOT classify as "suspicious".
### 7.9 Phase 13: rag_engine.py Migration (9 sites)
1 silent-swallow + 5 broad-catch + 3 rethrow. Single phase (small file).
### 7.10 Phase 14: Audit Gate + End-of-Track Report
5 tasks: `--strict` audit; unit tests; batched suite; report; tracks.md + umbrella update.
---
## 8. Verification Criteria
- **VC-1** `audit_exception_handling.py --include-baseline --strict` exits 0.
- **VC-2** 0 INTERNAL_BROAD_CATCH across 3 baseline files (62 → 0).
- **VC-3** 0 INTERNAL_SILENT_SWALLOW across 3 baseline files (15 → 0).
- **VC-4** 0 INTERNAL_RETHROW across 3 baseline files (10 → 0 or classified).
- **VC-5** 0 UNCLEAR across 3 baseline files (1 → 0).
- **VC-6** The 4 BOUNDARY_SDK sites in `ai_client.py` are preserved.
- **VC-7** The 9 INTERNAL_PROGRAMMER_RAISE sites (4 ai_client + 5 rag_engine) are preserved.
- **VC-8** `tests/test_baseline_result.py` exists with ≥102 tests (88 site + 14 invariant), all pass.
- **VC-9** 11-tier batched test suite passes with no new regressions.
- **VC-10** Per-phase audit gates verified (each phase's invariant test confirms the expected count drop).
- **VC-11** Tier 2 acknowledged styleguide re-read at start of each phase (14 styleguide-ack commits).
- **VC-12** Git history shows ≥110 atomic commits (88 site + 14 phase setup + 3 infra + 2 docs).
- **VC-13** End-of-track report at `docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md`.
- **VC-14** `conductor/tracks.md` row updated to "shipped 2026-06-XX".
- **VC-15** Umbrella spec count updated; campaign 100% complete.
---
## 9. Out of Scope
- **Sub-tracks 1-4** (all shipped; out of scope).
- **Migrating `tests/` files** (out of scope per the convention ancestor).
- **Adding new `try/except` sites** (this track migrates EXISTING sites only).
- **Changing the audit heuristic** (sub-track 3 Phase 7 + sub-track 4 Phase 11/12 are correct).
- **Removing the legacy wrappers** (sub-track 3 Phase 6 Group 6.3 pattern preserves them; follow-up track can migrate callers).
- **Migrating the 41 stay-as-is sites** (4 BOUNDARY_SDK + 9 INTERNAL_PROGRAMMER_RAISE + 28 INTERNAL_COMPLIANT).
---
## 10. Risks
| ID | Risk | Likelihood | Mitigation |
|---|---|---|---|
| R5-1 | ai_client.py's multi-provider `_send_<vendor>_result` helpers are partially in place; the 33 remaining sites include some already-`_result` and some still-broad-catch | low | Phase 1 inventory forces explicit per-site classification |
| R5-2 | mcp_client.py's 45 tool functions: each tool is a small surface; per-tool `_result` helper follows the established convention | low | Per-phase audit gate; if a batch fails, the phase stops |
| R5-3 | rag_engine.py's 9 sites include 3 INTERNAL_RETHROW that may need Pattern 1/2/3 classification | medium | Phase 13 includes classification step |
| R5-4 | Per-site `Result[T]` migration in 3 large files could regress the existing 41 compliant sites | low | Per-phase audit gate; if compliant count drops, the phase fails |
| R5-5 | The 9 INTERNAL_PROGRAMMER_RAISE + 4 BOUNDARY_SDK sites may be incorrectly classified (code may have changed since the heuristic was added) | low | Phase 1 inventory forces explicit per-site classification; misclassifications reported to user |
| R5-6 | Tier 2 invents a laundering heuristic (the sliming pattern from sub-tracks 2/3) | medium | Anti-sliming protocol enforced per phase; "If a site resists migration: DO NOT invent a heuristic. Report." |
---
## 11. See Also
- `conductor/code_styleguides/error_handling.md` — the canonical convention.
- `conductor/code_styleguides/data_oriented_design.md` — the canonical DOD reference.
- `conductor/tracks/result_migration_20260616/spec.md` — the umbrella.
- `conductor/tracks/result_migration_gui_2_20260619/spec.md` — sub-track 4 (the anti-sliming template).
- `conductor/tracks/result_migration_app_controller_20260618/spec.md` — sub-track 3 (the data plane + heuristic tightening).
- `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.
- `docs/guide_mcp_client.md` — mcp_client.py architecture.
- `docs/guide_ai_client.md` — ai_client.py architecture.
- `docs/guide_rag.md` — rag_engine.py architecture.
- `scripts/audit_exception_handling.py` — the audit script (the gate).
- `tests/test_audit_heuristics.py` — 8 regression-guard tests (5 dunder + 3 lazy-loading).
- `docs/reports/RESULT_MIGRATION_CAMPAIGN_STATUS_20260619.md` — the campaign status report (4/5 sub-tracks shipped; this track completes the campaign).
@@ -0,0 +1,218 @@
# Track state for result_migration_baseline_cleanup_20260620
# Updated by Tier 2 Tech Lead as tasks complete
[meta]
track_id = "result_migration_baseline_cleanup_20260620"
name = "Result Migration - Sub-Track 5 (Baseline Cleanup)"
status = "active"
current_phase = 0
last_updated = "2026-06-20"
umbrella = "result_migration_20260616"
sub_track_index = 5
anti_sliming_protocol = "ENABLED — same template as sub-track 4 (which was the first to ship without error correction per user); 14 phases cap each phase at <=9 sites; per-phase styleguide re-read + per-site audit pre/post check + per-phase invariant test"
[blocked_by]
result_migration_gui_2_20260619 = "shipped 2026-06-20 (sub-track 4)"
[blocks]
# This is the final sub-track; no follow-up tracks in this campaign.
[phases]
phase_0 = { status = "pending", checkpointsha = "", name = "Setup + styleguide re-read (3 tasks)" }
phase_1 = { status = "pending", checkpointsha = "", name = "3-file inventory + classification (4 tasks; 88 sites in 3 inventory docs)" }
phase_2 = { status = "pending", checkpointsha = "", name = "Audit gate baseline (2 tasks; 3 baseline invariant tests)" }
phase_3 = { status = "pending", checkpointsha = "", name = "mcp_client Batch A (tool broad-catches; <=8 sites)" }
phase_4 = { status = "pending", checkpointsha = "", name = "mcp_client Batch B (tool broad-catches; <=8 sites)" }
phase_5 = { status = "pending", checkpointsha = "", name = "mcp_client Batch C (tool broad-catches; <=8 sites)" }
phase_6 = { status = "pending", checkpointsha = "", name = "mcp_client Batch D (tool broad-catches; <=8 sites)" }
phase_7 = { status = "pending", checkpointsha = "", name = "mcp_client Batch E (tool broad-catches; <=8 sites)" }
phase_8 = { status = "pending", checkpointsha = "", name = "mcp_client silent-swallow + UNCLEAR (5 + 1 = 6 sites; CRITICAL anti-sliming)" }
phase_9 = { status = "pending", checkpointsha = "", name = "ai_client Batch A (broad-catch; <=8 sites)" }
phase_10 = { status = "pending", checkpointsha = "", name = "ai_client Batch B (broad-catch; <=8 sites)" }
phase_11 = { status = "pending", checkpointsha = "", name = "ai_client silent-swallow (9 sites; CRITICAL anti-sliming)" }
phase_12 = { status = "pending", checkpointsha = "", name = "ai_client rethrow classification (7 sites; Pattern 1/2/3 or migrate)" }
phase_13 = { status = "pending", checkpointsha = "", name = "rag_engine migration (1 SS + 5 BC + 3 RETHROW = 9 sites)" }
phase_14 = { status = "pending", checkpointsha = "", name = "Audit gate + end-of-track report (5 tasks; --include-baseline --strict exits 0; 11/11 tiers PASS; campaign 100% complete)" }
[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: 3-file inventory + classification (4 tasks)
t1_1 = { status = "pending", commit_sha = "", description = "Run audit --include-baseline --json > tests/artifacts/PHASE1_AUDIT_BASELINE.json" }
t1_2 = { status = "pending", commit_sha = "", description = "Walk the audit + write 3 inventory docs (mcp_client 46 rows, ai_client 33 rows, rag_engine 9 rows)" }
t1_3 = { status = "pending", commit_sha = "", description = "Create tests/test_baseline_result.py with 4 Phase 1 invariant tests; Phase 1 checkpoint" }
# Phase 2: Audit gate baseline (2 tasks)
t2_1 = { status = "pending", commit_sha = "", description = "Add 3 Phase 2 invariant tests (baseline count capture per file); Phase 2 checkpoint" }
# Phase 3: mcp_client Batch A (<=8 sites)
t3_0 = { status = "pending", commit_sha = "", description = "Phase 3 styleguide re-read (lines 462-540) + ack commit" }
t3_1 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 1" }
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 = "Add Phase 3 invariant test; Phase 3 checkpoint" }
# Phase 4: mcp_client Batch B (<=8 sites)
t4_0 = { status = "pending", commit_sha = "", description = "Phase 4 styleguide re-read + ack commit" }
t4_1 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 1" }
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 = "Add Phase 4 invariant test; Phase 4 checkpoint" }
# Phase 5: mcp_client Batch C (<=8 sites)
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" }
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" }
t5_9 = { status = "pending", commit_sha = "", description = "Add Phase 5 invariant test; Phase 5 checkpoint" }
# Phase 6: mcp_client Batch D (<=8 sites)
t6_0 = { status = "pending", commit_sha = "", description = "Phase 6 styleguide re-read + ack commit" }
t6_1 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 1" }
t6_2 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 2" }
t6_3 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 3" }
t6_4 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 4" }
t6_5 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 5" }
t6_6 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 6" }
t6_7 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 7" }
t6_8 = { status = "pending", commit_sha = "", description = "Migrate Batch D site 8" }
t6_9 = { status = "pending", commit_sha = "", description = "Add Phase 6 invariant test; Phase 6 checkpoint" }
# Phase 7: mcp_client Batch E (<=8 sites)
t7_0 = { status = "pending", commit_sha = "", description = "Phase 7 styleguide re-read + ack commit" }
t7_1 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 1" }
t7_2 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 2" }
t7_3 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 3" }
t7_4 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 4" }
t7_5 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 5" }
t7_6 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 6" }
t7_7 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 7" }
t7_8 = { status = "pending", commit_sha = "", description = "Migrate Batch E site 8" }
t7_9 = { status = "pending", commit_sha = "", description = "Add Phase 7 invariant test; Phase 7 checkpoint" }
# Phase 8: mcp_client silent-swallow + UNCLEAR (6 sites; CRITICAL anti-sliming)
t8_0 = { status = "pending", commit_sha = "", description = "Phase 8 styleguide re-read (lines 462-940; AI Agent Checklist) + ack commit (CRITICAL anti-sliming)" }
t8_1 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 1 (NO narrowing+logging; full Result[T] propagation)" }
t8_2 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 2" }
t8_3 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 3" }
t8_4 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 4" }
t8_5 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 5" }
t8_6 = { status = "pending", commit_sha = "", description = "Migrate UNCLEAR site 6" }
t8_7 = { status = "pending", commit_sha = "", description = "Add Phase 8 invariant test (silent_swallow_count_zero + unclear_count_zero); Phase 8 checkpoint" }
# Phase 9: ai_client Batch A (<=8 sites)
t9_0 = { status = "pending", commit_sha = "", description = "Phase 9 styleguide re-read + ack commit" }
t9_1 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 1" }
t9_2 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 2" }
t9_3 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 3" }
t9_4 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 4" }
t9_5 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 5" }
t9_6 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 6" }
t9_7 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 7" }
t9_8 = { status = "pending", commit_sha = "", description = "Migrate Batch A site 8" }
t9_9 = { status = "pending", commit_sha = "", description = "Add Phase 9 invariant test; Phase 9 checkpoint" }
# Phase 10: ai_client Batch B (<=8 sites)
t10_0 = { status = "pending", commit_sha = "", description = "Phase 10 styleguide re-read + ack commit" }
t10_1 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 1" }
t10_2 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 2" }
t10_3 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 3" }
t10_4 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 4" }
t10_5 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 5" }
t10_6 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 6" }
t10_7 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 7" }
t10_8 = { status = "pending", commit_sha = "", description = "Migrate Batch B site 8" }
t10_9 = { status = "pending", commit_sha = "", description = "Add Phase 10 invariant test; Phase 10 checkpoint" }
# Phase 11: ai_client silent-swallow (9 sites; CRITICAL anti-sliming)
t11_0 = { status = "pending", commit_sha = "", description = "Phase 11 styleguide re-read + ack commit (CRITICAL anti-sliming)" }
t11_1 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 1" }
t11_2 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 2" }
t11_3 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 3" }
t11_4 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 4" }
t11_5 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 5" }
t11_6 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 6" }
t11_7 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 7" }
t11_8 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 8" }
t11_9 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 9" }
t11_10 = { status = "pending", commit_sha = "", description = "Add Phase 11 invariant test; Phase 11 checkpoint" }
# Phase 12: ai_client rethrow classification (7 sites)
t12_0 = { status = "pending", commit_sha = "", description = "Phase 12 styleguide re-read (Re-Raise Patterns lines 625-690) + ack commit" }
t12_1 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 1" }
t12_2 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 2" }
t12_3 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 3" }
t12_4 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 4" }
t12_5 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 5" }
t12_6 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 6" }
t12_7 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 7" }
t12_8 = { status = "pending", commit_sha = "", description = "Add Phase 12 invariant test; Phase 12 checkpoint" }
# Phase 13: rag_engine migration (9 sites)
t13_0 = { status = "pending", commit_sha = "", description = "Phase 13 styleguide re-read + ack commit" }
t13_1 = { status = "pending", commit_sha = "", description = "Migrate broad-catch site 1" }
t13_2 = { status = "pending", commit_sha = "", description = "Migrate broad-catch site 2" }
t13_3 = { status = "pending", commit_sha = "", description = "Migrate broad-catch site 3" }
t13_4 = { status = "pending", commit_sha = "", description = "Migrate broad-catch site 4" }
t13_5 = { status = "pending", commit_sha = "", description = "Migrate broad-catch site 5" }
t13_6 = { status = "pending", commit_sha = "", description = "Migrate silent-swallow site 6" }
t13_7 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 7" }
t13_8 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 8" }
t13_9 = { status = "pending", commit_sha = "", description = "Classify or migrate rethrow site 9" }
t13_10 = { status = "pending", commit_sha = "", description = "Add Phase 13 invariant test; Phase 13 checkpoint" }
# Phase 14: Audit gate + end-of-track report (5 tasks)
t14_1 = { status = "pending", commit_sha = "", description = "Run audit --include-baseline --strict; verify exit 0" }
t14_2 = { status = "pending", commit_sha = "", description = "Run tests/test_baseline_result.py -v; verify all 102+ tests PASSED" }
t14_3 = { status = "pending", commit_sha = "", description = "Run scripts/run_tests_batched.py; verify 11/11 tiers PASS" }
t14_4 = { status = "pending", commit_sha = "", description = "Write docs/reports/TRACK_COMPLETION_result_migration_baseline_cleanup_20260620.md" }
t14_5 = { status = "pending", commit_sha = "", description = "Final checkpoint + tracks.md update + umbrella count update + campaign status 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
phase_14_complete = false
mcp_client_broad_catch_zero = false
mcp_client_silent_swallow_zero = false
mcp_client_unclear_zero = false
ai_client_broad_catch_zero = false
ai_client_silent_swallow_zero = false
ai_client_rethrow_zero = false
rag_engine_broad_catch_zero = false
rag_engine_silent_swallow_zero = false
rag_engine_rethrow_zero = false
audit_strict_exits_0 = false
batched_suite_11_of_11_pass = false
site_inventory_88_rows_total = false
all_102_plus_tests_pass = false
campaign_100_percent_complete = false