gwoe-antragspruefer/docs/roadmap-programme-2026-05-08.md
Dotty Dotter 176b7c5018 docs: Roadmap Programme/Legislaturen mit 11 Entscheidungen
Strategische Klärungs-Runde im Anschluss an ADR 0013 — alle 11 offenen
Fragen entschieden, in 5 Implementierungs-Blöcke strukturiert:

Block 1 — Schema-Refactor (kurz):
- gueltig_ab umstellen von Regierungsbildung auf Wahltag (B1+B2)
- CSU als Alias auf CDU-BTW-Eintrag (B3)

Block 2 — Daten-Beschaffung:
- ~50 historische Wahlprogramme indizieren (A1)
- BIW Bremen + BVB/FW Brandenburg historisch (A2)
- BSW Manifest 2023 als parteiprogramm-Eintrag (B4)

Block 3 — Infrastruktur:
- Eigener PDF-Mirror auf Toppyr-Server (C3)
- Monatlicher Cron: Parteiwebseiten-Update-Check (C1)
- Täglicher Cron: inkrementelle Reindexierung (C2)

Block 4 — Auswertungen + UI:
- Eigene Detail-Views: Regierung-im-Detail, Wahlperiode (D2)
- Programmwechsel-Diff, Treuequote-Zeitreihe, Koalitions-Shift (D1)

Block 5 — Konsolidierung + Release:
- WAHLPROGRAMME als View über programme.PROGRAMME (E2)
- analyzer.py auf zeitpunktige Helper
- v1.1.0 Production-Release (E1)

