@startuml patcher-pipeline !theme plain title AI Patch Generation and Application Pipeline start :Receive source file + target file + instruction; :Build prompt with: - Source file diff (staged changes) - Source file full content - Target file current content - Generation instructions from rules; :Call AI via shell command (configured via git config or env); if (AI returned output?) then (yes) if (Output contains\n"API Error: Overloaded"?) then (yes) :Raise PatchGenerationError\n"Claude API is overloaded"; stop endif :Save raw output to\n.git/ai-rules-debug/*.raw.out; if (Output contains\n<<>>?) then (yes) :Extract content between\nSTART and END markers; else (no) if (Output contains\n"diff --git"?) then (yes) :Extract from\n"diff --git" onward; else (no) :Raise "AI output did not contain a diff"; stop endif endif else (no) :Raise "AI command failed"; stop endif :Save to *.clean.diff; :Sanitize patch: - Remove "index ..." lines - Remove "similarity index" lines - Keep only diff content; :Save to *.sanitized.diff; if (New file and missing\n"new file mode"?) then (yes) :Add "new file mode 100644" header; endif :Save to *.final.diff; if (Patch is empty?) then (yes) :Raise "AI returned empty patch"; stop endif :Try git apply -p1 --index --check; if (Check succeeded?) then (yes) :git apply -p1 --index; :Success!; stop endif :Try git apply -p1 --index --3way\n--recount --whitespace=nowarn; if (3-way succeeded?) then (yes) :Applied with 3-way merge; :Success!; stop endif if (Is new file?) then (yes) :Try git apply -p1 (without --index); if (Succeeded?) then (yes) :git add target file; :Success!; stop endif endif :Raise "Failed to apply patch\n(strict and 3-way both failed)"; stop note right **Debug Artifacts Location:** .git/ai-rules-debug/ Files saved: - *.raw.out (full AI response) - *.clean.diff (extracted patch) - *.sanitized.diff (cleaned patch) - *.final.diff (applied patch) Filename format: {output_path_with_underscores}-{pid}.{ext} end note @enduml