# Lessons ## 2026-05-30 — Release verifizieren BEVOR "fertig" gesagt wird; curl -F mit Leerzeichen im Pfad **Muster A (Edit ins Leere + trotzdem released):** Ein Edit schlug fehl ("String not found"), ich habe es übersehen, committet und v1.7.165 released — die Datei enthielt das Feature NICHT. Erst der nächste Blick zeigte es. **Regel:** Nach jedem Feature-Edit VOR dem Release `git show HEAD:datei | grep ` — bestätigen dass der Code wirklich im Release-Commit ist, nicht nur dass `git commit` durchlief. **Muster B (Gitea UNIQUE constraint):** `npm run release:gitea` pusht erst den Tag, dann erstellt es den Release. Gitea legt beim Tag-Push automatisch einen Tag-Release- Eintrag an (name=null). `fetchExistingRelease` im Script matcht den nicht → POST create → `UNIQUE constraint failed: release.repo_id, release.tag_name`. Commit + Tag sind dann schon gepusht, nur der Release+Assets fehlen. **Recovery:** `GET /api/v1/repos/.../releases/tags/` → id holen → `PATCH releases/` mit name/body/draft:false → Assets per `POST releases//assets?name=` hochladen. **Muster C (curl -F Datei mit Leerzeichen):** `curl -F "attachment=@release/Datei mit Leerzeichen.exe.blockmap"` lädt FALSCHEN Inhalt hoch (Server-Size != lokale Size). **Regel:** Datei mit Leerzeichen im Namen erst nach `/tmp/leerzeichenfrei` kopieren, DAS hochladen, Asset-Name über `?name=` setzen. Danach Server-Size gegen lokale Size prüfen. ## 2026-05-30 — Nicht in chaotische Parallel-Tool-Batches verfallen (User-Korrektur: "bist du in nem endless loop") **Muster:** Bei einem großen Multi-File-Edit habe ich Dutzende Tool-Calls (Bash-Probes, Reads, Edits, Python-Inline-Skripte, mehrfache tsc-Läufe) in EINEN Message-Block gepackt. Resultat: Ein einzelner Fehler/Cancel hat die ganze parallele Kette abgebrochen, Edits landeten halb, ich verlor den Überblick welche Änderung wirklich auf Disk war, und es wirkte wie eine Endlosschleife. Dazu: wegwerf-`scripts/_*.py`/`_*.txt` als Workaround gegen Output-Encoding statt der dedizierten Tools. **Regel:** - Edits über mehrere Dateien **sequenziell, einer nach dem anderen**, mit kurzer Verifikation dazwischen — nicht 20 spekulative Calls auf einmal. - Nach jedem Edit, der fehlschlagen kann (Anchor evtl. nicht eindeutig), das Ergebnis lesen, bevor der nächste folgt. Edit/Write erroren laut — darauf vertrauen. - KEINE Wegwerf-Python-Skripte ins Repo schreiben, um Shell-Output zu parsen. `Grep`/ `Read`/`Edit` nutzen. Wenn doch ein Temp nötig ist: nach `os.tmpdir()`, nie nach `scripts/`, und sofort wieder löschen. - Verifikation gebündelt am ENDE (1× tsc, 1× build, 1× vitest), nicht 10× zwischendrin. ## 2026-05-28 — Analyse-Befund gegen beobachtete Realität gaten (Advisor-Korrektur) **Muster:** Meine Analyse sagte einen *häufigen* Bug voraus (jede letzte Datei im Standard-Modus + jede Nested-Datei landet unbenannt), während der User nur "1-2 pro Staffel" meldete. Ich habe die Diskrepanz bemerkt ("zu schwer um unbemerkt zu bleiben") und sie mit weiterem Timing-Argument wegrationalisiert. **Regel:** Wenn die eigene Analyse etwas vorhersagt, das der beobachteten Realität widerspricht, NICHT die bequeme Lesart wählen — **mit einem Reproduktions-Test gaten**, bevor man fixt. Failing Test gegen den Ist-Stand zuerst (TDD/systematic-debugging Phase 4): - reproduziert → Bug bestätigt, mit Sicherheit fixen. - reproduziert nicht → Analyse hat eine Mitigation übersehen, kein Fix für Nicht-Bug. ## 2026-05-28 — Crash-Debris im Working Tree: stashen, nicht verwerfen **Muster:** Eine abgestürzte Session (API 400) hinterließ ein uncommittetes Working Tree, das drei releaste Commits revertierte. Verlockung: `git checkout`/discard, um clean HEAD zu bekommen. **Regel:** Fremde/unverstandene uncommittete Änderungen **`git stash`** (non-destruktiv, recoverable), nie blind verwerfen. Gibt clean HEAD, nichts geht verloren, kein Stall auf User-Rückfrage. Danach dem User sagen WAS gestasht wurde und WARUM. ## Wiring-Lock vs. Mechanism-Test Ein Test, der eine Hilfsfunktion mit dem richtigen Flag direkt aufruft, beweist nur, dass das Flag funktioniert — NICHT, dass der Produktionspfad das Flag setzt. Für echte Absicherung einen End-to-End-Test durch den realen Einstiegspunkt fahren und per Negativ-Gate (Flag temporär entfernen → Test muss fallen) verifizieren.