MR-Outcome-Tracking & Scoring-Kalibrierung: Feedback-Loop aus MR-Ergebnissen #90

Open
opened 2026-03-30 20:30:26 +00:00 by David · 0 comments
Collaborator

Beschreibung

Die Grundlage für jedes Self-Improvement: Erfassen ob MRs approved oder
rejected werden, und diese Daten nutzen um Scoring-Gewichte und
Schwellwerte automatisch zu kalibrieren.

Aktuell existieren die DB-Felder mr_outcome, mr_reviewed_at und
mr_comments_count im Ticket-Model — sie werden aber nie befüllt.
Es gibt keinen GitLab-Polling-Job und keinen Webhook-Handler. Die
Stats-API berechnet success_rate aus Daten die immer NULL sind.

Hintergrund

Ohne MR-Outcome-Daten ist kein Learning möglich:

  • Scoring-Gewichte (0.42/0.33/0.25) sind hardcoded Ratewerte
  • Schwellwerte (70/30) sind manuell konfigurierbar, aber niemand weiß ob sie optimal sind
  • False-Positive-Rate unbekannt (wie viele Autopilot-Tickets werden rejected?)
  • False-Negative-Rate unbekannt (wie viele Klärfälle wären Autopilot gewesen?)
  • success_rate im Dashboard ist immer 0% weil mr_outcome nie gesetzt wird

Dieses Issue vereint: #15 (Scoring-Kalibrierung), #16 (MR-Erfolgs-Tracking),
#19 (Feedback-Loop), #27 (GitLab Webhook/Polling), #68 (Scoring-Gewichte konfigurierbar).

Akzeptanzkriterien

MR-Outcome Erfassung

  • Neuer Scheduler-Job poll_mr_outcomes() (Intervall: 10min) in main.py
  • Pollt alle Tickets mit mr_id IS NOT NULL AND mr_outcome IS NULL
  • Setzt ticket.mr_outcome: "approved" | "changes_requested" | "closed" | "merged"
  • Setzt ticket.mr_reviewed_at beim ersten Review-Event
  • Aktualisiert ticket.mr_comments_count bei jeder Änderung
  • WebSocket-Broadcast bei Status-Änderung für Live-Dashboard

False-Positive / False-Negative Tracking

  • False Positives berechnen: Autopilot-Tickets (Score >= 70) mit mr_outcome = "changes_requested" oder "closed"
  • False Negatives berechnen: Klärfall-Tickets (Score 30-70) die nach minimalem Enrichment sofort approved wurden
  • Raten pro Score-Range: "Tickets 70-79 haben X% Erfolg, 80-89 haben Y% Erfolg"
  • Raten pro Repo: "repo-A hat 88% Erfolg, repo-B nur 45%"

Scoring-Kalibrierung

  • Scoring-Gewichte (aktuell 0.42/0.33/0.25) werden konfigurierbar via Settings-API
  • Neue Felder in Config: weight_klarheit_was, weight_klarheit_wo, weight_kontext
  • Auto-Kalibrierung: Nach jeweils 50 abgeschlossenen Tickets werden optimale Gewichte berechnet
  • Korrelationsanalyse: Welche Scoring-Dimension korreliert am stärksten mit MR-Erfolg?
  • Schwellwert-Empfehlung: "False-Positive-Rate ist 18% — Schwellwert von 70 auf 75 erhöhen?"
  • Kalibrierungs-Report als API-Endpoint: GET /api/stats/calibration

Dashboard-Erweiterung

  • Stats-API um Accuracy-Metriken erweitern: success_rate_by_score_range, false_positive_rate, false_negative_rate
  • Stats-API: success_rate_by_repo, success_rate_by_classification
  • Frontend: Accuracy-Charts im Dashboard (Score-Range vs Erfolgsrate)
  • Frontend: Kalibrierungs-Empfehlungen anzeigen ("Schwellwert zu niedrig")

Technische Hinweise

  • Betroffene Dateien:
    • Neu: backend/services/mr_tracker.py (GitLab MR-Polling-Job)
    • Neu: backend/services/calibration_engine.py (Korrelationsanalyse, Gewicht-Optimierung)
    • Ändern: backend/models/ticket.py (Felder existieren bereits, nur sicherstellen dass sie korrekt typisiert sind)
    • Ändern: backend/services/scoring_engine.py (Gewichte aus Config statt hardcoded lesen)
    • Ändern: backend/config.py (+ weight_klarheit_was/wo/kontext, calibration_interval)
    • Ändern: backend/main.py (MR-Tracking Scheduler-Job registrieren)
    • Ändern: backend/api/pipeline.py (Stats erweitern um Accuracy-Metriken + Calibration-Endpoint)
    • Ändern: frontend/src/pages/Dashboard.tsx (Accuracy-Charts, Kalibrierungs-Empfehlung)
    • Ändern: frontend/src/pages/Settings.tsx (Scoring-Gewichte konfigurierbar)
  • Ansatz: Erst MR-Polling implementieren (Daten sammeln), dann nach 50+ Datenpunkten
    Kalibrierung starten. Gewichte als Runtime-Settings, nicht als Code-Änderung.
  • Migration nötig: Nein (Felder existieren bereits)
  • Voraussetzung für: #88 (Post-Merge Verification), #89 (Knowledge Base)

Aufwand: L

