Prozessbibliothek als eigenes Repository auslagern (#9)

- ADR 0004 ersetzt ADR 0003: Die Prozessmodelle liegen im Repository
  AG_Prozesse/Prozessbibliothek, geklont nach Prozessbibliothek/ (neuer
  Eintrag in workspace.toml, .gitignore). prozesse/ ist entfernt; das
  Ablageformat (Ordner je Prozess, drei Dateien, Status) bleibt.
- pruefe_prozesse.py prüft den Klon (Ort über setup_workspace.repos_root),
  lässt Punkt-Ordner wie .git aus und erlaubt in der Wurzel nur die
  Repo-Dateien. Fehlt der Klon, gibt es einen Hinweis statt eines Befunds;
  pytest warnt dann.
- einlesen.py sucht den Bestand in der Bibliothek und nennt Treffer als
  Prozessbibliothek/<name>/, auch wenn der Klon woanders liegt.
- Regeln aus prozesse/README.md nach docs/leitfaden/08_prozessbibliothek.md,
  inklusive Ablauf bei Konverteränderungen (zwei Pull Requests).
- Verweise in AGENTS.md, README, Skills, Leitfäden, Vorlagen, Fallstricken
  und STATUS nachgezogen.
- Tests: python -m pytest -q -> 88 bestanden, 1 xfail (#8), 1 Warnung
  (Bibliothek noch nicht geklont).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 09:40:52 +02:00
co-authored by Claude Opus 5.5
parent 23a39fd929
commit 31131cc5c3
26 changed files with 312 additions and 131 deletions
@@ -46,8 +46,9 @@ git switch -c feature/<issue-nr>-<kurzname> # oder bugfix/… ; klein, ASCII,
schreiben, der den Fehler zeigt.
- **Jeder neue oder geänderte Test bekommt einen deutschen Docstring**, erste Zeile `"""Prüft, dass …"""`.
- Ändert sich die Markdown-Syntax oder ein Element: `Anleitung.md` bzw. `Elementkatalog.md` mitziehen. Syntax und
Ablageformat sind Verträge (`AGENTS.md`): vorher alle Modelle unter `prozesse/` prüfen, danach
`python scripts/pruefe_prozesse.py --erzeugen`.
Ablageformat sind Verträge (`AGENTS.md`): vorher alle Modelle der Prozessbibliothek prüfen, danach
`python scripts/pruefe_prozesse.py --erzeugen` und die neu erzeugten `.bpmn` als eigenen Pull Request in der
Bibliothek vorbereiten (`docs/leitfaden/08_prozessbibliothek.md`, „Wenn sich der Konverter ändert“).
## 5. Nachweis
- `python -m pytest -q` → alles grün.
+3 -3
View File
@@ -34,9 +34,9 @@ Beispiel (aus dem Workspace-Root):
python .agents/skills/sn-bpmn/md_to_bpmn.py entwuerfe/antrag-pruefen.md entwuerfe/antrag-pruefen.bpmn
```
Versionierte Modelle unter `prozesse/` werden nicht einzeln, sondern gesammelt
erzeugt: `python scripts/pruefe_prozesse.py --erzeugen` (siehe
`prozesse/README.md`).
Versionierte Modelle in der Prozessbibliothek werden nicht einzeln, sondern
gesammelt erzeugt: `python scripts/pruefe_prozesse.py --erzeugen` (siehe
`docs/leitfaden/08_prozessbibliothek.md`).
Die erzeugte `.bpmn`-Datei kann anschließend über den BPMN-Import-Dialog
in PICTURE geladen werden.
+9 -6
View File
@@ -21,9 +21,10 @@ schreibst oder bearbeitest.
1. **Quelle ermitteln.** Frage nach der Rohtext-, Word- oder PDF-Quelle,
falls keine angegeben oder angehängt wurde. Liegen Beschreibungen im
Eingangsordner `input/`, übernimmt der Skill `sn-einlesen` die Steuerung
und ruft diesen Skill je Datei auf. Gibt es den Prozess schon
unter `prozesse/<name>/`, ist dessen `<name>.md` der Ausgangspunkt:
dann auf einem Arbeitsbranch direkt dort ändern statt in `entwuerfe/`,
und ruft diesen Skill je Datei auf. Gibt es den Prozess schon in der
Prozessbibliothek (`Prozessbibliothek/<name>/`), ist dessen `<name>.md`
der Ausgangspunkt: dann auf einem Arbeitsbranch im Klon der Bibliothek
direkt dort ändern statt in `entwuerfe/`,
und nach Schritt 3 mit Schritt 5 weitermachen.
2. **Entwurf erzeugen.** Lies die Quelle und leite daraus eine
@@ -53,9 +54,11 @@ schreibst oder bearbeitest.
(geht auch direkt mit der `.md`, schon vor der Freigabe in Schritt 3).
Beim Anbieten der Vorschau dazusagen, dass PICTURE abweichen kann.
5. **Ablegen (nur auf Wunsch).** Ablauf und Regeln: `prozesse/README.md`
(ADR 0003). Kurz: Branch `feature/<issue-nr>-<name>` von `main`, Ordner
`prozesse/<name>/` mit `<name>.md` und Steckbrief `README.md` aus
5. **Ablegen (nur auf Wunsch).** Ablauf und Regeln:
`docs/leitfaden/08_prozessbibliothek.md` (ADR 0004). Kurz: Issue in der
Bibliothek, im Klon `Prozessbibliothek/` Branch
`feature/<issue-nr>-<name>` von `main`, Ordner `<name>/` mit
`<name>.md` und Steckbrief `README.md` aus
`docs/vorlagen/prozess_readme.md` (Status `Entwurf`, Annahmen aus
Schritt 2 unter „Annahmen und offene Punkte“), dann
`python scripts/pruefe_prozesse.py --erzeugen` und `python -m pytest -q`.
+10 -8
View File
@@ -14,7 +14,7 @@ und kann interne Inhalte enthalten. Ablauf für Menschen: `docs/leitfaden/07_pro
- **Eine Datei nach der anderen**, jede bis zu einer Entscheidung des Nutzers. Nicht mehrere Prozesse parallel
entwerfen.
- Inhalte aus `input/` landen nur bereinigt (ohne Namen, Aktenzeichen, Verfahrensdaten) in `entwuerfe/` oder
`prozesse/`.
der Prozessbibliothek.
## 1. Eingang prüfen
@@ -39,7 +39,7 @@ geänderten Datei beginnen. Ist nichts zu tun: ein Satz, fertig.
1. Datei lesen. In zwei Sätzen zusammenfassen, welchen Prozess sie beschreibt (Anlass, Ergebnis, Beteiligte
als Funktionen).
2. Bestand prüfen. Das Skript liefert `kandidaten` (Name und Wortüberschneidung, Schwelle 0,25) und die Liste
`bestand` aller Prozesse unter `prozesse/` und lokalen Entwürfe in `entwuerfe/`. **Die Zahl ist nur ein
`bestand` aller Prozesse der Prozessbibliothek und lokalen Entwürfe in `entwuerfe/`. **Die Zahl ist nur ein
Hinweis:** die `.md` der Kandidaten lesen und fachlich beurteilen, ob derselbe Ablauf gemeint ist. Auch die
Titel in `bestand` durchgehen – ein anders benannter Prozess kann derselbe sein.
3. Ergebnis mitteilen: „kein vorhandener Prozess“ oder „ähnlich zu …, weil …“ mit den Unterschieden.
@@ -67,13 +67,15 @@ Den Skill `sn-bpmn` ab Schritt 2 durchlaufen, mit der Datei aus `input/` als Que
Sonst den Entwurf aus dem Rohtext ableiten, wie in `sn-bpmn` Schritt 2.
- **Auf Freigabe warten** (`sn-bpmn` Schritt 3). Vorschau anbieten: `python scripts/vorschau.py entwuerfe/<name>.md`.
- Nach Freigabe umwandeln (`sn-bpmn` Schritt 4). Das ist der **Erfolg** für einen neuen Prozess.
- Ablegen unter `prozesse/` nur auf Wunsch (`sn-bpmn` Schritt 5; braucht ein Issue und einen Pull Request).
- Ablegen in der Prozessbibliothek nur auf Wunsch (`sn-bpmn` Schritt 5; braucht ein Issue und einen Pull Request
in der Bibliothek).
## 4b. Vorhandenen Prozess aktualisieren
- **Liegt er unter `prozesse/`:** Änderungen an versionierten Modellen gehen über Issue, Branch und Pull Request
(`AGENTS.md`). Gibt es kein Issue, einen Entwurf vorbereiten (Skill `sn-ticket`) und warten. Dann auf dem
Branch `prozesse/<name>/<name>.md` um die neuen Inhalte ergänzen, Unterschiede dem Nutzer zeigen, auf
- **Liegt er in der Prozessbibliothek:** Änderungen an versionierten Modellen gehen über Issue, Branch und Pull
Request in der Bibliothek (`AGENTS.md`, `docs/leitfaden/08_prozessbibliothek.md`). Gibt es kein Issue, einen
Entwurf vorbereiten (Skill `sn-ticket`, Repo `Prozessbibliothek`) und warten. Dann auf dem Branch im Klon
`Prozessbibliothek/<name>/<name>.md` um die neuen Inhalte ergänzen, Unterschiede dem Nutzer zeigen, auf
Freigabe warten, `python scripts/pruefe_prozesse.py --erzeugen`, `python -m pytest -q`, im Steckbrief unter
„Änderungen“ eintragen. **Erfolg** = Änderung committet.
- **Ist er nur ein lokaler Entwurf in `entwuerfe/`:** den Entwurf ergänzen, Unterschiede zeigen, auf Freigabe
@@ -83,7 +85,7 @@ Den Skill `sn-bpmn` ab Schritt 2 durchlaufen, mit der Datei aus `input/` als Que
```bash
python scripts/einlesen.py vermerk input/<datei>.md --ergebnis neu --ziel entwuerfe/<name>.md
python scripts/einlesen.py vermerk input/<datei>.md --ergebnis aktualisiert --ziel prozesse/<name>/
python scripts/einlesen.py vermerk input/<datei>.md --ergebnis aktualisiert --ziel Prozessbibliothek/<name>/
```
Das Skript schreibt als erste Zeile einen HTML-Kommentar mit Zeitstempel, Ergebnis, Ziel und Inhalts-Prüfsumme;
@@ -93,5 +95,5 @@ fehlgeschlagener Umwandlung.
## 6. Zusammenfassung
Am Ende eine Tabelle: Datei | Status vorher | Entscheidung | Ergebnis (Pfad) | Vermerk ja/nein. Dazu abgelehnte
Dateien mit Grund und, falls etwas unter `prozesse/` geändert wurde, den vorbereiteten Pull-Request-Text
Dateien mit Grund und, falls etwas in der Prozessbibliothek geändert wurde, den vorbereiteten Pull-Request-Text
(vollständig nach `docs/vorlagen/pull_request.md`). Push und Pull Request macht der Mensch.
+1
View File
@@ -1,5 +1,6 @@
# Weitere Repositories der Gruppe (siehe workspace.toml) sind eigenständige Git-Klone
# und werden hier nicht versioniert. Beim Eintragen eines neuen Repos hier ergänzen.
/Prozessbibliothek/
# Von scripts/setup_workspace.py aus .agents/skills/ gespiegelt (Claude Code liest nur .claude/skills/).
# Ohne Schrägstrich, damit auch ein Symlink bzw. eine Junction erfasst wird.
+7 -5
View File
@@ -10,7 +10,8 @@ Sie bleibt bewusst kurz: Details liegen in `docs/` und werden nur bei Bedarf gel
- Kernwerkzeug ist der Skill `sn-bpmn`: Prozessbeschreibung (Rohtext, Stichpunkte, Word/PDF) → strukturierte
Arbeitsschritt-`.md` → BPMN-2.0-Datei (`.agents/skills/sn-bpmn/md_to_bpmn.py`).
- Dieser Ordner ist der Klon des Repositories **`AG_Prozesse/Projektwissen`**. Weitere Repositories der Gruppe
würden als eigenständige Git-Klone in Unterordnern liegen und in `workspace.toml` stehen – derzeit gibt es keine.
liegen als eigenständige Git-Klone in Unterordnern und stehen in `workspace.toml`: derzeit
**`Prozessbibliothek`** mit den versionierten Prozessmodellen (ADR 0004).
- Die Arbeitsweise (Skripte, Skills, Git-Regeln) stammt aus `AG_QGIS/Projektwissen`, siehe
`docs/entscheidungen/0001-uebernahme-aus-ag-qgis.md`.
@@ -52,16 +53,17 @@ Sie bleibt bewusst kurz: Details liegen in `docs/` und werden nur bei Bedarf gel
nur die daraus abgeleiteten, bereinigten Arbeitsschritt-`.md` und BPMN-Dateien. Dasselbe gilt für den
Eingangsordner `input/` (Skill `sn-einlesen`): Dateien dort nie löschen, verschieben oder umbenennen; einziger
Eingriff ist der Einlese-Vermerk über `scripts/einlesen.py`.
- **Prozessmodelle liegen in `prozesse/<name>/`** (ADR 0003, Regeln in `prozesse/README.md`). Die `.md` ist
maßgeblich, die `.bpmn` wird nie von Hand bearbeitet, sondern mit `python scripts/pruefe_prozesse.py --erzeugen`
- **Prozessmodelle liegen im eigenen Repository `Prozessbibliothek`**, geklont nach `Prozessbibliothek/<name>/`
(ADR 0004, Regeln in `docs/leitfaden/08_prozessbibliothek.md`). Issues, Branches und Pull Requests zu Modellen
laufen dort. Die `.md` ist maßgeblich, die `.bpmn` wird nie von Hand bearbeitet, sondern mit `python scripts/pruefe_prozesse.py --erzeugen`
neu erzeugt. Den Status `abgenommen` setzt der Agent nie von sich aus.
- Rollen und Verantwortliche in Prozessmodellen als Funktion benennen („Sachbearbeitung Flurbereinigung"),
nie als Person.
- Keine Python-Abhängigkeiten außer der Standardbibliothek und `pytest` ohne Issue-Absprache und Eintrag in
`fallstricke.md`. Einzige eingebettete Fremdbibliothek ist bpmn-js unter `werkzeuge/vorschau/bpmn-js/` –
nicht von Hand ändern, Aktualisierung nach `werkzeuge/vorschau/README.md`.
- **Die Markdown-Syntax und das Ablageformat unter `prozesse/` sind Verträge.** Wer sie ändert, prüft vorher alle
Modelle unter `prozesse/`, zieht `Anleitung.md` bzw. `prozesse/README.md` nach und nennt die Änderung im Pull
- **Die Markdown-Syntax und das Ablageformat der Prozessbibliothek sind Verträge.** Wer sie ändert, prüft vorher
alle Modelle der Bibliothek, zieht `Anleitung.md` bzw. `docs/leitfaden/08_prozessbibliothek.md` nach und nennt die Änderung im Pull
Request unter „Änderungen an Syntax und Ablageformat“.
- Kein Umbau „nebenbei". Strukturänderungen nur über eigenes Issue.
+4 -3
View File
@@ -69,8 +69,9 @@ Du prüfst und änderst den Entwurf fachlich — als Diagramm ansehen geht jeder
Import in PICTURE. Syntax des Entwurfs: [`.agents/skills/sn-bpmn/Anleitung.md`](.agents/skills/sn-bpmn/Anleitung.md).
`input/`, `referenz/` und `entwuerfe/` werden nicht versioniert — Quelldokumente bleiben auf deinem Rechner.
Soll das Modell für alle verfügbar sein, legt der Agent es auf Wunsch unter [`prozesse/`](prozesse/README.md) ab —
mit Steckbrief und Status `Entwurf`, per Pull Request. Dort liegen auch die fertigen `.bpmn` zum Herunterladen.
Soll das Modell für alle verfügbar sein, legt der Agent es auf Wunsch in der
[Prozessbibliothek](docs/leitfaden/08_prozessbibliothek.md) ab, einem eigenen Repository, mit Steckbrief und Status
`Entwurf`, per Pull Request. Dort liegen auch die fertigen `.bpmn` zum Herunterladen.
## Am Werkzeug mitarbeiten
@@ -103,7 +104,7 @@ Die vollständige, für Agenten verbindliche Fassung steht in [`AGENTS.md`](AGEN
|---|---|
| [`AGENTS.md`](AGENTS.md) / `CLAUDE.md` | Anweisungen für Agenten (kanonisch ist `AGENTS.md`) |
| [`workspace.toml`](workspace.toml) | Gitea-Organisation und Verzeichnis weiterer Repositories |
| [`prozesse/`](prozesse/README.md) | Versionierte Prozessmodelle, ein Ordner je Prozess (ADR 0003) |
| `Prozessbibliothek/` | Klon des eigenen Repositorys mit den versionierten Prozessmodellen (ADR 0004, [Regeln](docs/leitfaden/08_prozessbibliothek.md)) |
| `scripts/` | `hallo.py`, `setup_workspace.py`, `gitea.py`, `pruefe_umlaute.py`, `pruefe_prozesse.py`, `vorschau.py`, `einlesen.py` |
| `input/` | Eingangsordner für Prozessbeschreibungen (`.md`), lokal, nicht versioniert – Skill `sn-einlesen` |
| [`werkzeuge/vorschau/`](werkzeuge/vorschau/README.md) | BPMN-Vorschau im Browser (bpmn-js, offline); `vorschau.html` auch ohne Python |
+3 -1
View File
@@ -10,10 +10,12 @@
| `leitfaden/04_werkzeuge_einrichten.md` | stabil | Einrichtung: Claude Code als CLI und in VS Code; von null zur ersten Aufgabe |
| `leitfaden/05_git_arbeitsweise.md` | **verbindlich** | Branches, Pull Requests, was der Agent darf |
| `leitfaden/07_prozesse_einlesen.md` | stabil | Einsteiger-Ablauf: Beschreibung in `input/` legen, einlesen, freigeben |
| `leitfaden/08_prozessbibliothek.md` | stabil | Regeln und Ablauf für die Prozessbibliothek (eigenes Repository) |
| `vorlagen/` | Vorlagen | Issue, PR, Übergabe, Repo-`AGENTS.md`, Steckbrief eines Prozesses |
Die Fachdoku des Konverters (Markdown-Syntax, Elementkatalog, Modellierregeln) liegt beim Skill in
`.agents/skills/sn-bpmn/`, die versionierten Prozessmodelle in `prozesse/` (Regeln: `prozesse/README.md`).
`.agents/skills/sn-bpmn/`, die versionierten Prozessmodelle im eigenen Repository `Prozessbibliothek`
(Regeln: `leitfaden/08_prozessbibliothek.md`).
Regel: **Lebende** Dokumente werden mit jeder Änderung gepflegt, **Momentaufnahmen** nicht nachträglich geändert
(neue Analyse = neue Datei mit Datum).
@@ -1,6 +1,6 @@
# 0003 – Prozessmodelle liegen versioniert in `prozesse/<name>/`, die `.md` ist maßgeblich
Status: vorgeschlagen · Datum: 2026-09-23 · Beteiligte: AG Prozesse
Status: ersetzt durch 0004 · Datum: 2026-09-23 · Beteiligte: AG Prozesse
## Kontext
Der Skill `sn-bpmn` legt Entwürfe in `entwuerfe/` ab; der Ordner ist nicht versioniert. Fertige Modelle hatten damit
@@ -0,0 +1,41 @@
# 0004 – Prozessmodelle liegen im eigenen Repository `Prozessbibliothek`
Status: vorgeschlagen · Datum: 2026-09-25 · Beteiligte: AG Prozesse · Ersetzt: 0003
## Kontext
Nach ADR 0003 lagen die Prozessmodelle in `prozesse/` innerhalb von `Projektwissen`. Damit waren Fachdaten und
Werkzeuge verschränkt (Issue #9): Wer ein Modell ändert, arbeitet im selben Verlauf, in denselben Issues und
Pull Requests wie am Konverter, an den Skills und an der Doku. Fachleute, die nur Modelle pflegen, müssen sich
durch Werkzeug-Änderungen lesen, und die Abnahme eines Modells geht im Verlauf der Werkzeuge unter.
## Entscheidung
Die Prozessmodelle liegen im eigenen Repository `AG_Prozesse/Prozessbibliothek`, das als Klon neben
`Projektwissen` im Workspace liegt (`workspace.toml`, `scripts/setup_workspace.py`).
- **Aufbau:** ein Ordner je Prozess direkt in der Wurzel, `<name>/` mit genau drei Dateien: Steckbrief
`README.md`, Arbeitsschritt-Beschreibung `<name>.md`, daraus erzeugte `<name>.bpmn`. In der Wurzel sonst nur
`README.md`, `AGENTS.md`, `CLAUDE.md`, `.gitattributes` und `.gitignore`. Das Repository enthält keinen Code.
- **Die `.md` ist maßgeblich** und die `.bpmn` wird mitcommittet, damit sie ohne Python heruntergeladen und in
PICTURE importiert werden kann. Der Steckbrief trägt den Status `Entwurf` oder `abgenommen`. Die Abnahme ist ein
eigener Pull Request in der Bibliothek. Diese Punkte bleiben aus ADR 0003 unverändert.
- **Regeln, Vorlagen und Prüfung bleiben in `Projektwissen`:** Ablageregeln in
`docs/leitfaden/08_prozessbibliothek.md`, Steckbrief-Vorlage `docs/vorlagen/prozess_readme.md`, Prüfung mit
`scripts/pruefe_prozesse.py` (Byte-Vergleich, Ordnerstruktur, Status) gegen den Klon. So gibt es den Konverter
nur an einer Stelle, und Regel und Prüfung ändern sich im selben Pull Request.
- **Ist die Bibliothek nicht geklont**, ist das für die Prüfung kein Fehler: geprüft werden dann nur die
Skill-Beispiele, und `pruefe_prozesse.py` sowie `pytest` weisen deutlich darauf hin.
- Issues zu einzelnen Modellen gehören in die Bibliothek, Issues zu Konverter, Skills und Doku nach
`Projektwissen`.
## Folgen
Modelle haben einen eigenen, lesbaren Verlauf, eigene Issues und eigene Pull Requests. Eine Konverteränderung,
die die Ausgabe verändert, braucht jetzt **zwei Pull Requests**: den in `Projektwissen` und einen in der
Bibliothek mit den neu erzeugten `.bpmn` (`python scripts/pruefe_prozesse.py --erzeugen` schreibt in den Klon).
Beide werden gemeinsam gemergt, damit die Bibliothek zum Konverter auf `main` passt. Wer nur `Projektwissen`
geklont hat, prüft keine Modelle mit; `scripts/hallo.py` meldet den fehlenden Klon.
## Verworfene Alternativen
Weiter `prozesse/` in `Projektwissen` (die Verschränkung bliebe); Prozessordner unter `prozesse/` im neuen Repo
(doppelter Pfad ohne Nutzen); eigenes Prüfskript in der Bibliothek (bräuchte eine Kopie von `md_to_bpmn.py`, die
auseinanderlaufen kann); Git-Submodul (für die Zielgruppe zu fehleranfällig, der Workspace klont Repos bereits
nebeneinander).
+2 -1
View File
@@ -27,4 +27,5 @@ Kurz, mit Grund.
|---|---|---|
| 0001 | Arbeitsweise aus AG_QGIS/Projektwissen übernehmen, ohne Historie | vorgeschlagen |
| 0002 | Branchmodell: `main` plus Arbeitsbranches | vorgeschlagen |
| 0003 | Prozessmodelle liegen versioniert in `prozesse/<name>/`, die `.md` ist maßgeblich | vorgeschlagen |
| 0003 | Prozessmodelle liegen versioniert in `prozesse/<name>/`, die `.md` ist maßgeblich | ersetzt durch 0004 |
| 0004 | Prozessmodelle liegen im eigenen Repository `Prozessbibliothek` | vorgeschlagen |
+6 -6
View File
@@ -14,7 +14,7 @@ Einrichtung Schritt für Schritt: `04_werkzeuge_einrichten.md`.
Wer nur modelliert, braucht Git kaum: Beschreibung als `.md` nach `input/` legen, Claude Code im Ordner
`AG_Prozesse` starten, „Lies den Ordner input ein“, Entwurf prüfen, umwandeln (`07_prozesse_einlesen.md`). Git und Pull Requests kommen erst ins Spiel, wenn sich am Konverter, an den Regeln oder an der Doku
etwas ändern soll — oder wenn ein Modell unter `prozesse/` abgelegt oder geändert wird (Abschnitt 2).
etwas ändern soll — oder wenn ein Modell in der Prozessbibliothek abgelegt oder geändert wird (Abschnitt 2).
## 2. Einen Prozess modellieren
@@ -26,7 +26,7 @@ flowchart TD
C -->|"passt so, wandle um"| D["&lt;name&gt;.bpmn"]
D --> E["Import in PICTURE"]
E -->|"Darstellungsfehler"| F["Issue anlegen<br/><i>Skill sn-ticket</i>"]
E -->|"für alle ablegen"| G["prozesse/&lt;name&gt;/<br/>Status Entwurf, Pull Request"]
E -->|"für alle ablegen"| G["Prozessbibliothek/&lt;name&gt;/<br/>Status Entwurf, Pull Request"]
G -->|"fachlich bestätigt"| H["Pull Request: Status abgenommen"]
```
@@ -39,8 +39,8 @@ flowchart TD
- **Rollen statt Personen.** Verantwortliche immer als Funktion („Sachbearbeitung"), nie mit Namen.
- **Darstellungsfehler in PICTURE** (Kanten durch Elemente, überlappende Lanes) sind Fehler des Konverters, nicht
deines Entwurfs. Issue anlegen, mit dem Entwurf als Beispiel (bereinigt).
- **Ablegen unter `prozesse/`** macht das Modell für alle sichtbar und versioniert (ADR 0003, Regeln in
`prozesse/README.md`). Die `.md` ist maßgeblich: Was nur in PICTURE nachgebessert wird, ist bei der nächsten
- **Ablegen in der Prozessbibliothek** macht das Modell für alle sichtbar und versioniert (eigenes Repository,
ADR 0004, Regeln in `08_prozessbibliothek.md`). Die `.md` ist maßgeblich: Was nur in PICTURE nachgebessert wird, ist bei der nächsten
Erzeugung weg. **Abnahme** heißt: ein eigener Pull Request, der im Steckbrief den Status auf `abgenommen` setzt;
das Review dieses Pull Requests ist die fachliche Bestätigung.
@@ -98,7 +98,7 @@ Werkzeugs (Claude Auto-Memory) ist ein Notizzettel; teilbares Wissen gehört in
| `.claude/commands/` | Slash-Befehle, z. B. `/hallo` |
| `.claude/settings.json` | Berechtigungen – sperrt `git push`, `merge`, `tag` |
| `docs/` | auf Abruf, nicht automatisch |
| `prozesse/` | auf Abruf; versionierte Modelle mit Steckbrief |
| `Prozessbibliothek/` | auf Abruf; eigener Klon mit den versionierten Modellen, eigene `AGENTS.md` |
| `input/` | beim Einlesen (Skill `sn-einlesen`); nicht versioniert |
| `referenz/`, `entwuerfe/` | nur, wenn du darauf verweist; nicht versioniert |
| `CLAUDE.local.md` | ja, lokal, nicht versioniert |
@@ -129,7 +129,7 @@ kleine PRs machen.
- [ ] Jeder neue oder geänderte Test hat einen deutschen Docstring `"""Prüft, dass …"""`
- [ ] Keine Debug-`print`, kein auskommentierter Code
- [ ] Änderungen an Markdown-Syntax oder Ablageformat im PR benannt (oder „keine“)
- [ ] Bei geänderter BPMN-Ausgabe: PICTURE-Import dokumentiert, `.bpmn` unter `prozesse/` neu erzeugt
- [ ] Bei geänderter BPMN-Ausgabe: PICTURE-Import dokumentiert, `.bpmn` der Bibliothek neu erzeugt (eigener PR dort)
- [ ] Keine personenbezogenen Daten, keine Originalunterlagen
- [ ] PR-Text vollständig nach Vorlage, mit Checkliste und Übergabenotiz; Wissensbasis nachgezogen, falls nötig
- [ ] Diff gelesen: nur, was das Issue verlangt
+6 -5
View File
@@ -71,12 +71,12 @@ Dieselbe Übersicht bekommst du ohne Agent mit `python scripts/einlesen.py`.
## 4. Entscheiden: Gibt es den Prozess schon?
Für jede neue Datei sucht der Agent im Bestand – versionierte Prozesse unter `prozesse/` und deine lokalen Entwürfe
Für jede neue Datei sucht der Agent im Bestand – versionierte Prozesse der Prozessbibliothek und deine lokalen Entwürfe
unter `entwuerfe/` – und sagt, ob und warum ein vorhandener Prozess passt. Gibt es einen, fragt er dich:
| Wenn du wählst … | … passiert |
|---|---|
| **Vorhandenen Prozess aktualisieren** | Der vorhandene Entwurf bzw. Prozess wird um die neuen Inhalte ergänzt. Bei Prozessen unter `prozesse/` geht das über ein Issue und einen Pull Request (Abschnitt 7). |
| **Vorhandenen Prozess aktualisieren** | Der vorhandene Entwurf bzw. Prozess wird um die neuen Inhalte ergänzt. Bei Prozessen der Prozessbibliothek geht das über ein Issue und einen Pull Request dort (Abschnitt 7). |
| **Als neuen Prozess anlegen** | Es entsteht ein eigener Entwurf mit anderem Namen. |
| **Datei überspringen** | Nichts passiert. Die Datei erscheint beim nächsten Einlesen wieder. |
| **Einlesen beenden** | Der Agent hört auf; die übrigen Dateien bleiben unberührt. |
@@ -114,8 +114,9 @@ Zeile unsichtbar, im Editor sichtbar. Bitte nicht von Hand ändern.
## 7. Für alle sichtbar ablegen (optional)
Entwürfe liegen nur auf deinem Rechner. Soll das Modell für die Gruppe verfügbar sein, legt der Agent es auf
Wunsch unter `prozesse/<name>/` ab – mit Steckbrief und Status `Entwurf` (Regeln: `prozesse/README.md`). Das ist
eine Änderung am gemeinsamen Repository:
Wunsch in der Prozessbibliothek ab, einem eigenen Repository, unter `<name>/` mit Steckbrief und Status `Entwurf`
(Regeln: [`08_prozessbibliothek.md`](08_prozessbibliothek.md)). Das ist eine Änderung an einem gemeinsamen
Repository:
1. Der Agent bereitet einen Issue-Text vor; **du** legst das Issue in Gitea an und nennst ihm die Nummer.
2. Der Agent legt den Ordner auf einem eigenen Branch an und bereitet Commit und Pull-Request-Text vor.
@@ -146,4 +147,4 @@ nacheinander und fragt bei jeder einzeln.
- Skill `sn-einlesen` (`.agents/skills/sn-einlesen/SKILL.md`) – was der Agent genau tut
- Skill `sn-bpmn` und `.agents/skills/sn-bpmn/Anleitung.md` – Entwurf und Syntax
- [`03_arbeitsweise.md`](03_arbeitsweise.md) – Arbeitsweise insgesamt
- `prozesse/README.md` – versionierte Ablage
- [`08_prozessbibliothek.md`](08_prozessbibliothek.md) – versionierte Ablage in der Prozessbibliothek
+65
View File
@@ -0,0 +1,65 @@
# Die Prozessbibliothek: Ablage der Prozessmodelle
Regeln und Ablauf für die versionierten Prozessmodelle der AG Prozesse (ADR 0004). Die Modelle liegen im eigenen
Repository [`AG_Prozesse/Prozessbibliothek`](https://entwicklung.flurneuordnung-sachsen.de/AG_Prozesse/Prozessbibliothek),
die Regeln und die Prüfung hier in `Projektwissen`. Arbeitsentwürfe gehören nicht in die Bibliothek, sondern nach
`entwuerfe/` (nicht versioniert).
## Wo sie liegt
`python scripts/setup_workspace.py` klont die Bibliothek in den Ordner `Prozessbibliothek/` im Workspace,
oder unter `repos_root` aus `workspace.local.toml`, wenn dort ein anderer Ort eingetragen ist.
`Projektwissen` versioniert den Ordner nicht mit, denn er ist ein eigener Git-Klon.
```
Prozessbibliothek/
README.md kurz: was hier liegt, Verweis auf diesen Leitfaden
AGENTS.md, CLAUDE.md Anweisungen für KI-Agenten
antrag-pruefen/
README.md Steckbrief: Status, Stand, Zuständigkeit, offene Punkte
antrag-pruefen.md Arbeitsschritt-Beschreibung – die maßgebliche Quelle
antrag-pruefen.bpmn daraus erzeugt, nie von Hand bearbeiten
```
## Regeln
- **Ordnername:** Kleinbuchstaben, Ziffern, Bindestriche (`antrag-pruefen`). Die beiden Modelldateien heißen wie
der Ordner.
- **Genau drei Dateien je Prozess.** Keine Originalunterlagen (Word, PDF), keine Bilder. Die bleiben lokal in
`referenz/`. In der Wurzel der Bibliothek liegen außer den Prozessordnern nur `README.md`, `AGENTS.md`,
`CLAUDE.md`, `.gitattributes` und `.gitignore`.
- **Die `.md` ist maßgeblich.** Die `.bpmn` wird nach jeder Änderung neu erzeugt und mitcommittet:
`python scripts/pruefe_prozesse.py --erzeugen` (aus `Projektwissen`). Änderungen, die in PICTURE nachgetragen
werden, fließen nicht zurück. Wer etwas dauerhaft ändern will, ändert die `.md`.
- **Status im Steckbrief:** `Entwurf` (liegt zur gemeinsamen Bearbeitung hier) oder `abgenommen` (fachlich
bestätigt). Den Wechsel auf `abgenommen` macht ein eigener Pull Request, dessen Review die Abnahme ist.
- **Keine personenbezogenen Daten.** Zuständigkeiten als Funktion, keine Namen, Aktenzeichen oder Verfahrensdaten.
- **Issues zu einem Modell** werden in der Bibliothek angelegt, Issues zu Konverter, Skills und Doku in
`Projektwissen`. Branches heißen in beiden Repositories `feature/<issue-nr>-<kurzname>`.
## Prüfen
Aus dem Workspace-Root (`Projektwissen`):
```bash
python scripts/pruefe_prozesse.py # Struktur, Status, .bpmn aktuell? Prüft auch die Skill-Beispiele
python -m pytest -q # enthält dieselbe Prüfung
```
Ist die Bibliothek nicht geklont, prüfen beide nur die Skill-Beispiele und weisen darauf hin.
## Einen Prozess ablegen
1. Entwurf mit dem Skill `sn-bpmn` erstellen und fachlich prüfen.
2. Issue in der Bibliothek, dann im Klon `Prozessbibliothek/` einen Branch `feature/<issue-nr>-<prozessname>`
von `main` anlegen.
3. Ordner anlegen, Entwurf als `<name>.md` hineinkopieren, Steckbrief aus `docs/vorlagen/prozess_readme.md`.
4. In `Projektwissen`: `python scripts/pruefe_prozesse.py --erzeugen`, dann `python -m pytest -q`.
5. Im Klon committen. Pull Request in der Bibliothek: Der Agent bereitet vor, der Mensch pusht.
## Wenn sich der Konverter ändert
Ändert ein Pull Request in `Projektwissen` die BPMN-Ausgabe, meldet `pruefe_prozesse.py` die betroffenen Modelle
als veraltet. Dann in der Bibliothek einen Branch mit demselben Issue-Bezug anlegen,
`python scripts/pruefe_prozesse.py --erzeugen` ausführen, die neuen `.bpmn` dort committen und beide Pull Requests
gemeinsam mergen: erst `Projektwissen`, direkt danach die Bibliothek.
+7 -2
View File
@@ -1,7 +1,7 @@
# Status des Projekts
Kurz und aktuell. Wird bei jedem Merge und jeder Übergabe gepflegt (Skill `sn-uebergabe`). Älteres wandert nach unten
in „Erledigt" oder wird gelöscht. **Stand: 23.09.2026.**
in „Erledigt" oder wird gelöscht. **Stand: 25.09.2026.**
## Aktuelle Phase
@@ -20,7 +20,8 @@ Skills sind übernommen, alles QGIS- und Plugin-Spezifische ist entfernt. Kern i
1. **Repo `Projektwissen` in Gitea öffentlich schalten** (Repo → Einstellungen → Sichtbarkeit). Die Organisation ist
öffentlich, das Repo nicht; ohne das liest `scripts/gitea.py` keine Tickets, und die Skills `sn-ticket` und
`sn-aufgabe-bearbeiten` laufen ins Leere.
2. **ADR 0003 (Ablage in `prozesse/`) vom Team annehmen lassen**, dann den ersten echten Prozess ablegen.
2. **ADR 0004 (Prozessbibliothek als eigenes Repository) vom Team annehmen lassen**, dann den ersten echten
Prozess dort ablegen.
3. **Glossar um BPMN-/PICTURE-Begriffe ergänzen** und die Flurbereinigungsbegriffe auf das prüfen, was für
Prozesse gebraucht wird.
4. **Leitfäden vom Team gegenlesen lassen.** `docs/leitfaden/03–05` sind für die Prozessarbeit neu gefasst;
@@ -30,6 +31,10 @@ Skills sind übernommen, alles QGIS- und Plugin-Spezifische ist entfernt. Kern i
## Erledigt
- 25.09.2026 **Prozessbibliothek als eigenes Repository** (#9, ADR 0004): `prozesse/` ist aus Projektwissen
entfernt, die Modelle liegen im Klon `Prozessbibliothek/` (`workspace.toml`). `pruefe_prozesse.py` und
`einlesen.py` suchen dort; Regeln in `docs/leitfaden/08_prozessbibliothek.md`.
- 23.09.2026 **Erster echter Einlese-Durchgang** (`input/Gewannenvermessung.md` → `entwuerfe/gewannenfestlegung`)
und daraus das **Referenzmodell** `beispiele/referenz_gewannenfestlegung` für Konvertertests (#7), mit
Strukturtests. Dabei gefunden: Kante durch Gateway S13 (#8, als `xfail` erfasst).
+2 -2
View File
@@ -2,9 +2,9 @@
<Was soll am Ende möglich sein? Ein Satz aus Nutzersicht.>
## Betroffen
Bereich: Prozessmodell (`prozesse/<name>/`) | Konverter `md_to_bpmn.py` | Skill | Skripte | Doku
Bereich: Konverter `md_to_bpmn.py` | Skill | Skripte | Doku
Dateien (falls bekannt):
Ändert Markdown-Syntax oder Ablageformat unter `prozesse/`? nein | ja: <welche>
Ändert Markdown-Syntax oder Ablageformat der Prozessbibliothek? nein | ja: <welche>
## Fachlicher Hintergrund
<Begriffe, Regeln, Beispiel (keine echten Verfahrensdaten, keine Namen). Verweise auf Glossar.>
+4 -3
View File
@@ -4,12 +4,13 @@
## Wie geprüft
- `python -m pytest -q`: <Ergebniszeile>
- `python scripts/pruefe_umlaute.py`: <Ergebniszeile>
- Bei Modellen unter `prozesse/`: `.bpmn` mit `python scripts/pruefe_prozesse.py --erzeugen` erzeugt
- Bei Modellen der Prozessbibliothek: `.bpmn` mit `python scripts/pruefe_prozesse.py --erzeugen` erzeugt
- PICTURE-Import: <PICTURE-Version, Datei, Ergebnis> | nicht nötig, weil …
## Änderungen an Syntax und Ablageformat
keine | <welche, mit Verweis auf Issue: Markdown-Syntax (`Anleitung.md`), Ablage unter `prozesse/`
(`prozesse/README.md`, ADR 0003); welche Modelle unter `prozesse/` angepasst oder neu erzeugt wurden>
keine | <welche, mit Verweis auf Issue: Markdown-Syntax (`Anleitung.md`), Ablage in der Prozessbibliothek
(`docs/leitfaden/08_prozessbibliothek.md`, ADR 0004); welche Modelle der Bibliothek angepasst oder neu erzeugt
wurden, mit Verweis auf den zugehörigen PR dort>
## Übergabenotiz
<nach docs/vorlagen/uebergabe.md>
+5 -4
View File
@@ -21,10 +21,11 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik
sondern nur auf `<script`/`</script` geprüft. (23.09.2026)
- **Jede Änderung an der Ausgabe von `md_to_bpmn.py` macht die abgelegten `.bpmn` rot.** Der Test in
`tests/test_pruefe_prozesse.py` vergleicht jede `.bpmn` unter `prozesse/` und in `beispiele/` byte-genau mit der
Umwandlung ihrer `.md`. Nach einer Konverteränderung `python scripts/pruefe_prozesse.py --erzeugen` ausführen und
die neu erzeugten Dateien mit in den Pull Request nehmen. Das setzt voraus, dass der Konverter deterministisch
bleibt: keine Zufalls-IDs, keine Zeitstempel, keine Reihenfolge aus `set`-Iteration. (ADR 0003, 23.09.2026)
`tests/test_pruefe_prozesse.py` vergleicht jede `.bpmn` der Prozessbibliothek und in `beispiele/` byte-genau mit
der Umwandlung ihrer `.md`. Nach einer Konverteränderung `python scripts/pruefe_prozesse.py --erzeugen` ausführen;
die neuen `.bpmn` der Beispiele gehören in den Pull Request, die der Bibliothek in einen eigenen Pull Request dort
(ADR 0004). Das setzt voraus, dass der Konverter deterministisch
bleibt: keine Zufalls-IDs, keine Zeitstempel, keine Reihenfolge aus `set`-Iteration. (ADR 0003, 23.09.2026; ADR 0004, 25.09.2026)
- **Zusätzliche Zeilen in einer Arbeitsschritt-`.md` nur ganz oben oder mit `#`.** `parse_markdown()` bricht
nach dem ersten Schritt bei jeder unbekannten Zeile ab; davor überspringt es Zeilen, die nicht wie
`Schlüssel: Wert` aussehen. Deshalb steht der Einlese-Vermerk (`<!-- eingelesen: … -->`) als erste Zeile.
-39
View File
@@ -1,39 +0,0 @@
# Prozessmodelle
Hier liegen die versionierten Prozessmodelle der AG Prozesse, ein Ordner je Prozess (ADR 0003).
Arbeitsentwürfe gehören nicht hierher, sondern nach `entwuerfe/` (nicht versioniert).
```
prozesse/
antrag-pruefen/
README.md Steckbrief: Status, Stand, Zuständigkeit, offene Punkte
antrag-pruefen.md Arbeitsschritt-Beschreibung – die maßgebliche Quelle
antrag-pruefen.bpmn daraus erzeugt, nie von Hand bearbeiten
```
## Regeln
- **Ordnername:** Kleinbuchstaben, Ziffern, Bindestriche (`antrag-pruefen`). Die beiden Modelldateien heißen wie
der Ordner.
- **Genau drei Dateien.** Keine Originalunterlagen (Word, PDF), keine Bilder — die bleiben lokal in `referenz/`.
- **Die `.md` ist maßgeblich.** Die `.bpmn` wird nach jeder Änderung neu erzeugt und mitcommittet:
`python scripts/pruefe_prozesse.py --erzeugen`. Änderungen, die in PICTURE nachgetragen werden, fließen nicht
zurück — wer etwas dauerhaft ändern will, ändert die `.md`.
- **Status im Steckbrief:** `Entwurf` (liegt zur gemeinsamen Bearbeitung hier) oder `abgenommen` (fachlich
bestätigt). Den Wechsel auf `abgenommen` macht ein eigener Pull Request, dessen Review die Abnahme ist.
- **Keine personenbezogenen Daten.** Zuständigkeiten als Funktion, keine Namen, Aktenzeichen oder Verfahrensdaten.
## Prüfen
```bash
python scripts/pruefe_prozesse.py # Struktur, Status, .bpmn aktuell?
python -m pytest -q # enthält dieselbe Prüfung
```
## Einen Prozess ablegen
1. Entwurf mit dem Skill `sn-bpmn` erstellen und fachlich prüfen.
2. Branch `feature/<issue-nr>-<prozessname>` von `main`.
3. Ordner anlegen, Entwurf als `<name>.md` hineinkopieren, Steckbrief aus `docs/vorlagen/prozess_readme.md`.
4. `python scripts/pruefe_prozesse.py --erzeugen`, dann Tests.
5. Pull Request — der Agent bereitet vor, der Mensch pusht.
+11 -8
View File
@@ -11,7 +11,8 @@ Mechanische; die fachliche Einschätzung und die Rückfrage an den Menschen mach
geändert .md mit Vermerk, aber der Inhalt hat sich seitdem geändert
eingelesen .md mit Vermerk, Inhalt unverändert – wird übersprungen
Für neue und geänderte Dateien: vorgeschlagener Prozessname, ob die Datei schon eine
gültige Arbeitsschritt-.md ist, und ähnliche vorhandene Prozesse (prozesse/, entwuerfe/).
gültige Arbeitsschritt-.md ist, und ähnliche vorhandene Prozesse
(Prozessbibliothek, entwuerfe/).
vermerk Trägt nach erfolgreichem Einlesen oben in die .md einen Vermerk mit Zeitstempel ein.
Aufrufe (aus dem Workspace-Root):
@@ -39,9 +40,11 @@ import unicodedata
from datetime import datetime
from pathlib import Path
from setup_workspace import repos_root
ROOT = Path(__file__).resolve().parents[1]
EINGANG = ROOT / "input"
PROZESSE = ROOT / "prozesse"
BIBLIOTHEK = repos_root() / "Prozessbibliothek" # eigenes Repository (ADR 0004), wie in pruefe_prozesse.py
ENTWUERFE = ROOT / "entwuerfe"
SKILL = ROOT / ".agents" / "skills" / "sn-bpmn"
@@ -103,7 +106,7 @@ def setze_vermerk(pfad: Path, ergebnis: str, ziel: str, jetzt: datetime | None =
# ------------------------------------------------------------ Einordnung ---
def slug(text: str) -> str:
"""Ordnername nach ADR 0003: Kleinbuchstaben, Ziffern, Bindestriche; Umlaute ausgeschrieben."""
"""Ordnername nach ADR 0004: Kleinbuchstaben, Ziffern, Bindestriche; Umlaute ausgeschrieben."""
text = text.lower()
for alt, neu in (("ä", "ae"), ("ö", "oe"), ("ü", "ue"), ("ß", "ss")):
text = text.replace(alt, neu)
@@ -138,16 +141,16 @@ def ist_arbeitsschritt_md(text: str) -> bool:
def bestand() -> list[dict]:
"""Vorhandene Prozesse (prozesse/) und lokale Entwürfe (entwuerfe/) mit Titel und Wörtern."""
"""Vorhandene Prozesse (Prozessbibliothek) und lokale Entwürfe (entwuerfe/) mit Titel und Wörtern."""
eintraege = []
if PROZESSE.is_dir():
for ordner in sorted(p for p in PROZESSE.iterdir() if p.is_dir()):
if BIBLIOTHEK.is_dir():
for ordner in sorted(p for p in BIBLIOTHEK.iterdir() if p.is_dir() and not p.name.startswith(".")):
md = ordner / f"{ordner.name}.md"
text = md.read_text(encoding="utf-8") if md.is_file() else ""
readme = ordner / "README.md"
titel = titel_von(readme.read_text(encoding="utf-8"), ordner.name) if readme.is_file() else ordner.name
eintraege.append({"art": "Prozess", "name": ordner.name, "titel": titel_von(text, titel),
"pfad": ordner.relative_to(ROOT).as_posix() + "/", "woerter": woerter(text)})
"pfad": f"{BIBLIOTHEK.name}/{ordner.name}/", "woerter": woerter(text)})
if ENTWUERFE.is_dir():
for md in sorted(ENTWUERFE.glob("*.md")):
if re.match(r"^\d{8}-\d{6}-(issue|kommentar)-", md.name):
@@ -261,7 +264,7 @@ def main() -> int:
v = unter.add_parser("vermerk", help="Einlese-Vermerk in eine .md schreiben")
v.add_argument("datei", help="Datei in input/")
v.add_argument("--ergebnis", required=True, choices=ERGEBNISSE)
v.add_argument("--ziel", required=True, help="wo das Ergebnis liegt, z. B. entwuerfe/<name>.md oder prozesse/<name>/")
v.add_argument("--ziel", required=True, help="wo das Ergebnis liegt, z. B. entwuerfe/<name>.md oder Prozessbibliothek/<name>/")
args = ap.parse_args()
if args.befehl == "vermerk":
+49 -15
View File
@@ -1,7 +1,9 @@
#!/usr/bin/env python3
"""Prüft die versionierten Prozessmodelle unter prozesse/ und die Beispiele des Skills sn-bpmn.
"""Prüft die versionierten Prozessmodelle der Prozessbibliothek und die Beispiele des Skills sn-bpmn.
Jeder Prozess liegt in einem eigenen Ordner prozesse/<name>/ mit genau drei Dateien:
Die Prozessbibliothek ist ein eigenes Repository (AG_Prozesse/Prozessbibliothek, ADR 0004). Sie wird von
scripts/setup_workspace.py neben Projektwissen geklont – in den Workspace-Ordner oder nach repos_root aus
workspace.local.toml. Jeder Prozess liegt dort in einem eigenen Ordner <name>/ mit genau drei Dateien:
README.md Steckbrief mit Status, Stand, Zuständigkeit (Vorlage docs/vorlagen/prozess_readme.md)
<name>.md Arbeitsschritt-Beschreibung – die maßgebliche Quelle
@@ -11,12 +13,17 @@ Geprüft wird:
* Ordnername in Kleinbuchstaben, Ziffern und Bindestrichen,
* genau diese drei Dateien, keine weiteren (Originalunterlagen gehören nach referenz/),
* README.md nennt einen gültigen Status (Entwurf | abgenommen),
* <name>.md lässt sich umwandeln, und <name>.bpmn ist byte-gleich mit dem Ergebnis.
* <name>.md lässt sich umwandeln, und <name>.bpmn ist byte-gleich mit dem Ergebnis,
* in der Wurzel der Bibliothek liegen außer den Prozessordnern nur README.md, AGENTS.md, CLAUDE.md,
.gitattributes und .gitignore.
Ist die Bibliothek nicht geklont, ist das kein Befund; es werden nur die Beispiele geprüft, und ein Hinweis
nennt den Befehl zum Klonen.
Die Beispiele in .agents/skills/sn-bpmn/beispiele/ werden auf die letzte Bedingung geprüft.
Aufrufe (aus dem Workspace-Root):
python scripts/pruefe_prozesse.py # alles prüfen
python scripts/pruefe_prozesse.py --erzeugen # alle .bpmn aus ihren .md neu erzeugen, dann prüfen
Die neu erzeugten .bpmn der Bibliothek werden dort auf einem eigenen Branch committet (eigener Pull Request).
Exit-Code: 0 = in Ordnung, 1 = mindestens ein Befund.
"""
@@ -28,9 +35,11 @@ import re
import sys
from pathlib import Path
from setup_workspace import repos_root
ROOT = Path(__file__).resolve().parents[1]
SKILL = ROOT / ".agents" / "skills" / "sn-bpmn"
PROZESSE = ROOT / "prozesse"
BIBLIOTHEK = repos_root() / "Prozessbibliothek"
BEISPIELE = SKILL / "beispiele"
sys.path.insert(0, str(SKILL))
@@ -38,6 +47,8 @@ import md_to_bpmn # noqa: E402 (liegt im Skill-Ordner, nicht als Paket install
ORDNERNAME = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
STATUSWERTE = ("Entwurf", "abgenommen")
# Dateien, die in der Wurzel der Bibliothek neben den Prozessordnern liegen dürfen
REPO_DATEIEN = {"README.md", "AGENTS.md", "CLAUDE.md", ".gitattributes", ".gitignore"}
STATUSZEILE = re.compile(r"^\|\s*Status\s*\|\s*(?P<wert>[^|]*?)\s*\|", re.MULTILINE)
@@ -49,10 +60,13 @@ def erzeuge_bpmn(md_pfad: Path) -> bytes:
def _relativ(pfad: Path) -> str:
try:
return pfad.relative_to(ROOT).as_posix()
except ValueError:
return pfad.as_posix()
"""Pfad für Meldungen: relativ zum Workspace, Bibliotheks-Pfade beginnend mit „Prozessbibliothek/“."""
for basis in (ROOT, BIBLIOTHEK.parent):
try:
return pfad.relative_to(basis).as_posix()
except ValueError:
pass
return pfad.as_posix()
def pruefe_modell(md_pfad: Path) -> list[str]:
@@ -102,21 +116,39 @@ def pruefe_ordner(ordner: Path) -> list[str]:
return befunde
def prozessordner(wurzel: Path = PROZESSE) -> list[Path]:
return sorted(p for p in wurzel.iterdir() if p.is_dir()) if wurzel.is_dir() else []
def prozessordner(wurzel: Path = BIBLIOTHEK) -> list[Path]:
"""Prozessordner der Bibliothek; .git und andere Punkt-Ordner zählen nicht."""
if not wurzel.is_dir():
return []
return sorted(p for p in wurzel.iterdir() if p.is_dir() and not p.name.startswith("."))
def beispiele(wurzel: Path = BEISPIELE) -> list[Path]:
return sorted(wurzel.glob("*.md")) if wurzel.is_dir() else []
def pruefe_alles() -> list[str]:
def pruefe_bibliothek(wurzel: Path = BIBLIOTHEK) -> list[str]:
"""Befunde zur Wurzel der Bibliothek und zu allen Prozessordnern; leer, wenn sie nicht geklont ist."""
befunde: list[str] = []
if PROZESSE.is_dir():
for fremd in sorted(p for p in PROZESSE.iterdir() if p.is_file() and p.name != "README.md"):
befunde.append(f"{_relativ(fremd)}: Dateien gehören in einen Prozessordner prozesse/<name>/")
for ordner in prozessordner():
if not wurzel.is_dir():
return befunde
for fremd in sorted(p for p in wurzel.iterdir() if p.is_file() and p.name not in REPO_DATEIEN):
befunde.append(f"{_relativ(fremd)}: Dateien gehören in einen Prozessordner <name>/")
for ordner in prozessordner(wurzel):
befunde += pruefe_ordner(ordner)
return befunde
def hinweis_bibliothek(wurzel: Path = BIBLIOTHEK) -> str:
"""Hinweis, wenn die Bibliothek nicht geklont ist; sonst leer."""
if wurzel.is_dir():
return ""
return (f"Hinweis: Prozessbibliothek nicht geklont ({wurzel.as_posix()}) – nur die Beispiele geprüft. "
f"Klonen mit: python scripts/setup_workspace.py")
def pruefe_alles() -> list[str]:
befunde = pruefe_bibliothek()
for md_pfad in beispiele():
befunde += pruefe_modell(md_pfad)
return befunde
@@ -145,6 +177,8 @@ def main() -> int:
befunde = pruefe_alles()
for befund in befunde:
print(befund)
if hinweis := hinweis_bibliothek():
print(hinweis)
anzahl = len(prozessordner())
status = "GRÜN" if not befunde else "ROT"
print(f"{status}: {len(befunde)} Befund/e, {anzahl} Prozess(e), {len(beispiele())} Beispiel(e).")
+1 -1
View File
@@ -6,7 +6,7 @@ Das Skript erzeugt daraus eine einzelne, in sich geschlossene HTML-Datei (Biblio
eingebettet) und öffnet sie im Standardbrowser. Es wird nichts übertragen; die Seite lädt nichts aus dem Netz.
Aufrufe (aus dem Workspace-Root):
python scripts/vorschau.py prozesse/antrag-pruefen/antrag-pruefen.bpmn
python scripts/vorschau.py Prozessbibliothek/antrag-pruefen/antrag-pruefen.bpmn
python scripts/vorschau.py entwuerfe/antrag-pruefen.md # .md wird vorher umgewandelt
python scripts/vorschau.py <datei> --ausgabe vorschau.html --nicht-oeffnen
python scripts/vorschau.py --stdin < datei.bpmn > vorschau.html # Filter, z. B. als Gitea-Renderer
+24 -7
View File
@@ -22,18 +22,18 @@ FESTE_ZEIT = datetime(2026, 9, 23, 14, 5, 12, tzinfo=timezone(timedelta(hours=2)
@pytest.fixture
def ws(tmp_path, monkeypatch):
"""Leerer Workspace mit input/, prozesse/ und entwuerfe/ an Stelle des echten."""
for name in ("input", "prozesse", "entwuerfe"):
"""Leerer Workspace mit input/, entwuerfe/ und geklonter Prozessbibliothek an Stelle des echten."""
for name in ("input", "Prozessbibliothek", "entwuerfe"):
(tmp_path / name).mkdir()
monkeypatch.setattr(einlesen, "ROOT", tmp_path)
monkeypatch.setattr(einlesen, "EINGANG", tmp_path / "input")
monkeypatch.setattr(einlesen, "PROZESSE", tmp_path / "prozesse")
monkeypatch.setattr(einlesen, "BIBLIOTHEK", tmp_path / "Prozessbibliothek")
monkeypatch.setattr(einlesen, "ENTWUERFE", tmp_path / "entwuerfe")
return tmp_path
def lege_prozess_an(ws, name, text):
ordner = ws / "prozesse" / name
ordner = ws / "Prozessbibliothek" / name
ordner.mkdir()
(ordner / f"{name}.md").write_text(text, encoding="utf-8")
(ordner / "README.md").write_text(f"# {name}\n\n| | |\n|---|---|\n| Status | Entwurf |\n", encoding="utf-8")
@@ -92,11 +92,11 @@ def test_neue_md_mit_titel_namensvorschlag_und_art(ws):
def test_gleichnamiger_prozess_wird_als_kandidat_mit_1_gemeldet(ws):
"""Prüft, dass ein vorhandener Prozess mit gleichem Ordnernamen als Kandidat mit Ähnlichkeit 1 erscheint."""
"""Prüft, dass ein Prozess der Bibliothek mit gleichem Ordnernamen als Kandidat mit Ähnlichkeit 1 erscheint."""
lege_prozess_an(ws, "antrag-pruefen", ARBEITSSCHRITTE)
(ws / "input" / "neu.md").write_text(ARBEITSSCHRITTE.replace("erfassen", "prüfen"), encoding="utf-8")
kandidaten = eintrag(einlesen.pruefe_eingang(), "neu.md")["kandidaten"]
assert kandidaten[0]["pfad"] == "prozesse/antrag-pruefen/"
assert kandidaten[0]["pfad"] == "Prozessbibliothek/antrag-pruefen/"
assert kandidaten[0]["aehnlichkeit"] == 1.0
@@ -117,6 +117,23 @@ def test_gitea_entwuerfe_zaehlen_nicht_zum_bestand(ws):
assert einlesen.pruefe_eingang()["bestand"] == []
def test_punktordner_der_bibliothek_zaehlen_nicht_zum_bestand(ws):
"""Prüft, dass .git und andere Punkt-Ordner im Bibliotheks-Klon nicht als Prozess gelten."""
(ws / "Prozessbibliothek" / ".git").mkdir()
assert einlesen.pruefe_eingang()["bestand"] == []
def test_bibliothek_ausserhalb_des_workspace_wird_mit_ihrem_namen_genannt(ws, tmp_path_factory, monkeypatch):
"""Prüft, dass ein Prozess auch dann als 'Prozessbibliothek/<name>/' erscheint, wenn der Klon woanders liegt."""
anderswo = tmp_path_factory.mktemp("klone") / "Prozessbibliothek"
anderswo.mkdir()
monkeypatch.setattr(einlesen, "BIBLIOTHEK", anderswo)
ordner = anderswo / "antrag-pruefen"
ordner.mkdir()
(ordner / "antrag-pruefen.md").write_text(ARBEITSSCHRITTE, encoding="utf-8")
assert [e["pfad"] for e in einlesen.pruefe_eingang()["bestand"]] == ["Prozessbibliothek/antrag-pruefen/"]
def test_vermerk_steht_oben_mit_zeitstempel_und_markiert_als_eingelesen(ws):
"""Prüft, dass der Vermerk als erste Zeile mit Zeitstempel geschrieben wird und die Datei danach als eingelesen gilt."""
datei = ws / "input" / "antrag.md"
@@ -156,7 +173,7 @@ def test_zweiter_vermerk_kommt_obenauf_der_erste_bleibt(ws):
datei = ws / "input" / "antrag.md"
datei.write_text(ARBEITSSCHRITTE, encoding="utf-8")
einlesen.setze_vermerk(datei, "neu", "entwuerfe/antrag-pruefen.md", jetzt=FESTE_ZEIT)
einlesen.setze_vermerk(datei, "aktualisiert", "prozesse/antrag-pruefen/", jetzt=FESTE_ZEIT + timedelta(days=1))
einlesen.setze_vermerk(datei, "aktualisiert", "Prozessbibliothek/antrag-pruefen/", jetzt=FESTE_ZEIT + timedelta(days=1))
zeilen = datei.read_text(encoding="utf-8").splitlines()
assert "2026-09-24" in zeilen[0] and "aktualisiert" in zeilen[0]
assert "2026-09-23" in zeilen[1] and "| neu |" in zeilen[1]
+40 -3
View File
@@ -1,5 +1,6 @@
"""Tests für scripts/pruefe_prozesse.py und für den Bestand unter prozesse/ – reines Python/pytest."""
"""Tests für scripts/pruefe_prozesse.py und für den Bestand der Prozessbibliothek – reines Python/pytest."""
import sys
import warnings
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
@@ -32,11 +33,47 @@ def lege_prozess_an(wurzel, name="test-prozess", status="Entwurf"):
return ordner
def test_bestand_unter_prozesse_und_beispiele_ist_konsistent():
"""Prüft, dass alle Prozessordner und Skill-Beispiele im Repository ohne Befund sind."""
def test_bestand_der_bibliothek_und_beispiele_ist_konsistent():
"""Prüft, dass alle Prozessordner der geklonten Prozessbibliothek und die Skill-Beispiele ohne Befund sind."""
if not pp.BIBLIOTHEK.is_dir():
warnings.warn(f"Prozessbibliothek nicht geklont ({pp.BIBLIOTHEK}) – nur die Skill-Beispiele geprüft. "
"Klonen mit: python scripts/setup_workspace.py")
assert pp.pruefe_alles() == []
def test_bibliothek_liegt_als_klon_neben_projektwissen():
"""Prüft, dass die Prozessbibliothek unter dem Klon-Ordner aus workspace.toml/workspace.local.toml gesucht wird."""
import setup_workspace
assert pp.BIBLIOTHEK == setup_workspace.repos_root() / "Prozessbibliothek"
def test_prozessordner_ohne_punktordner(tmp_path):
"""Prüft, dass .git und andere Punkt-Ordner im Bibliotheks-Klon nicht als Prozess gelten."""
lege_prozess_an(tmp_path)
(tmp_path / ".git").mkdir()
(tmp_path / ".gitea").mkdir()
assert [o.name for o in pp.prozessordner(tmp_path)] == ["test-prozess"]
def test_fremde_datei_in_der_bibliothekswurzel_wird_gemeldet(tmp_path):
"""Prüft, dass in der Wurzel der Bibliothek nur die Repo-Dateien erlaubt sind und alles andere gemeldet wird."""
lege_prozess_an(tmp_path)
for erlaubt in ("README.md", "AGENTS.md", "CLAUDE.md", ".gitattributes", ".gitignore"):
(tmp_path / erlaubt).write_text("", encoding="utf-8")
(tmp_path / "antrag.bpmn").write_text("", encoding="utf-8")
befunde = pp.pruefe_bibliothek(tmp_path)
assert len(befunde) == 1 and "antrag.bpmn" in befunde[0]
def test_fehlende_bibliothek_ist_kein_befund_aber_ein_hinweis(tmp_path):
"""Prüft, dass eine nicht geklonte Bibliothek keinen Befund, aber einen Hinweis auf setup_workspace.py ergibt."""
fehlt = tmp_path / "Prozessbibliothek"
assert pp.pruefe_bibliothek(fehlt) == []
assert "setup_workspace.py" in pp.hinweis_bibliothek(fehlt)
fehlt.mkdir()
assert pp.hinweis_bibliothek(fehlt) == ""
def test_es_gibt_mindestens_ein_beispiel():
"""Prüft, dass der Abgleich .md/.bpmn wenigstens an den Skill-Beispielen tatsächlich greift."""
assert pp.beispiele(), "keine Beispiele in .agents/skills/sn-bpmn/beispiele/"
+1 -1
View File
@@ -8,7 +8,7 @@ Grundlage ist [bpmn-js](https://github.com/bpmn-io/bpmn-js), die Bibliothek hint
**Mit Python** (aus dem Workspace-Root) — öffnet die Vorschau direkt im Browser, auch für einen Entwurf:
```bash
python scripts/vorschau.py prozesse/antrag-pruefen/antrag-pruefen.bpmn
python scripts/vorschau.py Prozessbibliothek/antrag-pruefen/antrag-pruefen.bpmn
python scripts/vorschau.py entwuerfe/antrag-pruefen.md # .md wird vorher umgewandelt
```
+7 -5
View File
@@ -13,8 +13,10 @@ branch = "main"
python_min = "3.11"
# Weitere Repositories der Gruppe werden hier als eigenständige Klone eingetragen und
# von scripts/setup_workspace.py in Unterordner geklont. Derzeit gibt es keine.
#
# [[repos]]
# name = "Beispiel" # Repo-Name auf Gitea = Ordnername
# branch = "main"
# von scripts/setup_workspace.py in Unterordner geklont (Repo-Name auf Gitea = Ordnername).
# Die versionierten Prozessmodelle (ADR 0004). scripts/pruefe_prozesse.py und scripts/einlesen.py
# suchen sie unter diesem Namen.
[[repos]]
name = "Prozessbibliothek"
branch = "main"