# Fallstricke und Erkenntnisse Gemeinsames Gedächtnis: Dinge, die man **nicht aus dem Code ablesen kann** und die schon einmal Zeit gekostet haben. Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik. Veraltetes löschen, nicht auskommentieren. ## BPMN und PICTURE (Skill sn-bpmn, md_to_bpmn.py) - **Vorschau und PICTURE können sich unterscheiden, auch ohne Fehler im Modell.** Beispiel XOR-Gateway: PICTURE zeichnet das „X“ nach eigenen Regeln, auch ohne `isMarkerVisible`. Die Vorschau (bpmn-js) hält sich an das Attribut und zeigte ohne es leere Rauten. Seit #15 setzt der Konverter das Attribut, beide zeigen das X. Wirkt etwas nur in der Vorschau falsch, erst in PICTURE gegenprüfen, bevor der Konverter geändert wird. (PICTURE 2026.4.1, #15, 25.09.2026) - **Gateway → Gateway mit Ziel „hinter“ dem Start-Stub braucht einen seitlichen Umweg.** Liegt der Stub des Start-Gateways schon jenseits des Ziel-Anschlusspunkts (z. B. Südpunkt unten, Ziel höher mit Nordpunkt), läuft das letzte gerade Stück durch die Ziel-Raute. `orthogonal_points()` weicht dann über `_ausweichachse()` aus. Die Achse liegt **im Gang direkt vor der Ziel-Spalte** (Abstand 85 zur Mitte), **nicht in der Mitte zwischen Quelle und Ziel**: Liegen die beiden zwei Spalten auseinander, steht dort eine Aufgabe (im Referenzmodell S43). (#8, 25.09.2026) - **Bekannte Layoutfehler je Kreuzung als xfail, nie je Modell.** Stünde ein ganzes Modell auf `xfail`, bliebe jede neue Kreuzung darin unsichtbar, solange der alte Fehler besteht. Deshalb prüft `test_keine_unbekannte_kante_fuehrt_durch_ein_element` alle Kanten gegen alle Elemente und meldet alle Funde außer den Paaren in `BEKANNTE_KREUZUNGEN`. Jedes dieser Paare hat einen eigenen strikten xfail-Test. Anlass: Die alte Gateway-Prüfung brach beim ersten Fund ab; bei #8 stand nur S12→S13 im Issue, tatsächlich waren es sieben Kreuzungen. (#16, 25.09.2026) - **Zusammenführende Gateways brauchen eine Beschriftung mit Zuständigkeit**, sonst landen sie in der Lane „Nicht zugeordnet“ (`split_lane()` braucht Text nach dem Doppelpunkt). In BPMN bleiben Zusammenführungen üblicherweise unbeschriftet – ein Fall für eine spätere Konverteränderung. (23.09.2026, Referenzmodell) - **Das bpmn.io-Wasserzeichen ist Lizenzauflage.** bpmn-js steht unter MIT, verlangt aber, dass das Wasserzeichen unten rechts sichtbar bleibt und nicht überdeckt wird. In `werkzeuge/vorschau/vorschau.html` deshalb nichts in die untere rechte Ecke der Zeichenfläche legen. (bpmn-js `LICENSE`, 23.09.2026) - **Diagramme nie roh in ein `` würde den Skriptblock beenden. `scripts/vorschau.py` maskiert jedes `<` im Diagramm als `\u003c`; die Bibliothek selbst wird nicht verändert, sondern nur auf ``) als erste Zeile. (23.09.2026, `scripts/einlesen.py`) - **`Path.read_text()` macht aus CRLF stillschweigend LF.** Wer eine Datei liest und mit Zusatz zurückschreibt, stellt so Windows-Dateien unbemerkt um. `scripts/einlesen.py` liest deshalb als Bytes. (23.09.2026, Test) - **Metadaten gehören nicht als Kopfzeile in die Arbeitsschritt-`.md`.** `parse_markdown()` liest eine Zeile wie `Verantwortliche Stelle: …` als Schritt mit ID `Verantwortliche` und Typ `Stelle` und bricht ab. Status und Stand stehen deshalb im Steckbrief `README.md` des Prozessordners. (23.09.2026) - **Zuständigkeit gilt auch für Gateways und Ereignisse.** Ohne `Rolle:`-Präfix landen sie in der Lane „Nicht zugeordnet“. Ein `?` stört nur vor dem Doppelpunkt: `Sachbearbeitung: Antrag vollständig?` funktioniert. (23.09.2026, beim Erstellen der Beispiele) - **Ein Gateway hat in PICTURE nur vier feste Anschlusspunkte (N/O/S/W auf der Rautenkontur), keinen variablen Rand wie ein Rechteck.** Eine Kante, die diesen Punkt verlässt bzw. dort ankommt, darf sich danach **nicht** direkt zur Ziel-/Quellkoordinate drehen, wenn diese auf der anderen Achse liegt – sonst läuft der rechtwinklige Streckenzug quer durchs Innere der Raute zurück, statt außen herumzugehen (`orthogonal_points()` in `md_to_bpmn.py`, behoben BPMN-Skill 21.09.2026). Ursache: die feste Anschlusspunkt-Zuteilung (`assign_gateway_sides()`, Präferenzreihenfolge S/O/W/N bzw. N/W/O/S) kennt die tatsächliche Lage des anderen Endes nicht. Die Kante muss beim Verlassen/Ankommen an einer Raute zuerst ein Stück auf der sicheren Stub-Achse bleiben (die einzige garantiert freie Koordinate außerhalb der Kontur), bevor sie zur anderen Achse abbiegt – sonst reicht ein einfacher Bounding-Box-Test nicht, um den Fehler zu erkennen (ein Punkt auf der Rautenkontur liegt immer innerhalb der Bounding-Box). Prüfen mit echter Diamant-Geometrie (Manhattan-Abstand zum Mittelpunkt, skaliert auf die Halbachsen, < 1 heißt innen), nicht mit der Bounding-Box – siehe `test_kante_fuehrt_nicht_durchs_innere_eines_gateways` in `test_md_to_bpmn.py`. ## Text und Sprache - **Deutscher Text ohne Umlaute/ß ist ein eigenständiges Muster, kein Einzelfall.** KI-generierter Text weicht gern auf ASCII aus (`gueltig` statt `gültig`, `ueber` statt `über`) – in AG_QGIS über alle Plugins verteilt gefunden (Plugin_SN_Basis #42), im BPMN-Skill in Elementnamen und Docstrings. Neuen deutschen Text (Beschriftungen im Modell, Kommentare, Docstrings) immer mit echten Umlauten/ß schreiben. Vor dem Commit `python scripts/pruefe_umlaute.py` laufen lassen – findet das Muster in `.py`-Dateien (String-Inhalte und Kommentare mit Leerzeichen). Die Wortstammliste ist bewusst konservativ; Ersatz fürs Lesen ist sie nicht. Arbeitsschritt-`.md` prüft das Skript nicht. (AG_QGIS 09/2026) ## Umgebung und Werkzeuge - **Öffentliche Organisation heißt nicht öffentliches Repo.** In Gitea haben Organisation und Repo getrennte Sichtbarkeit. `AG_Prozesse` war öffentlich, `Projektwissen` privat: Die Weboberfläche zeigte es angemeldeten Personen normal, die API ohne Anmeldung lieferte 404. `scripts/gitea.py` liest bewusst ohne Token und braucht deshalb ein öffentliches Repo; es prüft das jetzt vor jeder Abfrage. Prüfen ohne Anmeldung: `curl -s -o /dev/null -w "%{http_code}" https://entwicklung.flurneuordnung-sachsen.de/api/v1/repos/AG_Prozesse/Projektwissen` muss `200` liefern. (23.09.2026) - **Gitea ordnet Commits über die E-Mail-Adresse zu.** Stimmt `user.email` nicht mit einer im Gitea-Konto hinterlegten Adresse überein, erscheinen die Commits ohne Zuordnung zum Benutzer. Es gilt die dienstliche Adresse, die im Gitea-Konto hinterlegt ist. Wer den Rechner auch privat nutzt, setzt sie je Repository mit `git config --local` statt global. Nachträglich nur durch Umschreiben der Historie korrigierbar. (AG_QGIS 04.09.2026) - **`pytest` ist die einzige Abhängigkeit außerhalb der Standardbibliothek.** Die Tests des Konverters brauchen es; `md_to_bpmn.py` selbst läuft ohne. (23.09.2026) - **`.vscode/` gehört nicht ins Repository.** Einstellungen mit Pfaden eines einzelnen Arbeitsplatzes gehören in die Benutzereinstellungen, siehe `docs/leitfaden/04_werkzeuge_einrichten.md`. (AG_QGIS 04.09.2026) ## Zusammenarbeit - **Tool-Gedächtnis ist lokal.** Die Claude-Auto-Memory sieht niemand sonst. Geteiltes Wissen nur in diesem Ordner. - **Issues sind teils Diskussionen**, nicht Aufträge (Label `Diskussion`). Vor der Umsetzung Konsens im Issue abwarten oder im PR als Annahme kennzeichnen. - **Quelldokumente enthalten oft Interna.** Word/PDF-Prozessbeschreibungen nur lokal unter `referenz/` ablegen (nicht versioniert). Vor dem Committen eines Arbeitsschritt-Entwurfs prüfen, dass keine Namen, Aktenzeichen oder Verfahrensdaten darin stehen. (23.09.2026)