UX-08 phase 2b review: keep over-rating evidence, pin latch clearing, plainer rows
checks / unit (pull_request) Successful in 8m48s
infra-pin / fresh (pull_request) Successful in 1s

- During a bound episode an earlier over-rating count stays on the page (amber,
  under its own title); test_clamp pins it.
- test_messages pins that every latch row says how it clears.
- pv_entities description no longer claims the page names the entity (en, nl);
  allowlist hash updated for that option-desc line.
- Plainer texts: multi-inverter direction banner, "fine now" after an episode,
  and the e-stop, peak-forecast and peak-guard-waiting rows move to messages.py.
- TEL-12 DECISIONS points to UX-08 item 3 for the retired row rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-09-27 03:10:25 +02:00
co-authored by Claude Opus 5.5
parent 696142bccc
commit 571b884315
9 changed files with 61 additions and 12 deletions
+11 -5
View File
@@ -4669,8 +4669,7 @@ class Controller:
_pg = self.peak_guard
if _pg is None:
out.append({"ok": True, "warn": True, "id": "peak_guard",
"text": "peak guard: no decision yet - the first "
"control cycle has not run"})
"text": messages.row_peak_guard_waiting()})
elif _pg.saturated:
out.append({"ok": False, "warn": False, "id": "peak_guard",
"text": messages.row_peak_saturated(_pg.ceiling_w)})
@@ -4821,6 +4820,12 @@ class Controller:
# SAFETY-40: the integrator bound alone is amber, not red.
out.append({"ok": False, "warn": True, "id": "not_keeping_up",
"text": messages.row_not_keeping_up(_cw.bound)})
# No over-rating in THIS episode (`bug` would be set), so any count
# is from an earlier one: keep that software-fault evidence shown.
if _cw.over_rating:
out.append({"ok": False, "warn": True, "id": "power_too_high",
"text": messages.row_before(
messages.T_OUTPUT_CLAMP, _cw.over_rating)})
else:
if _cw.over_rating:
out.append({"ok": False, "warn": True, "id": "power_too_high",
@@ -4940,13 +4945,14 @@ class Controller:
out.append({"ok": False, "warn": True, "id": "estop",
"text": messages.row_no_estop()})
else:
out.append({"ok": True, "warn": False, "text": "e-stop fitted"})
out.append({"ok": True, "warn": False, "id": "estop",
"text": messages.row_estop_fitted()})
if not o.get("peak_forecast_entity"):
# ok=False + warn=True renders as a caution, not a pass. A check that
# is both is a check nobody reads.
out.append({"ok": False, "warn": True,
"text": "no peak forecast: maintenance charging is not capacity-capped"})
out.append({"ok": False, "warn": True, "id": "peak_forecast",
"text": messages.row_no_peak_forecast()})
# --- TEL-11 ----------------------------------------------------------
# ⚠️ NO ROW AT ALL WHEN THE ROSTER IS EMPTY, AND THAT IS A DELIBERATE
# DIFFERENCE FROM THE PEAK-FORECAST CAUTION DIRECTLY ABOVE. That one