# Implementation Plan: Tier 4 Auto-Patching (tier4_auto_patching_20260306) > **Reference:** [Spec](./spec.md) | [Architecture Guide](../../../docs/guide_architecture.md) ## Phase 1: Patch Generation Focus: Generate unified diff on test failure - [x] Task 1.1: Initialize MMA Environment - [x] Task 1.2: Extend Tier 4 prompt for patch generation - WHERE: `src/mma_prompts.py` or inline in `ai_client.py` - WHAT: Prompt to generate unified diff - HOW: ```python TIER4_PATCH_PROMPT = """ Analyze the error and generate a unified diff patch to fix it. Output format: --- a/path/to/file.py +++ b/path/to/file.py @@ -line,count +line,count @@ context -removed line +added line context """ ``` - [x] Task 1.3: Add patch generation function - WHERE: `src/ai_client.py` - WHAT: Generate patch from error - HOW: ```python def run_tier4_patch_generation(error: str, file_context: str) -> str: prompt = TIER4_PATCH_PROMPT + f"\n\nError:\n{error}\n\nFiles:\n{file_context}" return send(prompt, model="gemini-2.5-flash-lite") ``` ## Phase 2: Diff Viewer UI Focus: Display side-by-side diff - [ ] Task 2.1: Parse unified diff - WHERE: `src/gui_2.py` or new `src/diff_viewer.py` - WHAT: Parse diff into hunks - HOW: ```python def parse_diff(diff_text: str) -> list[dict]: hunks = [] current_hunk = None for line in diff_text.split("\n"): if line.startswith("@@"): if current_hunk: hunks.append(current_hunk) current_hunk = {"header": line, "lines": []} elif current_hunk: current_hunk["lines"].append(line) if current_hunk: hunks.append(current_hunk) return hunks ``` - [ ] Task 2.2: Render diff viewer - WHERE: `src/gui_2.py` - WHAT: Color-coded diff display - HOW: ```python for hunk in hunks: for line in hunk["lines"]: if line.startswith("+"): imgui.text_colored(vec4(100, 255, 100, 255), line) elif line.startswith("-"): imgui.text_colored(vec4(255, 100, 100, 255), line) else: imgui.text(line) ``` ## Phase 3: Patch Application Focus: Apply patch with backup - [ ] Task 3.1: Create backup before apply - WHERE: `src/gui_2.py` or `src/mcp_client.py` - WHAT: Backup file to .backup - HOW: ```python import shutil backup_path = file_path.with_suffix(file_path.suffix + ".backup") shutil.copy(file_path, backup_path) ``` - [ ] Task 3.2: Apply patch - WHERE: `src/gui_2.py` - WHAT: Use patch command or difflib - HOW: ```python import subprocess result = subprocess.run(["patch", "-p1"], input=diff_text, capture_output=True, text=True) ``` - [ ] Task 3.3: Restore on failure - WHERE: `src/gui_2.py` - WHAT: Restore from backup if patch fails - HOW: `shutil.copy(backup_path, file_path)` ## Phase 4: Modal UI Focus: Approval modal for patches - [ ] Task 4.1: Create patch approval modal - WHERE: `src/gui_2.py` - WHAT: Modal with diff preview and Apply/Reject buttons - HOW: ```python if self._show_patch_modal: imgui.open_popup("Apply Patch?") if imgui.begin_popup_modal("Apply Patch?"): # Render diff if imgui.button("Apply"): self._apply_current_patch() imgui.close_current_popup() imgui.same_line() if imgui.button("Reject"): imgui.close_current_popup() imgui.end_popup() ``` ## Phase 5: Testing - [x] Task 5.1: Write unit tests - [x] Task 5.2: Conductor - Phase Verification