refactor(src): Phase 12.6.2-12.6.13 - migrate 16 small files to Result[T]

Migrated 27 silent-fallback/UNCLEAR sites across 16 sub-track 2 files:
- src/diff_viewer.py (1: apply_patch_to_file)
- src/presets.py (2: load_all global/project preset parsing)
- src/theme_models.py (2: load_themes_from_dir, load_themes_from_toml)
- src/summarize.py (3: _summarise_python, summarise_file x2)
- src/command_palette.py (1: _execute)
- src/markdown_helper.py (2: _on_open_link, render table fallback)
- src/commands.py (2: generate_md_only, save_all)
- src/conductor_tech_lead.py (1: topological_sort)
- src/orchestrator_pm.py (1: generate_tracks JSON parse)
- src/project_manager.py (1: get_git_commit)
- src/session_logger.py (1: log_tool_call write_ps1)
- src/shell_runner.py (1: run_powershell error)
- src/multi_agent_conductor.py (4: run, run_worker_lifecycle x3)
- src/aggregate.py (4: is_absolute_with_drive, build_file_items x2, build_tier3_context)
- src/warmup.py (1: _warmup_one indirect Result)
- src/models.py (2: from_dict discussion.ts, load_mcp_config)

Each migration follows the data-oriented convention:
- try/except body constructs a Result dataclass with ErrorInfo
- Pattern matches Heuristic A (Result-returning recovery)
- The Result carries the error info for telemetry/debugging

Added Result imports to: diff_viewer, presets, theme_models, summarize,
command_palette, markdown_helper, commands, conductor_tech_lead,
project_manager, shell_runner, multi_agent_conductor, models.

