Files
creator/backend/auto_loop.py
2026-07-06 17:32:52 +02:00

40 lines
1.9 KiB
Python
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.
"""Auto-Repair-Loop einer Ebene: QA → Befunde beheben, bis 100 % (10.0/10),
Stillstand (Repair verbessert die Note nicht mehr) oder max_iter erreicht ist.
Reine Primitive — keine Kanban-/DB-Kopplung. Der Aufrufer übergibt zwei Coroutinen:
`messen()` liefert die aktuelle QA-Note (010), `reparieren()` behebt die Befunde.
So bleibt der Loop pro Ebene (Inventar/Artefakte/Guide) identisch testbar.
"""
import logging
log = logging.getLogger("creator.auto_loop")
VOLL = 10.0 # 100 % = 10.0/10
MAX_ITER = 10 # Sicherheitslimit: mehr Runden ⇒ etwas im System stimmt nicht
async def auto_repair_loop(ebene: str, erst_note: float, reparieren, max_iter: int = MAX_ITER) -> dict:
"""Loop QA→Repair für eine Ebene.
erst_note : float — bereits gemessene QA-Note vor dem ersten Repair (010).
reparieren() -> float: behebt die Befunde UND gibt die neu gemessene Note zurück
(die Repair-Bausteine messen ohnehin am Ende — keine Doppelmessung).
Stopp bei: Note == VOLL (fertig), Note verbessert sich nicht mehr (stillstand),
oder max_iter Runden (limit). Returns {ebene, note, runden, grund} mit
grund ∈ {"fertig","stillstand","limit"} — der Aufrufer nutzt grund für die
Fortschritts-/Systemfehler-Meldung.
"""
if erst_note >= VOLL:
return {"ebene": ebene, "note": erst_note, "runden": 0, "grund": "fertig"}
note = erst_note
for runde in range(1, max_iter + 1):
neu = await reparieren()
log.info("[%s] Auto-Loop Runde %d: %.1f%.1f", ebene, runde, note, neu)
if neu >= VOLL:
return {"ebene": ebene, "note": neu, "runden": runde, "grund": "fertig"}
if neu <= note: # keine Verbesserung ⇒ weitere Runden zwecklos (kein Repair-Pfad)
return {"ebene": ebene, "note": neu, "runden": runde, "grund": "stillstand"}
note = neu
return {"ebene": ebene, "note": note, "runden": max_iter, "grund": "limit"}