bugfix-protocol · diff

v1.0.0 to v1.0.0

163 added, 165 removed. Audit A to A.

---
name: bugfix-protocol
version: 1.0.0
type: protocol
author: Lukas Geiger
created: 2026-03-12
updated: 2026-03-12
description: Systematic 6-phase debugging protocol. Structured approach to bugs with quick checks, isolated testing, 20-minute rule, and bug report template.
standalone: true
anthropic_compatible: true
bach_compatible: false
bach_origin: true
category: dev
tags: [debugging, bugfix, protocol, python, pyqt6, systematic]
language: de
status: active
visibility: public
dependencies: {'tools': [], 'services': [], 'protocols': [], 'python': []}
provenance: {'origin': 'bach', 'origin_path': 'system/skills/workflows/bugfix-protokoll.md', 'origin_version': '1.0.0', 'origin_repo': 'github.com/ellmos-ai/bach', 'last_sync_from_origin': '2026-03-12', 'last_sync_to_origin': None, 'local_changes_since_sync': True}
---
-
<img src="banner.png" width="100%" alt="bugfix-protocol banner">
- > **Deutsch** — Offizielle Deutsch-Version / Documento Oficial en Deutsch.
-
-
- # Bugfix Protocol: Systematic 6-Phase Debugging (Deutsch)
+ # Bugfix-Protokoll: Systematisches 6-Phasen Debugging
- A structured approach to bugs — from symptom analysis to verification.
- Prevents aimless trial-and-error and ensures fixes are sustainable.
+ Strukturiertes Vorgehen bei Bugs — von der Symptom-Analyse bis zur Verifikation.
+ Verhindert planloses Herumprobieren und stellt sicher, dass Fixes nachhaltig sind.
---
- ## Übersicht & Zweck
+ ## Uebersicht
- | Phase | Name | Goal | Max. Time |
+ | Phase | Name | Ziel | Max. Zeit |
|-------|------|------|-----------|
- | 1 | Quick Checks | Rule out obvious causes | 2 min |
- | 2 | Diagnosis | Locate root cause | 10 min |
- | 3 | Isolated Test | Make bug reproducible | 5 min |
- | 4 | Fix | Minimal correction | 10 min |
- | 5 | Verification | Verify fix + check side effects | 5 min |
- | 6 | Documentation | Preserve knowledge | 2 min |
+ | 1 | Schnell-Checks | Offensichtliche Ursachen ausschliessen | 2 min |
+ | 2 | Diagnose | Ursache lokalisieren | 10 min |
+ | 3 | Isolierter Test | Bug reproduzierbar machen | 5 min |
+ | 4 | Fix | Minimale Korrektur | 10 min |
+ | 5 | Verifikation | Fix pruefen + Seiteneffekte | 5 min |
+ | 6 | Dokumentation | Wissen sichern | 2 min |
- **20-Minute Rule:** If no progress after 20 minutes, change approach or seek help.
+ **20-Minuten-Regel:** Wenn nach 20 Minuten kein Fortschritt → Ansatz wechseln oder Hilfe holen.
---
- ## Phase 1: Quick Checks (2 min)
+ ## Phase 1: Schnell-Checks (2 min)
- Before diving deep — check the most common causes:
+ Bevor du tief einsteigst — pruefe die haeufigsten Ursachen:
- ### Checklist
+ ### Checkliste
- - [ ] **Syntax error?** Read error message carefully, check line
- - [ ] **Import error?** Module installed? Correct name? Circular import?
- - [ ] **Typo?** Variable/function names correct?
- - [ ] **Wrong data type?** String instead of int? None where object expected?
- - [ ] **Stale cache?** Delete `__pycache__`, restart
- - [ ] **Wrong environment?** Correct venv active? Correct Python version?
- - [ ] **Encoding?** UTF-8 vs. cp1252 (Windows classic)
+ - [ ] **Syntax-Fehler?** Fehlermeldung genau lesen, Zeile pruefen
+ - [ ] **Import-Fehler?** Modul installiert? Richtiger Name? Circular Import?
+ - [ ] **Tippfehler?** Variablen-/Funktionsnamen korrekt?
+ - [ ] **Falscher Datentyp?** String statt Int? None wo Objekt erwartet?
+ - [ ] **Veralteter Cache?** `__pycache__` loeschen, Neustart
+ - [ ] **Falsche Umgebung?** Richtiges venv aktiv? Richtige Python-Version?
+ - [ ] **Encoding?** UTF-8 vs. cp1252 (Windows-Klassiker)
- ### Quick Actions
+ ### Schnell-Aktionen
```bash
- # Clear cache (Deutsch)
+ # Cache leeren
find . -name "__pycache__" -type d -exec rm -rf {} + 2>&1
find . -name "*.pyc" -delete 2>&1
- # Check imports (Deutsch)
- python -c "import modulename"
+ # Imports pruefen
+ python -c "import modulname"
- # Check syntax (Deutsch)
- python -m py_compile file.py
+ # Syntax pruefen
+ python -m py_compile datei.py
```
---
- ## Phase 2: Diagnosis (10 min)
+ ## Phase 2: Diagnose (10 min)
- ### Strategy: Outside-In
+ ### Strategie: Von aussen nach innen
- 1. **Analyze error message** — Read traceback from bottom to top
- 2. **Check recent changes** — `git diff`, `git log --oneline -10`
- 3. **Use diagnostic tools** — Use project-specific diagnostic tools
+ 1. **Fehlermeldung analysieren** — Traceback von unten nach oben lesen
+ 2. **Letzte Aenderungen pruefen** — `git diff`, `git log --oneline -10`
+ 3. **Diagnose-Tools einsetzen** — Eigene Diagnose-Tools je nach Projekt verwenden
- ### Diagnostic Tools (Examples)
+ ### Diagnose-Tools (Beispiele)
- Depending on the project, specialized diagnostic scripts may be helpful:
+ Je nach Projekt koennen spezialisierte Diagnose-Skripte hilfreich sein:
- | Tool | Purpose |
- |------|---------|
- | `import_diagnose.py` | Analyze import problems |
- | `method_analyzer.py` | Check method signatures |
- | `env_checker.py` | Validate environment variables/paths |
+ | Tool | Zweck |
+ |------|-------|
+ | `import_diagnose.py` | Import-Probleme analysieren |
+ | `method_analyzer.py` | Methoden-Signaturen pruefen |
+ | `env_checker.py` | Umgebungsvariablen/Pfade validieren |
- > **Note:** Create project-specific diagnostic tools or use existing ones.
- > The systematic approach matters, not the specific tool.
+ > **Hinweis:** Eigene Diagnose-Tools je nach Projekt erstellen oder vorhandene
+ > Projekt-Tools nutzen. Wichtig ist das systematische Vorgehen, nicht das
+ > spezifische Tool.
- ### Debugging Techniques
+ ### Debugging-Techniken
```python
- # 1. Print debugging (quick but effective) (Deutsch)
+ # 1. Print-Debugging (schnell aber effektiv)
print(f"DEBUG: variable={variable!r}, type={type(variable)}")
- # 2. Breakpoint (interactive) (Deutsch)
+ # 2. Breakpoint (interaktiv)
breakpoint() # Python 3.7+
- # 3. Extended traceback (Deutsch)
+ # 3. Traceback erweitern
import traceback
traceback.print_exc()
- # 4. Logging instead of print (Deutsch)
+ # 4. Logging statt Print
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug(f"State: {state!r}")
```
---
- ## Phase 3: Isolated Test (5 min)
+ ## Phase 3: Isolierter Test (5 min)
### Minimal Reproducible Example (MRE)
- Goal: Reproduce the bug with minimal code.
+ Ziel: Bug mit minimal Code reproduzieren.
```python
- # test_bug.py — Minimal Reproduction Test (Deutsch)
+ # test_bug.py — Minimaler Reproduktions-Test
"""
- Bug: [Short description]
- Expected: [What should happen]
- Actual: [What happens instead]
+ Bug: [Kurze Beschreibung]
+ Erwartet: [Was sollte passieren]
+ Tatsaechlich: [Was passiert stattdessen]
"""
- # Minimal setup (Deutsch)
- # ... only the essentials (Deutsch)
+ # Minimaler Setup
+ # ... nur das Noetigste
- # Bug trigger (Deutsch)
- # ... exact code that triggers the bug (Deutsch)
+ # Bug-Ausloeser
+ # ... exakter Code der den Bug triggert
- # Expected result (Deutsch)
- # assert result == expected, f"Got {result}" (Deutsch)
+ # Erwartetes Ergebnis
+ # assert result == expected, f"Got {result}"
```
- ### Isolation Strategies
+ ### Isolations-Strategien
- 1. **New file:** Reproduce the bug in a separate file
- 2. **Remove dependencies:** One by one, until the bug disappears
- 3. **Binary search:** Halve the code block, check which half contains the bug
- 4. **Git bisect:** `git bisect start`, `git bisect bad`, `git bisect good <commit>`
+ 1. **Neue Datei:** Bug in eigener Datei reproduzieren
+ 2. **Abhaengigkeiten entfernen:** Eine nach der anderen, bis Bug verschwindet
+ 3. **Halbieren:** Code-Block halbieren, pruefen welche Haelfte den Bug enthaelt
+ 4. **Git Bisect:** `git bisect start`, `git bisect bad`, `git bisect good <commit>`
---
## Phase 4: Fix (10 min)
- ### Principles
+ ### Prinzipien
- 1. **Minimal:** Change as little as possible
- 2. **Understand:** Never fix blindly — understand WHY it's broken
- 3. **One thing:** One fix per commit, don't fix multiple issues at once
- 4. **Backward-compatible:** Don't break existing functionality
+ 1. **Minimal:** Aendere so wenig wie moeglich
+ 2. **Verstehen:** Nie blind fixen — verstehe WARUM es kaputt ist
+ 3. **Eine Sache:** Ein Fix pro Commit, nicht mehrere Probleme gleichzeitig
+ 4. **Rueckwaerts-kompatibel:** Bestehende Funktionalitaet nicht brechen
- ### Fix Patterns
+ ### Fix-Muster
```python
- # BAD: Treating the symptom (Deutsch)
+ # SCHLECHT: Symptom behandeln
try:
result = broken_function()
- except: # Swallow everything
+ except: # Alles schlucken
result = default_value
- # GOOD: Fix the root cause (Deutsch)
+ # GUT: Ursache beheben
def broken_function():
- if input_data is None: # Actual cause: missing None check
+ if input_data is None: # Eigentliche Ursache: None-Check fehlte
return default_value
return process(input_data)
```
- ### Common Fix Categories
+ ### Haeufige Fix-Kategorien
- | Category | Typical Fix |
- |----------|------------|
- | None/Null | Guard clause: `if x is None: return default` |
- | Index error | Bounds check: `if i < len(lst)` |
- | Type error | Explicit conversion: `str(x)`, `int(x)` |
- | Import error | Fix path, install package |
- | Encoding | Specify UTF-8 explicitly: `encoding='utf-8'` |
- | Race condition | Lock/Mutex, or change order |
- | State bug | Check initialization, add reset |
+ | Kategorie | Typischer Fix |
+ |-----------|--------------|
+ | None/Null | Guard-Clause: `if x is None: return default` |
+ | Index-Fehler | Bounds-Check: `if i < len(lst)` |
+ | Type-Fehler | Explizite Konvertierung: `str(x)`, `int(x)` |
+ | Import-Fehler | Pfad korrigieren, Paket installieren |
+ | Encoding | UTF-8 explizit angeben: `encoding='utf-8'` |
+ | Race Condition | Lock/Mutex, oder Reihenfolge aendern |
+ | State-Bug | Initialisierung pruefen, Reset einfuegen |
---
- ## Phase 5: Verification (5 min)
+ ## Phase 5: Verifikation (5 min)
- ### Checklist
+ ### Checkliste
- - [ ] **Bug is fixed:** Original problem no longer occurs
- - [ ] **MRE passes:** Isolated test runs through
- - [ ] **No regression:** Existing tests still pass
- - [ ] **Edge cases:** Empty input, None, large data tested
- - [ ] **Project tools:** Check project tools directory for relevant test/validation tools
+ - [ ] **Bug ist gefixt:** Originales Problem tritt nicht mehr auf
+ - [ ] **MRE besteht:** Isolierter Test laeuft durch
+ - [ ] **Keine Regression:** Bestehende Tests laufen noch
+ - [ ] **Edge Cases:** Leere Eingabe, None, grosse Daten getestet
+ - [ ] **Projekt-Tools:** Im Projekt-Tools-Verzeichnis nachschauen ob es relevante Test-/Validierungstools gibt
- ### Test Commands
+ ### Test-Befehle
```bash
- # Unit tests (Deutsch)
+ # Unit-Tests
python -m pytest tests/ -v
- # Only affected tests (Deutsch)
- python -m pytest tests/test_module.py -v -k "test_name"
+ # Nur betroffene Tests
+ python -m pytest tests/test_modul.py -v -k "test_name"
- # Type check (Deutsch)
- python -m mypy file.py
+ # Type-Check
+ python -m mypy datei.py
- # Lint (Deutsch)
- python -m flake8 file.py
+ # Lint
+ python -m flake8 datei.py
```
---
- ## Phase 6: Documentation (2 min)
+ ## Phase 6: Dokumentation (2 min)
- ### Bug Report Template
+ ### Bug-Report Template
```markdown
- ## Bug Report: [Short Title]
+ ## Bug-Report: [Kurztitel]
- **Date:** YYYY-MM-DD
- **Severity:** critical / high / medium / low
- **Component:** [Module/File]
+ **Datum:** YYYY-MM-DD
+ **Schwere:** kritisch / hoch / mittel / niedrig
+ **Komponente:** [Modul/Datei]
### Symptom
- [What the user sees / error message]
+ [Was der User sieht / Fehlermeldung]
- ### Root Cause
- [Technical root cause]
+ ### Ursache
+ [Technische Root-Cause]
### Fix
- [What was changed + why]
+ [Was geaendert wurde + warum]
- ### Affected Files
- - `file1.py` — [Change]
- - `file2.py` — [Change]
+ ### Betroffene Dateien
+ - `datei1.py` — [Aenderung]
+ - `datei2.py` — [Aenderung]
- ### Prevention
- [How can this type of bug be prevented in the future?]
+ ### Praevention
+ [Wie kann dieser Bug-Typ in Zukunft vermieden werden?]
```
- ### Commit Message Format
+ ### Commit-Message Format
```
- fix: [Short description of the fix]
+ fix: [Kurze Beschreibung des Fixes]
- Cause: [Root cause in one sentence]
- Fix: [What was changed]
- Test: [How verified]
+ Ursache: [Root-Cause in einem Satz]
+ Fix: [Was geaendert wurde]
+ Test: [Wie verifiziert]
```
---
- ## PyQt6 / GUI Debugging — Common Pitfalls
+ ## PyQt6 / GUI Debugging — Haeufige Fallen
- > This section is relevant for desktop GUI projects with PyQt6/PySide6.
+ > Diese Sektion ist relevant fuer Desktop-GUI-Projekte mit PyQt6/PySide6.
### Top 5 PyQt6 Traps
- | Trap | Problem | Solution |
+ | Trap | Problem | Loesung |
|------|---------|---------|
- | **Signal-Slot Disconnect** | Signal connected but handler doesn't run | `print` in handler, check signature |
- | **Thread Safety** | GUI update from worker thread | `QMetaObject.invokeMethod` or use signal |
- | **Layout Cascade** | Widget invisible/misplaced | `widget.show()`, check layout hierarchy |
- | **Event Loop Block** | GUI freezes | Move long operations to QThread |
- | **Garbage Collection** | Widget suddenly disappears | Keep reference as `self.widget` |
+ | **Signal-Slot Disconnect** | Signal connected aber Handler laeuft nicht | `print` in Handler, Signature pruefen |
+ | **Thread-Safety** | GUI-Update aus Worker-Thread | `QMetaObject.invokeMethod` oder Signal nutzen |
+ | **Layout-Cascade** | Widget unsichtbar/falsch platziert | `widget.show()`, Layout-Hierarchie pruefen |
+ | **Event-Loop Block** | GUI friert ein | Langzeit-Ops in QThread auslagern |
+ | **Garbage Collection** | Widget verschwindet ploetzlich | Referenz als `self.widget` halten |
- ### PyQt6 Debug Helpers
+ ### PyQt6 Debug-Helfer
```python
- # Dump widget hierarchy (Deutsch)
+ # Widget-Hierarchie ausgeben
def dump_widget_tree(widget, indent=0):
print(" " * indent + f"{widget.__class__.__name__}: {widget.objectName()}")
for child in widget.findChildren(QWidget):
if child.parent() == widget:
dump_widget_tree(child, indent + 2)
- # Signal debugging (Deutsch)
+ # Signal-Debugging
from PyQt6.QtCore import QObject
original_connect = QObject.connect
def debug_connect(self, *args, **kwargs):
print(f"CONNECT: {self.__class__.__name__} -> {args}")
return original_connect(self, *args, **kwargs)
```
---
## Quick Reference
```
- BUG FOUND?
- |
- v
- [Phase 1: Quick Checks] ──── Obvious? -> FIX
- |
- v
- [Phase 2: Diagnosis] ────────── Cause clear? -> Phase 4
- |
- v
- [Phase 3: Isolated Test] ── Reproducible? -> Phase 4
- | |
- | Not reproducible?
- | |
- | Add logging,
- | wait for recurrence
- v
- [Phase 4: Fix] ─────────────── Minimal + understood
- |
- v
- [Phase 5: Verification] ────── Tests green? -> Phase 6
- | |
- | Tests red? -> Back to Phase 4
- v
- [Phase 6: Documentation] ───── Bug report + commit
+ BUG GEFUNDEN?
+ │
+ ▼
+ [Phase 1: Schnell-Checks] ──── Offensichtlich? → FIX
+ │
+ ▼
+ [Phase 2: Diagnose] ────────── Ursache klar? → Phase 4
+ │
+ ▼
+ [Phase 3: Isolierter Test] ── Reproduzierbar? → Phase 4
+ │ │
+ │ Nicht reproduzierbar?
+ │ │
+ │ Logging einbauen,
+ │ auf erneutes Auftreten warten
+ ▼
+ [Phase 4: Fix] ─────────────── Minimal + verstanden
+ │
+ ▼
+ [Phase 5: Verifikation] ────── Tests gruen? → Phase 6
+ │ │
+ │ Tests rot? → Zurueck zu Phase 4
+ ▼
+ [Phase 6: Dokumentation] ───── Bug-Report + Commit
```
- ### 20-Minute Rule
+ ### 20-Minuten-Regel
- If you're stuck after 20 minutes:
+ Wenn du nach 20 Minuten festhaengst:
- 1. **Change approach** — Try a different debugging technique
- 2. **Rubber duck** — Explain the problem out loud (or write it down)
- 3. **Take a break** — Step away for 5 minutes, return with fresh eyes
- 4. **Get help** — Ask a colleague, Stack Overflow, documentation
- 5. **Reset** — `git stash`, start completely fresh
+ 1. **Ansatz wechseln** — Andere Debugging-Technik probieren
+ 2. **Rubber Duck** — Problem laut erklaeren (oder aufschreiben)
+ 3. **Pause** — 5 Minuten weggehen, dann mit frischem Blick
+ 4. **Hilfe holen** — Kollege fragen, Stack Overflow, Dokumentation
+ 5. **Zuruecksetzen** — `git stash`, komplett neu anfangen
+