Plus Detail-Gotchas und nächster konkreter Schritt (Block 1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:03:20 +02:00

162 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Roadmap Programme/Legislaturen — Entscheidungen 2026-05-08
Ergebnis der strategischen Klärungs-Runde im Anschluss an [ADR
0013](adr/0013-programme-legislaturen-zeitpunktige-bewertung.md). Alle 11
offenen Fragen entschieden.
## Entscheidungen im Überblick
| ID | Frage | Entscheidung |
|----|-------|--------------|
| A1 | Historische Indexierung | **Volle historische Indexierung** (~50 PDFs, 3 Vorperioden × 16 BL) |
| A2 | Kleine/historische Fraktionen | **Auch historische** (BIW Bremen, BVB/FW Brandenburg) |
| B1 | Antrag vor Regierungsbildung | **Programm gilt ab Wahltag** |
| B2 | Opposition vs. Regierung | **Alle ab Wahltag** (löst B1 implizit) |
| B3 | CDU+CSU teilen Programm | **CSU als Alias auf CDU-Eintrag** |
| B4 | BSW kein Grundsatzprogramm | **Manifest 2023 als parteiprogramm-Eintrag** |
| C1 | Programm-Updates verfolgen | **Cron: monatlich Parteiwebseiten checken** |
| C2 | Reindexierung | **Cron: täglich, nur fehlende** |
| C3 | PDF-Quellen-Stabilität | **+ Eigener Mirror auf Toppyr-Server** |
| D1 | Neue Auswertungen | **Alle vier:** Programmwechsel, Treuequote, Koalitions-Shift, Regierung-im-Detail |
| D2 | UI-Investition | **Eigene Detail-Views** für Regierung & Wahlperiode |
| E1 | Prod-Deploy | **Erst nach historischer Indexierung** (v1.1.0 als Belohnung) |
| E2 | WAHLPROGRAMME konsolidieren | **Erst nach historischer Indexierung** |
## Implementierungs-Reihenfolge (logische Abhängigkeiten)
### Block 1 — Schema-Refactor (ohne neue Daten, schnell)
**1.1** B1+B2: `gueltig_ab` umstellen von Regierungsbildung auf Wahltag
- Migration: pro Wahlprogramm-Eintrag das `wahltermin` aus
`legislaturen.py` holen → `gueltig_ab = wahltermin`
- `regierungsbildung` bleibt erhalten für die UI-Anzeige "Regierung zur
Antragszeit" (Bewertungs-Kontext)
- Tests anpassen: B1 (vor-Regierungsbildung) liefert nun das Wahlprogramm
ab Wahltag
**1.2** B3: CSU-Alias-Mechanismus
- Optionales `alias_of`-Feld im Programm-Schema
- `csu-bund-2025` wird zu `{"alias_of": "cdu-bund-2025", ...}`
- Lookup-Helper resolvt Aliase automatisch
**Aufwand:** kurz (1-2h Code + Tests)
### Block 2 — Daten-Beschaffung (Background-Agents parallel)
**2.1** A1: 50 historische Wahlprogramme beschaffen
- 16 BL × ~3-5 Vorperioden × ~5 Parteien = ~50 PDFs
- Per Bundesland Liste + URLs zusammensuchen (Background-Agent)
- Lokale Mirrors anlegen (siehe C3)
- SHA-256 in `wahlprogramm-shas.lock.json` pinnen
**2.2** A2: Historische Fraktionen ergänzen
- BIW Bremen 2023-Programm beschaffen + im Schema (HB-Eintrag) ergänzen
- BVB/FREIE WÄHLER Brandenburg WP7 (2019-2024) beschaffen
- In `legislaturen.REGIERUNGEN` ggf. aktualisieren falls nötig
**2.3** B4: BSW Manifest 2023 indizieren
- PDF beschaffen (URL: bsw-vg.de/wp-content/uploads/2024/01/BSW_Parteiprogramm.pdf
oder neuere Version)
- Als `bsw-manifest` in `embeddings.PROGRAMME` einbauen mit
`gueltig_ab="2023-10-23"`
- programme.py: Eintrag als `grundsatzprogramm-bund` registrieren
**Aufwand:** mittel — eigene Session(en), DashScope-API-Last
### Block 3 — Infrastruktur (Cron + Mirror)
**3.1** C3: Mirror-Server-Setup
- Auf Toppyr-Server: `/var/www/programme-mirror/` als statisches PDF-Archiv
- Spiegel via rsync von `app/static/referenzen/`
- URLs in `wahlprogramm-links.yaml` um `mirror_url`-Feld erweitern
**3.2** C1: Monatlicher Cron — Parteiwebseiten-Update-Check
- `scripts/check-programm-updates.sh` per Cron alle 30 Tage
- Liest `wahlprogramm-links.yaml`, ruft jede URL ab, vergleicht SHA-256
- Bei Hash-Mismatch oder 404: Telegram-Notification an Topic 4247
- Output in `data/programm-updates.log`
**3.3** C2: Täglicher Cron — inkrementelles Reindexing
- `scripts/reindex-fehlende.sh` per Cron 03:00 Uhr
- Nutzt vorhandene `reindex_embeddings.py`-Logik (skip-already-indexed)
- Loggt in `auto_rate_runs`-ähnliche Tracking-Tabelle
**Aufwand:** kurz-mittel
### Block 4 — Auswertungen + UI (Detail-Views)
**4.1** D2: "Regierung im Detail"-View (`/regierung/{name}`)
- Pro Kabinett: Anträge der Amtszeit, Score-Verteilung, Auffälligkeiten,
Programm-Treue-Quote der Regierungsfraktionen
**4.2** D1: Programmwechsel-Diff (`/partei/{name}/programmwechsel`)
- Wahlprogramm 2017 vs. 2022 — semantischer Diff via Embeddings
- Heatmap pro GWÖ-Wert: hat sich die Programmatik verschoben?
**4.3** D1: Treuequote-Zeitreihe (`/auswertungen/treuequote`)
- Pro Regierung: % der Anträge, die ≥7 Treue-Score zum eigenen
Wahlprogramm haben → Erfüllungsgrad der Wahlversprechen
**4.4** D1: Koalitions-Shift (`/partei/{name}/koalitionen`)
- Stimmverhalten der gleichen Partei in verschiedenen Koalitionen
vergleichen
**Aufwand:** lang — eigenes Feature-Projekt
### Block 5 — Konsolidierung + Release
**5.1** E2: WAHLPROGRAMME als View über programme.PROGRAMME
- `wahlprogramme.WAHLPROGRAMME` wird `@property` auf
`programme.PROGRAMME`-Filter
- `embeddings.PROGRAMME` analog
- ~1h Code, alle Tests müssen grün bleiben
**5.2** analyzer.py auf zeitpunktige Helper migrieren
- `wahlprogramm_zum_zeitpunkt(bl, partei, antrag.datum)` statt
`WAHLPROGRAMME[bl][partei]`
- `find_relevant_chunks` mit Datum-Filter (nur Programme mit
`gueltig_ab ≤ antrag.datum < gueltig_bis`)
- Smoke-Test gegen 5 historische Anträge: stimmen die Ergebnisse?
**5.3** E1: Production-Release v1.1.0
- main → release/1.1 branch
- Tag v1.1.0
- Deploy auf prod (gwoe.toppyr.de) mit komplettem Stack
- ADR 0014 für Release-Bilanz
**Aufwand:** mittel
## Grobe Zeitplanung
| Block | Sessions | Wann |
|-------|----------|------|
| Block 1 (Schema-Refactor) | 1 | jederzeit |
| Block 2 (Daten-Beschaffung) | 3-5 | nach Block 1 |
| Block 3 (Infra) | 1-2 | parallel zu Block 2 möglich |
| Block 4 (Auswertungen) | 4-6 | nach Block 2 |
| Block 5 (Konsolidierung + Release) | 1-2 | als Letztes |
## Gotchas und offene Detail-Fragen
- **B1+B2 Migration:** muss in einem einzigen Commit passieren
(Schema-Bruch). Tests refactoren.
- **A2 historische Fraktionen:** BVB/FW Brandenburg ist ein Wahlbündnis,
nicht eine Partei — wie modellieren? (Optionen: als Alias auf BVB +
FW separat, oder als eigenständigen Schlüssel.)
- **B3 Alias:** wenn `csu-bund-2025` ein Alias auf `cdu-bund-2025` ist,
muss die UI klar machen "CDU+CSU teilen sich dieses Programm" und
nicht zwei separate Bewertungs-Quellen suggerieren.
- **C1 Cron:** wie unterscheidet er "neue Version desselben Programms"
von "Webseiten-Layout-Änderung mit gleichem PDF"? SHA-256-only
reicht für Layout-Tolerance nicht — alternativ: nur PDF-Bytes prüfen.
- **D1 Programmwechsel-Diff:** semantischer Diff zwischen zwei
Wahlprogrammen ist nicht trivial. Embedding-Cosine pro Chunk-Paar?
Oder summarized-by-LLM? Eigene Architektur-Entscheidung.
## Nächster konkreter Schritt
**Block 1 anfangen** — Schema-Refactor `gueltig_ab = Wahltag` und
CSU-Alias-Mechanismus. Das ist eine geschlossene Session, baut
direkt auf den bestehenden Modulen auf, und macht das Schema sauberer
für alles, was folgt.