Fáze 2.1: 4 zastaralé testy → expectedFailure; +2 fixtures vč. Infeasible reproduceru

Analýza (agent + ručně): všechny 4 failující testy vynucují heuristické chování
před retry-chain v5; současné chování je ekonomicky správné nebo jde o korektní
fallback. Scénáře zachovány s @unittest.expectedFailure + zdůvodněním —
přepsat na ekonomické asserty ve Fázi 3. Suite: 120 passed, 4 xfailed.

Nové golden fixtures home-01: 2026-05-01 extreme_neg_buy (buy −13.26;
ZACHYCENO: solver Infeasible po celém relax řetězci — zmrazeno jako golden
failure snapshot), 2026-05-25 evening_push. Golden replay i penalty audit
umí solver_error výsledky (penalta měnící feasibility se zviditelní).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dusan Vojacek
2026-06-11 13:56:12 +02:00
parent 0dc2e1df96
commit 9a2229641d
7 changed files with 14598 additions and 20 deletions

View File

@@ -84,12 +84,23 @@ def _replay_all() -> dict[str, dict]:
return out
def _diff(base: dict, new: dict) -> tuple[float, float, int]:
"""(Δcashflow, Δpenalty, změněné sloty) napříč fixtures."""
def _diff(base: dict, new: dict) -> tuple[float, float, int, list[str]]:
"""(Δcashflow, Δpenalty, změněné sloty, změny feasibility) napříč fixtures."""
d_cash = d_pen = 0.0
changed = 0
feas: list[str] = []
for key, b in base.items():
n = new[key]
b_err = "solver_error" in b
n_err = "solver_error" in n
if b_err or n_err:
if b_err and not n_err:
feas.append(f"{key}: INFEASIBLE → OK!")
changed += 1
elif n_err and not b_err:
feas.append(f"{key}: OK → INFEASIBLE")
changed += 1
continue
d_cash += n["totals"]["cashflow_czk"] - b["totals"]["cashflow_czk"]
d_pen += n["totals"]["penalty_czk"] - b["totals"]["penalty_czk"]
for rb, rn in zip(b["slots"], n["slots"]):
@@ -99,7 +110,7 @@ def _diff(base: dict, new: dict) -> tuple[float, float, int]:
or rb["pv_a_curtailed_w"] != rn["pv_a_curtailed_w"]
):
changed += 1
return d_cash, d_pen, changed
return d_cash, d_pen, changed, feas
def main() -> None:
@@ -113,9 +124,10 @@ def main() -> None:
print()
baseline = _replay_all()
base_cash = sum(r["totals"]["cashflow_czk"] for r in baseline.values())
base_pen = sum(r["totals"]["penalty_czk"] for r in baseline.values())
print(f"baseline: cashflow {base_cash:.1f} Kč, penalty {base_pen:.1f}\n")
base_cash = sum(r["totals"]["cashflow_czk"] for r in baseline.values() if "totals" in r)
base_pen = sum(r["totals"]["penalty_czk"] for r in baseline.values() if "totals" in r)
infeas = [k for k, r in baseline.items() if "solver_error" in r]
print(f"baseline: cashflow {base_cash:.1f} Kč, penalty {base_pen:.1f} Kč; infeasible fixtures: {infeas}\n")
header = f"{'konstanta':<55} {'hodnota':>9} {'Δcash':>8} {'Δpenalty':>9} {'Δsloty':>6} bind"
print(header)
@@ -132,8 +144,10 @@ def main() -> None:
_restore_const(name, saved)
continue
_restore_const(name, saved)
d_cash, d_pen, changed = _diff(baseline, result)
d_cash, d_pen, changed, feas = _diff(baseline, result)
bind = "NE (mrtvá?)" if changed == 0 and abs(d_cash) < 0.05 else "ano"
if feas:
bind = " | ".join(feas)
rows.append((name, value, d_cash, d_pen, changed, bind))
print(f"{name:<55} {value:>9} {d_cash:>8.1f} {d_pen:>9.1f} {changed:>6} {bind}")