diff --git a/TextToModel.py b/TextToModel.py index ba171a3..77f87d9 100644 --- a/TextToModel.py +++ b/TextToModel.py @@ -138,6 +138,15 @@ def _unresolved(attempt: dict) -> List[str]: if not attempt["review"].objective_check.matches: oc = attempt["review"].objective_check problems.append(f"Zielfunktion passt nicht zur Frage (gefragt: {oc.asked_quantity}; modelliert: {oc.modeled_quantity})") + # Eine Annahme, die auch nach allen Korrekturrunden noch dem Text widerspricht (contradicts_task), + # die Lösung stärker einschränkt (stricter_than_task) oder mehr zulässt (weaker_than_task), macht + # das Ergebnis unzuverlässig – der Solver rechnet ein falsches Modell. Beobachtet am + # Portfoliomanagement: Prüfung erkannte x als Stückzahl statt als Betrag (contradicts_task), + # aber 2 Korrekturrunden reparierten es nicht, der Solver lief als reliable=True. + faulty = {"contradicts_task", "stricter_than_task", "weaker_than_task"} + for check in attempt["review"].checks: + if check.verdict.value in faulty: + problems.append(f"Prüfung: Annahme {check.verdict.value} – {check.unclear_point[:120]}") problems += [f"[{i.code}] {i.message}" for i in attempt["issues"] if i.severity == CheckSeverity.ERROR] return problems diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index 9a5864d..67920f0 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -115,6 +115,19 @@ def test_better_earlier_attempt_wins_over_worse_restart(): assert result.solver_run is not None # Zielgröße passt -> Solver läuft, Ergebnis aber als unzuverlässig markiert +def test_persistent_contradicted_assumption_is_unreliable(): + # beobachtet am Portfoliomanagement: Prüfung erkannte x als Stückzahl statt als Betrag + # (contradicts_task), aber die Korrektur reparierte es nicht. Der Solver lief als reliable=True. + # Ein verbleibendes contradicts_task nach allen Runden muss das Ergebnis unzuverlässig machen. + from test_review import make_review + contradicts = make_review(verdict="contradicts_task") + session = FakeSession(specs=[HALLUCINATED] * 3, reviews=[contradicts] * 3, + codes=[SolverCode(code=STRUCTURED_CODE)]) + result = run_pipeline("Aufgabe", session=session, max_revisions=2, max_restarts=0) + assert not result.reliable + assert any("Prüfung: Annahme contradicts_task" in i for i in result.reliability_issues) + + def test_no_restart_when_disabled(): session = FakeSession(specs=[HALLUCINATED] * 3, reviews=[MISMATCH] * 3) result = run_pipeline("Aufgabe", session=session, max_revisions=2, max_restarts=0)