docs(track): enumerate Phase 10 target sites (26 SILENT_SWALLOW + 18 UNCLEAR)

Phase 10 enumerates the remaining sites from the post-Phase-9 audit:

26 SILENT_SWALLOW sites across 16 files needing full Result[T]
migration (not narrowing):
- aggregate.py (1), api_hooks.py (1), context_presets.py (1),
  external_editor.py (1), file_cache.py (1), log_registry.py (1),
  models.py (1), multi_agent_conductor.py (1), orchestrator_pm.py (2),
  outline_tool.py (2), project_manager.py (3), session_logger.py (4),
  startup_profiler.py (1), theme_2.py (1), warmup.py (5)
- Includes 4 io_pool callback sites (warmup.py:139/215/249 + hot_reloader.py:58)

18 UNCLEAR sites (4 original from Phase 2 + 14 new from Phase 3-8 narrowing):
- Original: outline_tool.py:49, summarize.py:36, conductor_tech_lead.py:120,
  openai_compatible.py:87
- New: aggregate.py:50/274/446, commands.py:116/147, diff_viewer.py:167,
  file_cache.py:84, markdown_helper.py:200, models.py:1081,
  multi_agent_conductor.py:517, project_manager.py:98,
  session_logger.py:188, shell_runner.py:99, summarize.py:187

