feat: schwerwiegende KI-Funde dürfen ROT auslösen (konfigurierbar)
Bisher war das KI-Level hart auf Gelb gedeckelt — auch injizierte
Pornografie oder strafbare/diffamierende Inhalte lösten nie Rot aus.
Das unterschätzt echte Notfälle (Sicherheits- + Rechts-/Reputationsrisiko).
Neu: kategoriebasierter Grave-Override in score_ai_findings. Nur Kategorien
aus red_categories (default ["pornography","defamation_illegal"]) lösen Rot
aus, und nur bei Schwere ≥ red_min_severity (high) UND Konfidenz ≥
red_min_confidence (0.9). Alle anderen Kategorien (Spam, Off-Topic,
Propaganda, Widerspruch) bleiben höchstens Gelb. Die Punktsumme allein
ergibt weiterhin nie Rot. red_categories: [] stellt das alte Verhalten her.
Begründung für die konservative Schwelle: LLM-Konfidenzen sind nicht
perfekt kalibriert — nur die gravierendsten Fälle dürfen die volle
ROT-Dringlichkeit ("Dienstleister informieren, nichts freigeben") tragen.
Rot fließt über die bestehende _worst_level-Verdrahtung automatisch ins
Gesamt-Level + Exit-Code 2; gilt auch für Bildfunde (OCR).
Tests: 237 grün (+7 Rot-Gate, bestehender Cap-Test auf Punktsumme-Logik
umgestellt). Config + Template + README + Bedienungsanleitung aktualisiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d06e3d3dfd
commit
a8dcaabf7c
6 changed files with 98 additions and 15 deletions
|
|
@ -116,8 +116,10 @@ def run_ai_analysis(cfg: dict, bm, snap: dict, diff: dict) -> dict:
|
|||
|
||||
def score_ai_findings(ai_result: dict, cfg: dict) -> dict:
|
||||
"""
|
||||
Bewertet KI-Funde additiv. Das Level ist hart auf 'yellow' gedeckelt —
|
||||
KI allein löst niemals ROT aus (ROT bleibt harten Integritäts-Signalen).
|
||||
Bewertet KI-Funde additiv. Das Level ist auf 'yellow' gedeckelt — AUSSER
|
||||
schwerwiegende Kategorien (red_categories, default Pornografie/strafbar) lösen
|
||||
bei hoher Schwere + hoher Konfidenz ROT aus. Die Punktsumme selbst ergibt nie
|
||||
Rot; nur dieser kategoriebasierte Override tut das.
|
||||
|
||||
Returns {score, level, reasons, exit_code}.
|
||||
"""
|
||||
|
|
@ -151,6 +153,22 @@ def score_ai_findings(ai_result: dict, cfg: dict) -> dict:
|
|||
if cfg.get("ai_analysis", {}).get("unchecked_level") == "yellow" and level == "green":
|
||||
level, exit_code = "yellow", 1
|
||||
|
||||
# Grave-Override: nur die schwersten Kategorien lösen ROT aus (Vorrang vor gelb).
|
||||
ai_cfg = cfg.get("ai_analysis", {})
|
||||
red_cats = set(ai_cfg.get("red_categories", []))
|
||||
red_min_sev = _SEVERITY_ORDER.get(ai_cfg.get("red_min_severity", "high"), 3)
|
||||
red_min_conf = ai_cfg.get("red_min_confidence", 0.9)
|
||||
for f in ai_result.get("findings", []):
|
||||
if (f.get("category") in red_cats
|
||||
and _SEVERITY_ORDER.get(f.get("severity", "none"), 0) >= red_min_sev
|
||||
and f.get("confidence", 0.0) >= red_min_conf):
|
||||
level, exit_code = "red", 2
|
||||
reasons.append(
|
||||
f"Schwerwiegender KI-Fund ({f['category']}, {f.get('confidence', 0):.0%}) "
|
||||
f"auf {f.get('url', '?')} → ROT"
|
||||
)
|
||||
break
|
||||
|
||||
return {"score": score, "level": level, "reasons": reasons, "exit_code": exit_code}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue