feat: Warnung bei ungeschützter Sandbox, Prüf-Regel für konstante Kosten, Grund je Korrekturrunde
- sandbox_warning: fehlt bubblewrap oder ist SOLVER_SANDBOX=aus, steht das im Log und in SolverRun.warnings (vorher lief der Code stillschweigend ungeschützt) - Dijkstra-Markierung: der Report erklärt den Begriff selbst (DIJKSTRA_EXPLANATION), check_text_quality zählt das als Erklärung; Stamm 'markier' -> 'markierung' - Pruef-Prompt Regel 7: entscheidungsunabhängige Terme ohne Zahlenwert dürfen weggelassen oder symbolisch mitgeführt werden (wagner_whitin_dijkstra: 1+1 statt 2+1 Korrekturrunden, n=2) - revision_reasons: jede Korrekturrunde nennt ihren Auslöser im Log Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
26f988a953
commit
0f1ab04a8d
1 changed files with 148 additions and 8 deletions
|
|
@ -4,7 +4,7 @@ from typing import List
|
|||
|
||||
from checks.model_checks import has_errors
|
||||
from core.llm import LLMSession
|
||||
from core.model_schema import AssumptionReview, CheckIssue, CheckSeverity, OptimizationModelSpecification
|
||||
from core.model_schema import AssumptionReview, AssumptionVerdict, CheckIssue, CheckSeverity, OptimizationModelSpecification
|
||||
|
||||
REVIEW_PROMPT_FILE = Path(__file__).parent / "Pruef-Prompt.txt"
|
||||
|
||||
|
|
@ -34,6 +34,30 @@ def needs_work(review: AssumptionReview, issues: List[CheckIssue]) -> bool:
|
|||
or any(i.code in REVISION_WORTHY_WARNINGS for i in issues))
|
||||
|
||||
|
||||
def revision_reasons(review: AssumptionReview, issues: List[CheckIssue]) -> List[str]:
|
||||
"""Warum eine Korrekturrunde nötig ist – fürs Log.
|
||||
|
||||
Bisher stand dort nur „Probleme gefunden“; welche Beanstandung eine Runde auslöste, ließ sich im
|
||||
Nachhinein nicht mehr feststellen (beobachtet an wagner_whitin_dijkstra, 20260917-160618).
|
||||
"""
|
||||
gruende = []
|
||||
oc = review.objective_check
|
||||
if not oc.matches:
|
||||
gruende.append(f"Zielgröße passt nicht: {oc.explanation[:160]}")
|
||||
if not oc.units_consistent:
|
||||
gruende.append(f"Einheiten der Zielfunktion uneinheitlich: {oc.unit_explanation[:160]}")
|
||||
faulty = {AssumptionVerdict.CONTRADICTS_TASK, AssumptionVerdict.STRICTER_THAN_TASK, AssumptionVerdict.WEAKER_THAN_TASK}
|
||||
for check in review.checks:
|
||||
if check.verdict in faulty:
|
||||
gruende.append(f"Annahme {check.verdict.value}: {check.unclear_point[:120]}")
|
||||
for fehlend in review.missing_assumptions:
|
||||
gruende.append(f"fehlende Annahme: {fehlend.unclear_point[:120]}")
|
||||
for issue in issues:
|
||||
if issue.severity == CheckSeverity.ERROR or issue.code in REVISION_WORTHY_WARNINGS:
|
||||
gruende.append(f"[{issue.code}] {issue.message[:120]}")
|
||||
return gruende
|
||||
|
||||
|
||||
def select_best(candidates: List[tuple]) -> int:
|
||||
"""Index der besten (spec, issues, review)-Runde.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue