# 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).