This commit is contained in:
team3
2026-07-13 05:18:55 +02:00
parent 7ee425f7fa
commit 8926f87185
19 changed files with 703 additions and 41 deletions

View File

@@ -52,6 +52,39 @@ def lauf_starten(topic: str, budget: int | None = None) -> int:
return run_id
def _tief_zuruecksetzen(topic: str, ebene: str) -> None:
"""tief=Re-Verify: Verifiziertes auf 'kandidat' zurückstufen — der BESTEHENDE
Verify-Weg beurteilt dann alles neu (verifiziert oder verworfen = Entfernen).
Nur wo es einen LLM-Verify gibt; korpus (Soll-Freeze) bleibt bewusst außen vor,
inventar/struktur prüfen ohnehin deterministisch alles bei jedem messen."""
if ebene == "artefakte":
db.execute("UPDATE artefakte SET status='kandidat' WHERE status='verifiziert'"
" AND atom_id IN (SELECT id FROM atome WHERE topic=?)", (topic,))
elif ebene == "guide":
db.execute("UPDATE sections SET stage='pruefer', qa_hash='', fix_versuche=0"
" WHERE baustein_id IN (SELECT id FROM bausteine WHERE topic=?)",
(topic,))
def aktualisierung_starten(topic: str, ebene: str, tief: bool = False) -> int:
"""Eine Ebene (und bei Auto-Flags die folgenden) erneut fahren — ohne Reset,
ohne Status-Rückschritt. bauen füllt Fehlendes, messen+Repair fixt Kaputtes.
tief=True: zusätzlich alles Verifizierte erneut durchs Panel (teuer)."""
if ebene not in [e[0] for e in EBENEN]:
raise ValueError(f"unbekannte Ebene: {ebene}")
if topic in _laeufe and not _laeufe[topic].done():
raise RuntimeError("Lauf läuft bereits")
agents.abbruch_aufheben(f"{topic}-")
if tief:
_tief_zuruecksetzen(topic, ebene)
git_hash, dirty = ledger.git_stand()
run_id = db.insert("runs", topic=topic, status="running", git_hash=git_hash,
git_dirty=int(dirty), budget_tokens=RUN_BUDGET_TOKENS,
grund=f"aktualisieren:{ebene}" + (":tief" if tief else ""))
_laeufe[topic] = asyncio.ensure_future(_lauf(topic, run_id, ab=ebene, erzwingen=True))
return run_id
def lauf_stoppen(topic: str) -> None:
agents.abbrechen(f"{topic}-")
task = _laeufe.get(topic)
@@ -163,13 +196,19 @@ def soll_reset(topic: str) -> None:
db.update("topics", "name", topic, status="korpus")
async def _lauf(topic: str, run_id: int) -> None:
async def _lauf(topic: str, run_id: int, ab: str | None = None,
erzwingen: bool = False) -> None:
"""Normaler Lauf ODER Aktualisierung (ab=Ebene, erzwingen=True): Aktualisieren
fährt fertige Ebenen erneut — bauen füllt Fehlendes, messen prüft Form, Repair
repariert. Nötig, weil der Resume-Skip fertige Ebenen sonst nie wieder anfasst
(Altbestands-Lücke: Katalog-Titel, Aussagen-Nachrüstung, Beleg-Fenster)."""
t = db.one("SELECT * FROM topics WHERE name=?", (topic,))
ctx = llm.Kontext(run_id, topic, t["provider"])
start_idx = [e[0] for e in EBENEN].index(ab) if ab else 0
try:
for name, modul, marke in EBENEN:
for name, modul, marke in EBENEN[start_idx:]:
status = db.one("SELECT status FROM topics WHERE name=?", (topic,))["status"]
if _fertig_ab(status, marke):
if not erzwingen and _fertig_ab(status, marke):
continue
db.update("runs", "id", run_id, ebene=name)
await modul.bauen(ctx)
@@ -190,7 +229,10 @@ async def _lauf(topic: str, run_id: int) -> None:
gate = getattr(modul, "gate", None)
if gate and (grund_gate := gate(ctx)):
raise RuntimeError(f"{name}-Gate: {grund_gate}")
db.update("topics", "name", topic, status=marke)
# Marker-Schutz: nie zurückdrehen — Aktualisieren einer frühen Ebene
# darf z. B. 'fertig' nicht auf 'artefakte_fertig' zurückstufen.
if not _fertig_ab(status, marke):
db.update("topics", "name", topic, status=marke)
flags = db.uj(db.one("SELECT auto FROM topics WHERE name=?", (topic,))["auto"], {})
if not flags.get(name, True) and marke != "fertig":
db.update("runs", "id", run_id, status="done", beendet=db.now(),