UX-11: safety log lines give one plain sentence and the code, the figures go to DEBUG
checks / unit (pull_request) Successful in 9m3s
infra-pin / fresh (pull_request) Successful in 2s

- Every WARNING/ERROR line that reported a safety reason (direction, delivery,
  stuck meter, stale reading, peak guard, circulation, over-rating) now ends in
  the reason's code (messages.reason_code()). The reason itself, figures and
  limits included, is on a DEBUG line right after it and in the action log.
- The reasons and state.json are unchanged, so an old state file loads and
  shows the same way: every saved reason opens with its code.
- test_messages part 6 checks every WARNING+ line at 25 words as logged; nine
  non-safety families are listed with a reason and capped. The byte pin in
  test_watchdog now pins the meaning, in order.
- The meter logs one WARNING per quiet episode, and INFO when back, so the red
  row's "the add-on log shows why" holds. The Why line past the hold names
  the missing reading. Action log: "25 engagements", "Shadow mode off: ...".

No trigger, latch, threshold, log level, notification id, cadence, row colour
or banner order changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
This commit is contained in:
glenn schrooyen
2026-09-27 13:34:30 +02:00
co-authored by Claude Opus 5.5
parent c4032ebc21
commit 29837dfaa7
10 changed files with 425 additions and 84 deletions
+6 -1
View File
@@ -1813,6 +1813,11 @@ _S56_ACCUSATIONS = [
]
_log56 = [r.getMessage() for r in _LOGREC[_S56_LOG0:]
if "battery power reading stopped changing" in r.getMessage()]
# UX-11: the ERROR line quotes the code, and the reason itself is on the DEBUG
# line logged beside it.
_dbg56 = [r.getMessage() for r in _LOGREC[_S56_LOG0:]
if r.levelno == logging.DEBUG
and r.getMessage().startswith("Evidence for ")] or [""]
def _s56_row(c):
@@ -1855,7 +1860,7 @@ check("PRECONDITION: all four operator-facing surfaces were really produced by "
"two are the same string, which is 11b again on the log surface",
len(_log56) == 2 and _log56[0] == _log56[1]
and all(len(s) > 30 for s in _S56_SURFACES.values())
and _r56_ref in _log56[-1])
and _log56[-1].endswith(": STALE_READING.") and _r56_ref in _dbg56[-1])
_idx56 = [_r56_ref.find(t) for _w, t in _S56_EXPLANATIONS]
check(f"11c. BOTH EXPLANATIONS ARE NAMED, AND IN THAT ORDER: "
f"{_S56_EXPLANATIONS[0][1]!r} at {_idx56[0]} then "