## Beschreibung Die Grundlage für jedes Self-Improvement: Erfassen ob MRs approved oder rejected werden, und diese Daten nutzen um Scoring-Gewichte und Schwellwerte automatisch zu kalibrieren. Aktuell existieren die DB-Felder `mr_outcome`, `mr_reviewed_at` und `mr_comments_count` im Ticket-Model — sie werden aber **nie befüllt**. Es gibt keinen GitLab-Polling-Job und keinen Webhook-Handler. Die Stats-API berechnet `success_rate` aus Daten die immer NULL sind. ## Hintergrund Ohne MR-Outcome-Daten ist kein Learning möglich: - Scoring-Gewichte (0.42/0.33/0.25) sind hardcoded Ratewerte - Schwellwerte (70/30) sind manuell konfigurierbar, aber niemand weiß ob sie optimal sind - False-Positive-Rate unbekannt (wie viele Autopilot-Tickets werden rejected?) - False-Negative-Rate unbekannt (wie viele Klärfälle wären Autopilot gewesen?) - `success_rate` im Dashboard ist immer 0% weil `mr_outcome` nie gesetzt wird Dieses Issue vereint: #15 (Scoring-Kalibrierung), #16 (MR-Erfolgs-Tracking), #19 (Feedback-Loop), #27 (GitLab Webhook/Polling), #68 (Scoring-Gewichte konfigurierbar). ## Akzeptanzkriterien ### MR-Outcome Erfassung - [ ] Neuer Scheduler-Job `poll_mr_outcomes()` (Intervall: 10min) in `main.py` - [ ] Pollt alle Tickets mit `mr_id IS NOT NULL AND mr_outcome IS NULL` - [ ] Setzt `ticket.mr_outcome`: "approved" | "changes_requested" | "closed" | "merged" - [ ] Setzt `ticket.mr_reviewed_at` beim ersten Review-Event - [ ] Aktualisiert `ticket.mr_comments_count` bei jeder Änderung - [ ] WebSocket-Broadcast bei Status-Änderung für Live-Dashboard ### False-Positive / False-Negative Tracking - [ ] False Positives berechnen: Autopilot-Tickets (Score >= 70) mit `mr_outcome` = "changes_requested" oder "closed" - [ ] False Negatives berechnen: Klärfall-Tickets (Score 30-70) die nach minimalem Enrichment sofort approved wurden - [ ] Raten pro Score-Range: "Tickets 70-79 haben X% Erfolg, 80-89 haben Y% Erfolg" - [ ] Raten pro Repo: "repo-A hat 88% Erfolg, repo-B nur 45%" ### Scoring-Kalibrierung - [ ] Scoring-Gewichte (aktuell 0.42/0.33/0.25) werden konfigurierbar via Settings-API - [ ] Neue Felder in Config: `weight_klarheit_was`, `weight_klarheit_wo`, `weight_kontext` - [ ] Auto-Kalibrierung: Nach jeweils 50 abgeschlossenen Tickets werden optimale Gewichte berechnet - [ ] Korrelationsanalyse: Welche Scoring-Dimension korreliert am stärksten mit MR-Erfolg? - [ ] Schwellwert-Empfehlung: "False-Positive-Rate ist 18% — Schwellwert von 70 auf 75 erhöhen?" - [ ] Kalibrierungs-Report als API-Endpoint: `GET /api/stats/calibration` ### Dashboard-Erweiterung - [ ] Stats-API um Accuracy-Metriken erweitern: `success_rate_by_score_range`, `false_positive_rate`, `false_negative_rate` - [ ] Stats-API: `success_rate_by_repo`, `success_rate_by_classification` - [ ] Frontend: Accuracy-Charts im Dashboard (Score-Range vs Erfolgsrate) - [ ] Frontend: Kalibrierungs-Empfehlungen anzeigen ("Schwellwert zu niedrig") ## Technische Hinweise - Betroffene Dateien: - Neu: `backend/services/mr_tracker.py` (GitLab MR-Polling-Job) - Neu: `backend/services/calibration_engine.py` (Korrelationsanalyse, Gewicht-Optimierung) - Ändern: `backend/models/ticket.py` (Felder existieren bereits, nur sicherstellen dass sie korrekt typisiert sind) - Ändern: `backend/services/scoring_engine.py` (Gewichte aus Config statt hardcoded lesen) - Ändern: `backend/config.py` (+ weight_klarheit_was/wo/kontext, calibration_interval) - Ändern: `backend/main.py` (MR-Tracking Scheduler-Job registrieren) - Ändern: `backend/api/pipeline.py` (Stats erweitern um Accuracy-Metriken + Calibration-Endpoint) - Ändern: `frontend/src/pages/Dashboard.tsx` (Accuracy-Charts, Kalibrierungs-Empfehlung) - Ändern: `frontend/src/pages/Settings.tsx` (Scoring-Gewichte konfigurierbar) - Ansatz: Erst MR-Polling implementieren (Daten sammeln), dann nach 50+ Datenpunkten Kalibrierung starten. Gewichte als Runtime-Settings, nicht als Code-Änderung. - Migration nötig: Nein (Felder existieren bereits) - Voraussetzung für: #88 (Post-Merge Verification), #89 (Knowledge Base) ## Aufwand: L
Sign in to join this conversation.
No description provided.