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>
6.8 KiB
Roadmap Programme/Legislaturen — Entscheidungen 2026-05-08
Ergebnis der strategischen Klärungs-Runde im Anschluss an ADR 0013. 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
wahlterminauslegislaturen.pyholen →gueltig_ab = wahltermin regierungsbildungbleibt 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-2025wird 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.jsonpinnen
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.REGIERUNGENggf. 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-manifestinembeddings.PROGRAMMEeinbauen mitgueltig_ab="2023-10-23" - programme.py: Eintrag als
grundsatzprogramm-bundregistrieren
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.yamlummirror_url-Feld erweitern
3.2 C1: Monatlicher Cron — Parteiwebseiten-Update-Check
scripts/check-programm-updates.shper 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.shper 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.WAHLPROGRAMMEwird@propertyaufprogramme.PROGRAMME-Filterembeddings.PROGRAMMEanalog- ~1h Code, alle Tests müssen grün bleiben
5.2 analyzer.py auf zeitpunktige Helper migrieren
wahlprogramm_zum_zeitpunkt(bl, partei, antrag.datum)stattWAHLPROGRAMME[bl][partei]find_relevant_chunksmit Datum-Filter (nur Programme mitgueltig_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-2025ein Alias aufcdu-bund-2025ist, 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.