TEST-17: grade the status page's peak row at a stated month, not at today's
checks / unit (pull_request) Successful in 3m35s
checks / unit (pull_request) Successful in 3m35s
release/1.0 went red at 00:00 on 2026-09-01 on a commit nobody had touched. `Controller.checks()` read the capacity-tariff peak with `self.peak.peak()` - no argument - so tariff.py resolved the month from `datetime.now()`, while test_tariff.py section 10 banks its quarter at the fixed fixture 2026-08-30. From 1 September the page was correctly asked for September, correctly answered NO_RECORD, and the row read "no completed quarter recorded yet" - a string containing no "peak", which the section's own filter required. Four checks failed. ISOLATED BY MOVING ONLY THE CLOCK. Same commit, same shipped-deps image, libfaketime: green at 2026-08-30, four failures at 2026-09-01. Identical atf4914a1, 04292c4~1 and04292c4, so this is the calendar and not a regression. It has been latent since TARIFF-01 merged on 2026-08-30, and every PR that ever ran this suite ran it in August. THE PRODUCT IS RIGHT AND THE TEST WAS WRONG, so the live page is unchanged. Section 5 of this same file calls NO_RECORD "a normal state on the 1st of the month" and a capacity tariff is billed monthly, so a page showing the current month is correct. `checks()` now takes `when: datetime | None = None` and threads it into peak() and warning_frac() - the convention PeakStore.peak(), PeakTracker.peak(), headroom_w() and warning_frac() all already follow. The one production caller passes nothing and still means today. AND THE DEFECT IS NOW DETECTABLE RATHER THAN SEASONAL. Three checks: the same controller read at two different reference months must produce two different rows, which no clock can satisfy; the later month must read NO_RECORD and stay distinguishable from both an observed peak and an unreadable store; and checks() with no argument must still mean today. Verified by mutation - a checks() that drops `when` is red at every clock tried, where the old section went green in August. The first draft of these checks was itself wrong in the same way and reproduced the bug: it selected rows on "peak", which the NO_RECORD row does not contain, so it dropped the row and then graded its absence. They select on "quarter(s) banked" instead. Full suite green, 15 files, at the real clock and at faked clocks in 2026-08, 2026-12, 2027-02 and 2027-03. Left alone deliberately: only the UNREADABLE branch prefixes its row with "capacity-tariff peak:". The NO_RECORD row carries neither that phrase nor the word "peak". That asymmetry is what made the original filter brittle and what broke the first draft above; it is product text with other suites reading it, so it is reported rather than changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
This commit is contained in:
co-authored by
Claude Opus 5
parent
f6ecd5ff03
commit
504e8daac3
@@ -1270,7 +1270,20 @@ class Controller:
|
||||
self.mqtt.close()
|
||||
|
||||
# -- UI ------------------------------------------------------------------
|
||||
def checks(self) -> list:
|
||||
def checks(self, when: datetime | None = None) -> list:
|
||||
"""The status rows. `when` is the reference time for anything billed by
|
||||
the calendar - today's month when it is None, which is what the live
|
||||
page means; `status_payload()` calls this with no argument.
|
||||
|
||||
⚠️ IT EXISTS SO THE PEAK ROW CAN BE GRADED (TEST-17). Every other peak
|
||||
query already takes it - `PeakStore.peak()`, `PeakTracker.peak()`,
|
||||
`headroom_w()`, `warning_frac()` - and the row built from them was the
|
||||
one thing that could only be read against `datetime.now()`. A suite
|
||||
that banks an August quarter then asks this page what the peak is goes
|
||||
green in August and red in September, which is what happened at 00:00
|
||||
on 2026-09-01: TARIFF-01's own section 10, red on a calendar boundary,
|
||||
on a commit nobody had touched for a day.
|
||||
"""
|
||||
o = self.o
|
||||
out = []
|
||||
if self.p1_enabled:
|
||||
@@ -1331,14 +1344,14 @@ class Controller:
|
||||
# a normal state on the 1st; "unreadable" is a broken instrument, and
|
||||
# a status page that spelled them the same way would let a 0 W read
|
||||
# look like a quiet month right up until SAFETY-07 shaved nothing.
|
||||
_pk = self.peak.peak()
|
||||
_pk = self.peak.peak(when)
|
||||
if _pk.is_unreadable:
|
||||
out.append({"ok": False, "warn": True,
|
||||
"text": "capacity-tariff peak: " + _pk.explain()})
|
||||
else:
|
||||
# §9.1's "warning entity at 80 %", as a status row rather than
|
||||
# a second entity - see the constructor on not doubling up.
|
||||
_frac = self.peak.warning_frac() or 0.0
|
||||
_frac = self.peak.warning_frac(when) or 0.0
|
||||
_ok = _frac < 0.8
|
||||
out.append({"ok": _ok, "warn": not _ok,
|
||||
"text": _pk.explain()
|
||||
|
||||
Reference in New Issue
Block a user