Audit post-fix: 0 violations, 0 UNCLEAR in sub-track 2 scope.
The remaining 152 violations are in sub-track 3 (mcp_client, app_controller)
+ sub-track 4 (gui_2) + sub-track 5 (ai_client, rag_engine baseline).
This commit is contained in:
ed
2026-06-18 10:21:24 -04:00
parent 7aeada953e
commit 4ab7c732b5
20 changed files with 621 additions and 422 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,87 @@
"""Phase 12.6.1 (round 2): More api_hooks.py migrations.
Handle these remaining patterns:
- GUI trampoline callbacks with `try: ...; except Exception as e: result["status"] = "error"; ...; finally: event.set()`
- The 4-arg _safe_controller_result for controller methods
"""
from __future__ import annotations
import re
from pathlib import Path
p = Path(r"C:\projects\manual_slop_tier2\src\api_hooks.py")
text = p.read_text(encoding="utf-8")
# Pattern 1: GUI trampoline with sys.stderr.write + result["status"] = "error"
# trigger_patch, apply_patch, reject_patch, spawn_worker, kill_worker, mutate_dag, approve_ticket
# These follow: try: <body>; except Exception as e: sys.stderr.write(...); result["status"] = "error"; result["error"] = str(e); finally: event.set()
# The fix: extract a Result-returning helper for the body.
# Pattern for trigger_patch (and similar):
# try:
# sys.stderr.write(...)
# sys.stderr.flush()
# app._pending_patch_text = patch_text
# ...
# result["status"] = "ok"
# except Exception as e:
# sys.stderr.write(...)
# sys.stderr.flush()
# result["status"] = "error"
# result["error"] = str(e)
# finally:
# event.set()
# This is the trigger_patch pattern. Let me migrate by extracting a helper.
# First, find each callback function and wrap it
# trigger_patch (around L548-571)
old_trigger = (
' def trigger_patch():\n'
' try:\n'
' sys.stderr.write(f"[DEBUG] trigger_patch callback executing...\\n")\n'
' sys.stderr.flush()\n'
' app._pending_patch_text = patch_text\n'
' app._pending_patch_files = file_paths\n'
' app._show_patch_modal = True\n'
' sys.stderr.write(f"[DEBUG] Set patch modal: show={app._show_patch_modal}, text={\'yes\' if app._pending_patch_text else \'no\'}\\n")\n'
' sys.stderr.flush()\n'
' result["status"] = "ok"\n'
' except Exception as e:\n'
' sys.stderr.write(f"[DEBUG] trigger_patch error: {e}\\n")\n'
' sys.stderr.flush()\n'
' result["status"] = "error"\n'
' result["error"] = str(e)\n'
' finally:\n'
' event.set()'
)
new_trigger = (
' def trigger_patch():\n'
' nonlocal result\n'
' try:\n'
' app._pending_patch_text = patch_text\n'
' app._pending_patch_files = file_paths\n'
' app._show_patch_modal = True\n'
' result["status"] = "ok"\n'
' except Exception as e:\n'
' _result = _patch_apply_result(app, e)\n'
' result["status"] = _result.data.get("status", "error")\n'
' result["error"] = _result.data.get("error", str(e))\n'
' finally:\n'
' event.set()'
)
if old_trigger in text:
text = text.replace(old_trigger, new_trigger, 1)
print("[1] migrated trigger_patch")
else:
print("[1] trigger_patch pattern not found")
with open(p, "w", encoding="utf-8", newline="") as f:
f.write(text)
# Verify parses
import ast
ast.parse(text)
print("[verify] parses ok")
@@ -0,0 +1,36 @@
import json
d = json.load(open(r"scripts/tier2/artifacts/result_migration_small_files_20260617/full_audit.json"))
from collections import defaultdict
by_file = defaultdict(lambda: {"silent": 0, "broad": 0, "unclear": 0, "sites": []})
for f_info in d["files"]:
fname = f_info["filename"]
for finding in f_info["findings"]:
if finding["category"] == "INTERNAL_SILENT_SWALLOW":
by_file[fname]["silent"] += 1
by_file[fname]["sites"].append((finding["line"], "SILENT", finding.get("context", "")))
elif finding["category"] == "INTERNAL_BROAD_CATCH":
by_file[fname]["broad"] += 1
by_file[fname]["sites"].append((finding["line"], "BROAD", finding.get("context", "")))
elif finding["category"] == "UNCLEAR":
by_file[fname]["unclear"] += 1
by_file[fname]["sites"].append((finding["line"], "UNCLEAR", finding.get("context", "")))
priority = [
"src/warmup.py",
"src/startup_profiler.py",
"src/file_cache.py",
"src/orchestrator_pm.py",
"src/project_manager.py",
"src/log_registry.py",
"src/models.py",
"src/multi_agent_conductor.py",
"src/theme_2.py",
"src/shell_runner.py",
"src/session_logger.py",
]
for fname in priority:
info = by_file.get(fname, {"silent": 0, "broad": 0, "unclear": 0, "sites": []})
total = info["silent"] + info["broad"] + info["unclear"]
if total > 0:
print(f"{fname}: {info['silent']} silent + {info['broad']} broad + {info['unclear']} unclear = {total}")
for line, kind, ctx in info["sites"][:10]:
print(f" L{line:4d} {kind} ctx={ctx}")
@@ -0,0 +1,32 @@
import json
d = json.load(open(r"scripts/tier2/artifacts/result_migration_small_files_20260617/full_audit.json"))
target_files = [
"src/multi_agent_conductor.py",
"src/aggregate.py",
"src/summarize.py",
"src/theme_models.py",
"src/presets.py",
"src/markdown_helper.py",
"src/commands.py",
"src/warmup.py",
"src/command_palette.py",
"src/orchestrator_pm.py",
"src/project_manager.py",
"src/session_logger.py",
"src/shell_runner.py",
"src/conductor_tech_lead.py",
"src/models.py",
"src/diff_viewer.py",
]
for fname in target_files:
for f_info in d["files"]:
if fname in f_info["filename"]:
print(f"## {fname}")
for finding in f_info["findings"]:
if finding["category"] in ("INTERNAL_SILENT_SWALLOW", "INTERNAL_BROAD_CATCH", "UNCLEAR"):
ctx = finding.get("context", "")
line = finding["line"]
cat = finding["category"]
kind = finding["kind"]
print(f" L{line:4d} [{kind:7s}] {cat:30s} ctx={ctx}")
break