fix: Solver-Fehler gilt als unzuverlässig; Aufräumrunde ohne LLM

- Status error nach allen Reparaturen -> reliable=False („Solver-Fehler: …“, auch bei
  --resolve); vorher Exit-Code 0 ohne Warnkasten. Benchmark zählt einen Absturz nicht
  als ehrliches Scheitern.
- Report: „längster Weg“ bei maximize; Harness druckt „Gefundener Weg“.
- check_requested_method: Verneinung kurz davor im selben Satz („ohne/nicht/statt/
  anders als Dijkstra“) ist keine Forderung.
- Reparatur-Prompt enthält die Fehlertexte aller früheren Versuche.
- ruff (F, E9) als Test tests/test_lint.py, Konfiguration in pyproject.toml.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-09-18 18:15:22 +02:00
commit f101b63947

View file

@ -503,12 +503,22 @@ REQUESTED_METHOD = {
}
# „ohne Dijkstra“, „nicht mit dem Simplex“, „statt Branch-and-Bound“: Erwähnung, keine Forderung. Nur im selben
# Satz und kurz davor – „Lösen Sie mit Dijkstra. Ohne Rechenweg gibt es keine Punkte.“ bleibt eine Forderung.
NEGATION_BEFORE = re.compile(r"\b(?:ohne|nicht|keine?[nmrs]?|statt|anstelle|anstatt|außer|ausser|anders als)\b[^.!?;\n]{0,30}$")
def _requested(name: str, text: str) -> bool:
"""Kommt das Verfahren mindestens einmal ohne vorangehende Verneinung vor?"""
return any(not NEGATION_BEFORE.search(text[:m.start()]) for m in re.finditer(re.escape(name), text))
def check_requested_method(spec: OptimizationModelSpecification, task: str) -> List[CheckIssue]:
"""Ein im Aufgabentext ausdrücklich verlangtes Verfahren muss auch verwendet werden."""
text = (task or "").lower()
issues = []
for name, stacks in REQUESTED_METHOD.items():
if name in text and spec.target_stack not in stacks:
if _requested(name, text) and spec.target_stack not in stacks:
issues.append(CheckIssue(
severity=CheckSeverity.ERROR, code="REQUESTED_METHOD_IGNORED",
message=f"Die Aufgabe verlangt ausdrücklich '{name}', das Modell nutzt aber "