Per-site list with file:line + context function name + migration strategy.
This commit is contained in:
ed
2026-06-17 22:26:38 -04:00
parent a160b753bb
commit 15b778485c
@@ -0,0 +1,94 @@
# Phase 10 Target Sites — Per-Site Enumeration
## Audit Source
`uv run python scripts/audit_exception_handling.py --json > audit_pre_phase10.json`
Generated after Phase 9 (current state). The 37-file scope (35 SMALL + 2 MEDIUM) is filtered.
## Site Counts
| Category | Count | Notes |
|---|---|---|
| `INTERNAL_SILENT_SWALLOW` | 26 | Narrow-catch + `pass` patterns. These need full `Result[T]` migration. (Spec estimated 27; off by 1 due to the `load_track_state` defensive fix already done in Phase 9.) |
| `UNCLEAR` | 18 | Includes 4 sites that were classified in Phase 2 (outline_tool.py:49, summarize.py:36, conductor_tech_lead.py:120, openai_compatible.py:87 — the original 4 UNCLEARs). The other 14 emerged from the Phase 3-8 narrowing strategy. |
## SILENT_SWALLOW Sites (26 total) — Phase 10.2 migration targets
| File | Line | Kind | Function context | Strategy |
|---|---|---|---|---|
| `src/aggregate.py` | 105 | EXCEPT | `stats` outer try | Full Result[T] migration |
| `src/api_hooks.py` | 914 | EXCEPT | websocket connection cleanup | Full Result[T] migration |
| `src/context_presets.py` | 16 | EXCEPT | `load_all_context_presets` | Full Result[T] migration |
| `src/external_editor.py` | 82 | EXCEPT | `_find_vscode_in_registry` subprocess.run | Full Result[T] migration |
| `src/file_cache.py` | 98 | EXCEPT | `_get_mtime` cache fallback | Full Result[T] migration |
| `src/log_registry.py` | 249 | EXCEPT | `_log_summary` stderr.write | Full Result[T] migration |
| `src/models.py` | 508 | EXCEPT | `from_dict` datetime.fromisoformat | Full Result[T] migration |
| `src/multi_agent_conductor.py` | 317 | EXCEPT | persona load fallback | Full Result[T] migration |
| `src/orchestrator_pm.py` | 37 | EXCEPT | track metadata.json read | Full Result[T] migration |
| `src/orchestrator_pm.py` | 49 | EXCEPT | track spec.md read | Full Result[T] migration |
| `src/outline_tool.py` | 90 | EXCEPT | ast.unparse ImGui context | Full Result[T] migration |
| `src/outline_tool.py` | 109 | EXCEPT | outer except in walk | Full Result[T] migration |
| `src/project_manager.py` | 366 | EXCEPT | `get_all_tracks` state.from_dict | Full Result[T] migration |
| `src/project_manager.py` | 378 | EXCEPT | `get_all_tracks` metadata.json read | Full Result[T] migration |
| `src/project_manager.py` | 393 | EXCEPT | `get_all_tracks` plan.md read | Full Result[T] migration |
| `src/session_logger.py` | 147 | EXCEPT | log_api_hook write | Full Result[T] migration |
| `src/session_logger.py` | 160 | EXCEPT | log_comms json.dump | Full Result[T] migration |
| `src/session_logger.py` | 201 | EXCEPT | log_tool_call write | Full Result[T] migration |
| `src/session_logger.py` | 245 | EXCEPT | log_cli_call write | Full Result[T] migration |
| `src/startup_profiler.py` | 40 | EXCEPT | `_end_phase` stderr.write | Full Result[T] migration |
| `src/theme_2.py` | 282 | EXCEPT | markdown_helper import + clear_cache | Full Result[T] migration |
| `src/warmup.py` | 139 | EXCEPT | `on_complete` callback fire | Full Result[T] migration (io_pool callback) |
| `src/warmup.py` | 215 | EXCEPT | `_record_success` callback fire | Full Result[T] migration (io_pool callback) |
| `src/warmup.py` | 249 | EXCEPT | `_record_failure` callback fire | Full Result[T] migration (io_pool callback) |
| `src/warmup.py` | 276 | EXCEPT | `_log_canary` stderr.write | Full Result[T] migration |
| `src/warmup.py` | 300 | EXCEPT | `_log_summary` stderr.write | Full Result[T] migration |
## UNCLEAR Sites (18 total) — Phase 10.3 heuristic targets
### Original 4 (Phase 2 already classified)
- `src/outline_tool.py:49` (Phase 2 decision: Migration-target)
- `src/summarize.py:36` (Phase 2 decision: Migration-target)
- `src/conductor_tech_lead.py:120` (Phase 2 decision: Compliant)
- `src/openai_compatible.py:87` (Phase 2 decision: Compliant)
### New 14 (emerged from Phase 3-8 narrowing)
- `src/aggregate.py:50` (EXCEPT — PureWindowsPath drive check)
- `src/aggregate.py:274` (EXCEPT — file read with traceback)
- `src/aggregate.py:446` (EXCEPT — AST skeleton fallback)
- `src/commands.py:116` (EXCEPT — generate_md)
- `src/commands.py:147` (EXCEPT — save_all)
- `src/diff_viewer.py:167` (EXCEPT — apply_patch)
- `src/file_cache.py:84` (EXCEPT — path mtime stat)
- `src/markdown_helper.py:200` (EXCEPT — render_table fallback)
- `src/models.py:1081` (EXCEPT — MCP config load)
- `src/multi_agent_conductor.py:517` (EXCEPT — file view injection)
- `src/project_manager.py:98` (EXCEPT — git rev-parse)
- `src/session_logger.py:188` (EXCEPT — log_tool_call script file write)
- `src/shell_runner.py:99` (EXCEPT — subprocess cleanup on error)
- `src/summarize.py:187` (EXCEPT — summarise_file fallback)
## io_pool Callback Sites (4 sites in Phase 10.2)
The warmup and hot_reloader paths use callback-based dispatch through `io_pool`. When a callback now returns `Result[T]`, the completion handler must check `result.ok` and thread the Result through:
- `src/warmup.py:139``on_complete` callback fire (in WarmupManager.on_complete())
- `src/warmup.py:215``_record_success` callback fire (in WarmupManager._record_success())
- `src/warmup.py:249``_record_failure` callback fire (in WarmupManager._record_failure())
- `src/hot_reloader.py:58``reload()` (in HotReloader.reload())
The current pattern: callback returns None (silent swallow). After migration:
- Callback signature: `def callback(result: Result[Snapshot]) -> None`
- The wrapper `try: callback(...) except SomeError as e: ...` becomes the wrapper
- The completion handler iterates over callbacks and threads the Result
## Summary
| Metric | Pre-Phase-10 |
|---|---|
| Files needing migration | 16 |
| Sites to migrate to Result[T] | 26 |
| New audit heuristics needed | 2-3 |
| Audit reclassification target | 14 new UNCLEAR → INTERNAL_COMPLIANT or BOUNDARY_* |
| io_pool callback sites to thread Result | 4 |
| Estimated per-file sites | 1-3 sites per file |
The 4 original UNCLEAR sites (outline_tool.py:49, summarize.py:36, conductor_tech_lead.py:120, openai_compatible.py:87) were classified in Phase 2; conductor_tech_lead.py:120 and openai_compatible.py:87 stay as-is (Compliant), and outline_tool.py:49 + summarize.py:36 are migration-targets and will be covered by Phase 10.2's outline_tool.py and summarize.py migrations.