ADRs: - 0006 Embedding-Modell-Migration v3->v4 (#123) - 0008 DDD-Lightweight-Migration (#136) Analysen: - ddd-bewertung.md (1237 Zeilen) — vollstaendige DDD-Analyse mit Tages-Roadmap - protokoll-parser-v6-machbarkeit.md (418 Zeilen) — #106 Phase 2 Vorbereitung Reference: - zugriffsrechte.md — 63 Routes x 3 User-Status, UI-Sichtbarkeits-Matrix Ops: - scripts/deploy.sh — mit Uptime-Kuma-Wartungsmodus (#149) - scripts/run-digest.sh — taeglicher Mail-Digest-Cron - scripts/run-monitoring-scan.sh — Monitoring-Scan-Cron (noch nicht aktiv) - scripts/smoke-test.sh — Gesamt-Funktionspruefung - pytest.ini: integration/slow/e2e Markers, addopts not-integration Tests/integration/: Live-Adapter-Tests + Frontend-XRef + Citation-Substring + Wahlprogramm-Indexed (4 Live-Test-Suites, marker-opt-in) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
419 lines
17 KiB
Markdown
419 lines
17 KiB
Markdown
# Plenarprotokoll-Parser v6 — Machbarkeits-Analyse
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Status** | Exploration |
|
||
| **Datum** | 2026-04-20 |
|
||
| **Refs** | Issue #106 (Abstimmungsverhalten), #126 (BL-übergreifender Parser), MEMORY `reference_nrw_protokoll_parser.md` |
|
||
| **Autor** | Claude Opus 4.7 (1M) — strukturelle Exploration, kein Code |
|
||
|
||
## Zweck
|
||
|
||
Strukturierte Bewertung, ob ein Parser v6 für das Abstimmungsverhalten in
|
||
Plenarprotokollen sinnvoll ist — und wenn ja, in welcher Architektur.
|
||
Entscheidungsgrundlage, **keine** Implementierungs-Vorgabe.
|
||
|
||
## 1. Bestandsaufnahme: v5 heute
|
||
|
||
### 1.1 Wo lebt der Parser?
|
||
|
||
**Befund:** Im Produktionscode (`webapp/app/`) existiert **kein**
|
||
`protokoll_parser.py` oder vergleichbares Modul. Grep über alle
|
||
`app/*.py` auf `parse_protokoll`, `Plenarprotokoll`, `MMP`, `Wer stimmt`,
|
||
`Damit ist der Antrag` liefert **null** Treffer in Produktions-Python —
|
||
nur ein inzidentelles `Plenarprotokoll` im Kommentar zu
|
||
`parlamente.py:986`.
|
||
|
||
Der v5-Parser ist also **POC-Code aus einer früheren Session**, der
|
||
nicht ins Repo gelangt ist. Die einzige belastbare Referenz ist die
|
||
Memory-Datei
|
||
`~/.claude/projects/…gwoe…/memory/reference_nrw_protokoll_parser.md`
|
||
(95 Zeilen, 12 Apr. 2026).
|
||
|
||
**Konsequenz:** v6 ist **kein Refactor**, sondern ein Neuaufbau. Das
|
||
reduziert Altlast-Risiko, bedeutet aber auch: es gibt keine
|
||
Baseline-Test-Fixtures im Repo, keine bestehenden Call-Sites, die
|
||
zu brechen wären. Saubere grüne Wiese.
|
||
|
||
### 1.2 Was v5 laut Memory kann
|
||
|
||
Aus `reference_nrw_protokoll_parser.md` (zur Orientierung, nicht als
|
||
Autorität — Memory ist 8 Tage alt):
|
||
|
||
**Input:** PDF-Text von `landtag.nrw.de/.../MMP{WP}-{N}.pdf`, nach
|
||
Worttrennungs-Auflösung (`-\s*\n\s*` → `""`) und
|
||
Whitespace-Normalisierung.
|
||
|
||
**Anchor-Phrasen für Ergebnis-Klassifikation:**
|
||
|
||
```
|
||
Damit ist der Antrag [Drucksache X] angenommen|abgelehnt
|
||
Damit ist der Gesetzentwurf [Drucksache X] angenommen|abgelehnt
|
||
Damit ist dieser Antrag Drucksache X angenommen|abgelehnt
|
||
Damit ist (diese|die) Überweisungsempfehlung … angenommen → überwiesen
|
||
Somit ist dieser Antrag Drucksache X abgelehnt
|
||
```
|
||
|
||
**Segment-Boundaries** (trennen Abstimmungen im selben TOP):
|
||
|
||
```
|
||
Damit kommen wir zur Abstimmung
|
||
Wir kommen (somit )?zur Abstimmung
|
||
Wir stimmen (?!zu)
|
||
Somit kommen wir (direkt )?zu den Abstimmungen
|
||
```
|
||
|
||
**Vote-Pattern** (Ja/Nein/Enthaltung):
|
||
|
||
- `Wer stimmt … zu? – Das (ist|sind) [Fraktionen]` → Ja-Stimmer
|
||
- `Wer stimmt dagegen?` / `Wer lehnt … ab?` → Nein-Stimmer
|
||
- `Wer enthält sich?` / `Gibt es Enthaltungen?` → Enthaltungen
|
||
|
||
**Negations-Antworten** (= leere Liste): `niemand`, `Keine
|
||
Gegenstimmen`, `nicht der Fall`, `Auch nicht`.
|
||
|
||
**Sonderfälle:**
|
||
- Re-Vote (Präsident unterbricht): „Vielleicht sind sich dann alle
|
||
einig." → letzte Instanz im Segment zählt.
|
||
- Beschlussempfehlung-vs-Gesetzentwurf: abgestimmt wird über den
|
||
Gesetzentwurf, die Empfehlungs-DS ist `nicht_gesondert_abgestimmt`.
|
||
- Protokoll-Typo (MMP18-115): Anchor nennt falsche DS → Segment-Entry-DS
|
||
hat Vorrang (v6-Forderung).
|
||
- Petitions-Sammelüberweisung (Drucksache 18/33 = Übersicht) →
|
||
Einzelpetitionen haben **kein** Ergebnis.
|
||
|
||
### 1.3 Validierungs-Stand v5
|
||
|
||
| Protokoll | Treffer | Bemerkung |
|
||
|---|---|---|
|
||
| MMP18-119 (Training) | 19/19 | 100 % Precision **und** Recall |
|
||
| MMP18-115 | 10/32 | fehlende Anchor-Varianten |
|
||
| MMP18-110 | 17/6 | Sammel-Petitions-Einzelansprache (False Positives) |
|
||
| MMP18-100 | 8/25 | ähnlich wie MMP18-115 |
|
||
|
||
**Interpretation:** v5 ist **overfit auf MMP18-119**. Präzision bleibt
|
||
hoch (keine falschen Abstimmungs-Ergebnisse), aber der Recall-Einbruch
|
||
auf ~30-50 % schon **innerhalb** NRW zeigt: die Anchor-Liste deckt nicht
|
||
einmal NRW-interne Variation ab. Cross-BL wird drastisch schlechter.
|
||
|
||
## 2. Cross-BL-Strukturanalyse
|
||
|
||
### 2.1 Sample-Verfügbarkeit im Repo
|
||
|
||
**Befund:** **Keine** Plenarprotokoll-Samples im Repo.
|
||
|
||
Geprüfte Pfade:
|
||
- `webapp/tests/fixtures/` → leer (nur Sub-Dir-Marker, keine Dateien)
|
||
- `webapp/app/static/` → nur Wahlprogramm-PDFs
|
||
- `webapp/data/` → nur `gwoe-antraege.db` (SQLite)
|
||
- `antraege/` (Projekt-Root) → 80+ PDFs, aber alle Drucksachen
|
||
(Anträge), keine MMP-Protokolle
|
||
- `TEMP/` → HAR-Captures der Dokumentations-Frontends, keine PDFs
|
||
|
||
Keine einzige `MMP*.pdf` oder `PlPr*.pdf` im gesamten Projekt-Tree.
|
||
|
||
### 2.2 Strukturelle Annahmen aus Doku-Systemen
|
||
|
||
Ohne Samples ist eine echte Struktur-Analyse nicht möglich. Aus
|
||
`app/bundeslaender.py` und `app/parlamente.py` lassen sich nur
|
||
**Plausibilitäts-Hypothesen** ableiten:
|
||
|
||
| Familie | BL | Protokoll-Quirk (Hypothese) |
|
||
|---|---|---|
|
||
| OPAL | NRW | MMP-PDF, stereotyp (v5-Referenz) |
|
||
| StarWeb/portala | HE, SH, BB, RP, LSA, BE | Plenarprotokolle typischerweise als PDF mit Zweispalten-Layout |
|
||
| ParlDok | MV, HH, TH | eigene Redaktionsrichtlinie pro LT |
|
||
| PARiS | HB | Bürgerschaft, Kleinst-Parlament |
|
||
| Eigensystem | BY, SL, SN | je eigene Typografie |
|
||
| DIP (BUND) | BUND | Plenarprotokolle als **strukturiertes XML** verfügbar — Ausnahme! |
|
||
|
||
**Wichtig:** Die Adapter in `parlamente.py` liefern bisher **Drucksachen**
|
||
(Anträge), nicht Plenarprotokolle. Für Protokoll-Download müssten die
|
||
Adapter erweitert werden — das ist Teil des Scopes von #106.
|
||
|
||
### 2.3 Fraktions-Namen-Normalisierung — vorhanden
|
||
|
||
`app/parteien.py:187` bietet `normalize_partei(raw, *, bundesland=None)`,
|
||
das laut Docstring die vier Adapter-eigenen `_normalize_fraktion()`
|
||
ersetzt. Das ist **entscheidend**, weil Protokolle Fraktionen in ihrer
|
||
LT-spezifischen Schreibweise nennen (`BÜNDNIS 90/DIE GRÜNEN`,
|
||
`GRÜNE`, `B'90/Grüne`). Die Komponente ist da und getestet — v6 muss
|
||
sie nicht neu bauen.
|
||
|
||
## 3. Lösungs-Ansätze
|
||
|
||
### 3.1 Option A — Rule-based expand (v5 pro BL)
|
||
|
||
Pro Bundesland eine `abstimmung_rules_<bl>.yaml` mit BL-spezifischen
|
||
Anchors, Segment-Boundaries, Vote-Patterns. Ein generischer Engine-
|
||
Kern lädt die Rules und parst.
|
||
|
||
**Pro:**
|
||
- Deterministisch, reproduzierbar, offline.
|
||
- Null Laufzeit-Kosten, Millisekunden pro Protokoll.
|
||
- Präzision bleibt bei 100 % (nur bekannte Anchors matchen).
|
||
|
||
**Contra:**
|
||
- **Recall-Problem überträgt sich** linear auf 17 BL. v5 schafft in NRW
|
||
schon nur 30-50 % auf unbekannten Protokollen — 17-fach skaliert
|
||
heißt: pro BL eigene Overfit-Runde.
|
||
- Format-Drift zwischen Wahlperioden (neues Redaktionsteam, neuer
|
||
Stilführer) bricht still.
|
||
- Wartungs-Aufwand: geschätzt 2-3 Tage Reverse-Engineering pro BL, plus
|
||
~0,5 Tage Nachpflege pro WP-Wechsel.
|
||
|
||
**Aufwand:** 2-3 Tage pro BL × 17 = **34-51 Personentage** bis
|
||
Vollabdeckung. Pro BL-Nachpflege alle 4-5 Jahre.
|
||
|
||
**Risiko:** Stille Recall-Einbrüche, die nur durch Ground-Truth-Tests
|
||
entdeckt werden. Ohne kontinuierliches Fixture-Update degradiert die
|
||
Datenqualität.
|
||
|
||
### 3.2 Option B — LLM-Extraction pro Seite
|
||
|
||
Ein strukturiertes Prompt nimmt eine Protokoll-Seite (oder einen
|
||
10-Seiten-Block) und liefert JSON:
|
||
|
||
```json
|
||
{
|
||
"abstimmungen": [
|
||
{
|
||
"drucksache": "18/17492",
|
||
"titel": "…",
|
||
"ergebnis": "angenommen|abgelehnt|überwiesen",
|
||
"ja": ["CDU", "GRÜNE"],
|
||
"nein": ["SPD", "AfD", "FDP"],
|
||
"enthaltung": [],
|
||
"namentlich": false
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**Pro:**
|
||
- Ein Prompt für alle 17 BL, Format-Drift-robust.
|
||
- Nutzt bestehende LLM-Pipeline (`analyzer.py`, Qwen-Plus).
|
||
- Neue BL kosten **null** Entwicklungs-Zeit nach Grund-Integration.
|
||
- Zitat-Binding-Pattern aus ADR 0001 direkt übertragbar (Post-LLM-Match
|
||
gegen Protokoll-Text, genau wie bei Wahlprogramm-Zitaten).
|
||
|
||
**Contra:**
|
||
- **Kosten:** ein Protokoll hat 120-200 Seiten. Bei 10 Seiten pro
|
||
Prompt-Call: ~15-20 Calls × ~0,03 €/Call bei Qwen-Plus = **0,45-0,60 €
|
||
pro Protokoll**. NRW-WP18 hat ~170 Plenarsitzungen → ~85 € allein für
|
||
NRW, ~1500 € für alle 17 BL × 1 WP. Erträglich, aber nicht trivial.
|
||
- **Laufzeit:** 15-20 Calls × 10 s = 2,5-3 min pro Protokoll.
|
||
- **LLM-Halluzinationen:** ADR 0001 zeigt, dass Zitate cross-mixen.
|
||
Hier: Gefahr, dass LLM ein Abstimmungs-Ergebnis halluziniert, das im
|
||
Protokoll nicht vorkommt. Citation-Binding gegen Protokoll-Text ist
|
||
Pflicht.
|
||
|
||
**Aufwand:** Grund-Integration 3-5 Tage (Prompt-Engineering + Citation-
|
||
Binding analog ADR 0001 + Cache-Layer, damit dasselbe Protokoll nicht
|
||
zweimal abgefragt wird). Pro BL **null** zusätzlich.
|
||
|
||
**Risiko:** LLM-Halluzinationen bei stillem Citation-Binding-Bug;
|
||
Kosten-Explosion wenn alle WPs voll nachgefahren werden.
|
||
|
||
### 3.3 Option C — Hybrid: Rules-Pre-Filter + LLM-Strukturierung
|
||
|
||
**Stufe 1 (Rules):** Ein universelles Regex-Set (wenige, stabile
|
||
Anchors) segmentiert das Protokoll in **Abstimmungs-Kandidat-Blöcke**.
|
||
Kandidat: Text zwischen zwei `Abstimmung|stimmen ab|stimmen … zu`-
|
||
Vorkommen.
|
||
|
||
**Stufe 2 (LLM):** Jeder Kandidat-Block (~500-2000 Tokens) wird an den
|
||
LLM gegeben mit dem Prompt „Extrahiere Drucksache, Ergebnis, Ja/Nein/
|
||
Enthaltung-Fraktionen. Nur was im Text steht."
|
||
|
||
**Stufe 3 (Verifier):** Jede extrahierte Fraktion wird gegen
|
||
`normalize_partei()` geprüft und gegen `BUNDESLAENDER[bl]
|
||
.landtagsfraktionen` gefiltert. Halluzinierte Fraktionen (nicht im LT
|
||
vertreten) werden gedroppt oder loggen einen Warn.
|
||
|
||
**Pro:**
|
||
- Kosten ~80 % niedriger als Option B (nur Kandidat-Blöcke, nicht
|
||
ganze Seiten).
|
||
- BL-übergreifend, weil Stufe 1 nur grobe Anchors braucht (`stimmen`,
|
||
`Abstimmung` als Lemma-Formen sind in allen dt. Parlamenten üblich).
|
||
- Verifier fängt die meisten Halluzinationen ab.
|
||
- Skaliert auf neue BL mit nahezu null Zusatz-Aufwand.
|
||
|
||
**Contra:**
|
||
- Drei Stufen = drei Stellen, an denen Bugs sein können.
|
||
- Stufe 1 kann Kandidaten übersehen (stille Recall-Lücke). Debuggable
|
||
über „kein Kandidat gefunden"-Log.
|
||
- Komplexer zu testen als reine Rules oder reines LLM.
|
||
|
||
**Aufwand:** 5-7 Tage Grund-Integration. Pro BL: 0,5 Tag (einmal
|
||
Kalibrierung der Stufe-1-Anchors mit einem Protokoll-Sample).
|
||
|
||
**Risiko:** Mittel. Komplexität ist höher, aber jede Stufe isoliert
|
||
testbar. Analog zur LLM-Citation-Binding-Architektur aus ADR 0001.
|
||
|
||
### 3.4 Bewertungs-Matrix
|
||
|
||
| Kriterium | A (Rules) | B (LLM-voll) | C (Hybrid) |
|
||
|---|---|---|---|
|
||
| Precision (erwartet) | 95-100 % | 85-95 % | 90-98 % |
|
||
| Recall (erwartet) | 30-60 % pro BL | 85-95 % | 80-92 % |
|
||
| Entwicklung (Tage) | 34-51 | 3-5 | 5-7 |
|
||
| Laufzeit-Kosten/Prot. | ~0 € | ~0,50 € | ~0,10 € |
|
||
| Skaliert auf neue BL | nein (linear) | ja (gratis) | ja (halbgratis) |
|
||
| Format-Drift-Robustheit | niedrig | hoch | mittel-hoch |
|
||
| Debug-Transparenz | hoch | niedrig | mittel |
|
||
| Offline-fähig | ja | nein | nein |
|
||
|
||
## 4. Entscheidungs-Baum
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([Issue #106: Abstimmungsverhalten]) --> Samples{Plenarprotokoll-<br/>Samples<br/>beschaffbar?}
|
||
Samples -->|nein| Stop1[STOP:<br/>Sample-Beschaffung zuerst]
|
||
Samples -->|ja, ≥3 BL| Scope{Scope<br/>klar?}
|
||
Scope -->|nur NRW, kurzfristig| OptA[Option A<br/>v5 härten auf NRW]
|
||
Scope -->|alle 17 BL| OptFamily{Kosten-Bereitschaft<br/>für LLM-Calls?}
|
||
OptFamily -->|nein, offline nötig| OptA_scaled[Option A:<br/>Rule-Engine pro BL<br/>34-51 Tage]
|
||
OptFamily -->|ja, 1500 €/WP OK| OptC[Option C Hybrid:<br/>5-7 Tage Grund<br/>+ 0,5 Tag/BL]
|
||
OptC --> POC[POC auf 2 BL:<br/>NRW + HE<br/>Ground-Truth-Set je 3 Prot.]
|
||
POC --> Eval{Recall<br/>≥ 80 % auf HE?}
|
||
Eval -->|ja| Rollout[Rollout auf 17 BL]
|
||
Eval -->|nein| Rethink[LLM-Prompt iterieren<br/>oder auf B eskalieren]
|
||
OptA_scaled --> NRW_first[NRW zuerst,<br/>dann nach Output-Ranking]
|
||
```
|
||
|
||
## 5. Empfehlung
|
||
|
||
### 5.1 Familie
|
||
|
||
**Option C (Hybrid)** als Primärweg. Begründung:
|
||
|
||
1. Die bestehende Architektur passt: `analyzer.py` nutzt schon LLM,
|
||
ADR 0001 liefert das Binding-Pattern, `parteien.py:normalize_partei`
|
||
gibt den Verifier.
|
||
2. Option A skaliert nicht auf 17 BL ohne Personen-Aufwand, den das
|
||
Projekt realistisch nicht hat (siehe Issue-Backlog).
|
||
3. Option B hat das Halluzinations-Risiko und Kosten ohne Gewinn
|
||
gegenüber C.
|
||
|
||
### 5.2 Minimum-Viable-Scope
|
||
|
||
1. **Protokoll-Download-Erweiterung der Adapter:** `get_plenarprotokoll
|
||
(wp, sitzung)` als optionale Methode. Zuerst nur NRW + 1 weiteres BL
|
||
(Vorschlag: BUND, weil dort XML statt PDF → erleichtert
|
||
Text-Extraktion).
|
||
2. **Stufe-1-Anchors** als einzige YAML-Datei (nicht pro BL), mit den
|
||
~5 stabilsten Formulierungen (`stimmen ab`, `Abstimmung über`,
|
||
`wer stimmt zu`, `wer ist dagegen`, `wer enthält sich`).
|
||
3. **Stufe-2-Prompt** mit Zitat-Binding-Anforderung (jede Fraktion
|
||
muss als Exakt-Substring im Kandidat-Block vorkommen).
|
||
4. **Stufe-3-Verifier** via `normalize_partei` und
|
||
`BUNDESLAENDER[bl].landtagsfraktionen`.
|
||
5. **Persistenz:** neue Tabelle `abstimmungen (drucksache, wp, sitzung,
|
||
ergebnis, ja_fraktionen, nein_fraktionen, enthaltung_fraktionen,
|
||
source_url, extracted_at, extractor_version)`.
|
||
|
||
### 5.3 Abbruch-Kriterien
|
||
|
||
- **Stop 1:** Wenn POC auf 2 BL nach 7 Tagen unter 70 % Recall bleibt,
|
||
ist C nicht erreicht. Fallback: B (voller Seiten-Scan) oder Parken.
|
||
- **Stop 2:** Wenn Nutzer-Interview zeigt, dass Abstimmungsverhalten
|
||
pro Drucksache **keinen Dashboard-Mehrwert** gegenüber dem bereits
|
||
aktiven Score hat, ist v6 unpriorisiert. Issue #106 hängt seit April
|
||
offen — die Frage „braucht das jemand?" ist vor Implementierung zu
|
||
klären.
|
||
- **Stop 3:** Wenn eine offene Datenquelle (z.B. `abgeordnetenwatch.de
|
||
/api`) Abstimmungsverhalten bereits strukturiert ausliefert, ist ein
|
||
eigener Parser obsolet → **Evaluations-Pflicht vor Bau**.
|
||
|
||
### 5.4 BL-Priorisierung
|
||
|
||
Nach CSV-Export `/api/auswertungen/export.csv` und Wichtigkeit:
|
||
|
||
1. **NRW** — größter Output, v5 vorhanden
|
||
2. **BUND** — XML statt PDF, einfachste Implementierung, hoher Impact
|
||
3. **HE, BY, BW** — große Flächenländer, hohe Drucksachen-Zahl
|
||
4. **BE, HH, HB** — Stadtstaaten, geringer Protokoll-Umfang, guter
|
||
Cross-Check für den Hybrid
|
||
5. Rest nach Output-Ranking aus Dashboard
|
||
|
||
## 6. Sample-Beschaffungs-Plan
|
||
|
||
Da im Repo keine Plenarprotokolle liegen, für den POC zuerst manuell
|
||
ziehen. Pro BL 1 aktuelles Protokoll:
|
||
|
||
| BL | Quelle | Format |
|
||
|---|---|---|
|
||
| NRW | `landtag.nrw.de/portal/WWW/dokumentenarchiv/Dokument/MMP{WP}-{N}.pdf` | PDF |
|
||
| BUND | `bundestag.de/services/opendata` (XML-Feed) | **XML** |
|
||
| BY | `bayern.landtag.de/parlament/dokumente/plenarprotokolle` | PDF |
|
||
| BW | `landtag-bw.de/home/dokumente/plenarprotokolle.html` | PDF |
|
||
| BE | `parlament-berlin.de/dokumente/open-data` (XML verfügbar) | XML/PDF |
|
||
| BB | `parlamentsdokumentation.brandenburg.de` (portala) | PDF |
|
||
| HB | `paris.bremische-buergerschaft.de/starweb/paris` | PDF |
|
||
| HH | `buergerschaft-hh.de/parldok` | PDF |
|
||
| HE | `starweb.hessen.de/portal` | PDF |
|
||
| MV | `dokumentation.landtag-mv.de` (ParlDok) | PDF |
|
||
| NI | `nilas.niedersachsen.de` (HAR-Capture nötig, siehe MEMORY) | PDF |
|
||
| RP | `opal.rlp.de` (portala) | PDF |
|
||
| SL | `landtag-saar.de` (Umbraco) | PDF |
|
||
| SN | `edas.landtag.sachsen.de` (XML-Export, siehe `project_sn_xml_export.md`) | **XML** |
|
||
| LSA | `padoka.landtag.sachsen-anhalt.de` (PARDOK) | PDF |
|
||
| SH | `lissh.lvn.parlanet.de/cgi-bin/starfinder/0` | PDF |
|
||
| TH | `parldok.thueringer-landtag.de` | PDF |
|
||
|
||
Speicherung unter `webapp/tests/fixtures/protokolle/<bl>/` (git-lfs
|
||
oder außerhalb des Repos, je nach Dateigröße). Pro Protokoll eine
|
||
`<protokoll>.expected.json` mit Ground-Truth-Abstimmungen als
|
||
Fixture.
|
||
|
||
**Minimum für POC:** NRW (MMP18-119 als Regression), BUND (XML als
|
||
Gegenprobe), HE (StarWeb als Cross-BL). Drei Protokolle × ~20-30
|
||
Abstimmungen = ~60-90 Ground-Truth-Items für Precision/Recall.
|
||
|
||
## 7. Offene Fragen für Tobias
|
||
|
||
1. **Bedarfs-Validierung:** Wer konsumiert das Abstimmungsverhalten
|
||
konkret im Dashboard? Gibt es eine UI-Spec dafür, oder ist das
|
||
gedachte Feature? Issue #106 nennt keine konkreten Konsumenten.
|
||
2. **LLM-Kosten:** Ist ~1500 € Budget für die 17-BL-Erstbefüllung einer
|
||
WP vertretbar? Oder muss der Rollout auf eine WP pro Jahr gedeckelt
|
||
werden?
|
||
3. **Alternative Datenquelle:** Wurde `abgeordnetenwatch.de/api`
|
||
geprüft? Die liefern auf Bundesebene strukturierte
|
||
Abstimmungsdaten und haben teilweise Landesabdeckung. Wenn ja, ist
|
||
v6 für diese BL obsolet.
|
||
4. **v5-POC-Code:** Existiert der Code noch auf der Festplatte (in
|
||
einem früheren Session-Worktree)? Ein Fundstück würde 1-2 Tage
|
||
Re-Implementations-Arbeit sparen.
|
||
|
||
## 8. Nächster Schritt (empfohlen)
|
||
|
||
1. **Vor jeder Zeile Code:** Beantworte Fragen 1 und 3 oben. Das
|
||
entscheidet, ob v6 überhaupt startet.
|
||
2. **Wenn ja:** POC auf NRW + BUND + HE mit Option C, Sample-Zug
|
||
manuell. 7 Tage Timebox.
|
||
3. **Wenn POC erfolgreich (Recall ≥ 80 %):** ADR für v6 schreiben
|
||
(analog 0001/0002), Rollout-Plan.
|
||
4. **Wenn POC scheitert:** Zurück zu Option A nur für NRW, v5-Recall-Lücken schließen, #106 auf NRW-only beschränken und #126 schließen
|
||
als „nicht wirtschaftlich".
|
||
|
||
## 9. Verifikations-Checkliste
|
||
|
||
- [x] v5-Code lokal gesucht → nicht im Repo
|
||
- [x] MEMORY-Referenz gelesen (95 Zeilen) — v5-Pattern dokumentiert
|
||
- [x] Sample-Inventar: **null Protokoll-Samples im Repo**
|
||
- [x] BL-Adapter-Architektur (ADR 0002) verstanden — `ParlamentAdapter`
|
||
hat aktuell **keine** `get_plenarprotokoll`-Methode
|
||
- [x] Fraktions-Normalisierung existiert (`parteien.py:187
|
||
normalize_partei`)
|
||
- [x] Kosten-Schätzung für Option B/C kalkuliert
|
||
- [x] Drei Optionen bewertet, Matrix + Mermaid-Diagramm
|
||
- [x] Abbruch-Kriterien formuliert
|
||
- [x] Sample-Beschaffungs-Plan für alle 17 BL
|
||
|
||
---
|
||
|
||
**Nicht in diesem Dokument:** Konkreter Code, Prompt-Vorlagen, ADR-Text
|
||
für v6. Alles nächste Phase nach Go/No-Go-Entscheidung von Tobias.
|