fix: Leere Controls (title/objective=None) filtern vor Store
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 44s
CI / test-python-voice (push) Successful in 33s
CI / test-bqas (push) Successful in 30s
CI / Deploy (push) Failing after 4s

- Batch-Postprocessing: Controls mit title/objective = None/null/"" werden
  gefiltert und nicht gespeichert. Title wird aus Objective abgeleitet falls
  nur Title fehlt.
- _store_control: Pre-store Quality Guard lehnt leere Controls ab
- Verhindert "None"-Controls die durch LLM-Parsing-Fehler entstehen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-14 06:59:47 +02:00
parent a58d1aa403
commit c4e993e3f8

View File

@@ -1526,9 +1526,22 @@ Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Elementen. Fuer Aspekte ohne
final: list[Optional[GeneratedControl]] = [] final: list[Optional[GeneratedControl]] = []
for i in range(len(batch_items)): for i in range(len(batch_items)):
control = all_controls.get(i) control = all_controls.get(i)
if not control or (not control.title and not control.objective): # Filter empty or invalid controls (LLM returned None/empty)
if not control:
final.append(None) final.append(None)
continue continue
title_invalid = not control.title or control.title.strip().lower() in ("none", "null", "")
obj_invalid = not control.objective or control.objective.strip().lower() in ("none", "null", "")
if title_invalid and obj_invalid:
logger.warning("Leerer Control gefiltert (title=%s, objective=%s) — wird nicht gespeichert",
control.title, control.objective)
final.append(None)
continue
# Clean up "None" strings from LLM
if title_invalid:
control.title = control.objective[:120] if control.objective else "Unbenannt"
if obj_invalid:
control.objective = control.title
if control.release_state == "too_close": if control.release_state == "too_close":
final.append(control) final.append(control)
@@ -1931,6 +1944,14 @@ Kategorien: {CATEGORY_LIST_STR}"""
def _store_control(self, control: GeneratedControl, job_id: str) -> Optional[str]: def _store_control(self, control: GeneratedControl, job_id: str) -> Optional[str]:
"""Persist a generated control to DB. Returns the control UUID or None.""" """Persist a generated control to DB. Returns the control UUID or None."""
# Pre-store quality guard — reject empty/invalid controls
if not control.title or control.title.strip().lower() in ("none", "null", ""):
logger.warning("Rejected control with empty/None title: %s", control.control_id)
return None
if not control.objective or control.objective.strip().lower() in ("none", "null", ""):
logger.warning("Rejected control with empty/None objective: %s%s", control.control_id, control.title)
return None
try: try:
# Get framework UUID # Get framework UUID
fw_result = self.db.execute( fw_result = self.db.execute(