From 3db2b6392fe294120278c527312ae93ff23895f2 Mon Sep 17 00:00:00 2001 From: SAFETY-97 dev Date: Sun, 4 Oct 2026 13:07:06 +0200 Subject: [PATCH] SAFETY-97: test the centred stale-path refusal (mutant S10 survived) At a 5 s meter a register frozen at rest on B trips the stale gate before the 12-cycle evidence; its refusal must be centred on B's idle reading, or the site stops and re-trips instead of refusing B. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019DBUfvndgHwaV339Fvd2gr --- goodwe_controller/test_safety97.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/goodwe_controller/test_safety97.py b/goodwe_controller/test_safety97.py index 62a6f81..f3bf095 100644 --- a/goodwe_controller/test_safety97.py +++ b/goodwe_controller/test_safety97.py @@ -124,6 +124,22 @@ print(f" B's register frozen at rest from 300 s, asked at 600 s: 0 W at " f"{park}") check("a register frozen at rest on B is caught as on A (within 36 s of " "the ask)", park is not None and park - 600.0 <= 36.0) +# At a 5 s meter the stale trip comes first: its refusal is centred too. +saved = dict(rig.OFFSET) +rig.OFFSET["b"] = -110.0 +try: + r = rig.run(2, lambda t: 2500.0 if t >= 600 else 0.0, 760.0, tick=5.0, + publish_s=1.0, dither=True, + freeze_at=lambda u: 300.0 if u == "b" else None) +finally: + rig.OFFSET.clear() + rig.OFFSET.update(saved) +st = [t for t, u in r["stale"] if u == "inverter-b"] +ref = [t for t, u in r["refused"] if u == "inverter-b"] +print(f" the same at a 5 s meter, B idle -110 W: stale {st}, refused {ref}") +check("...and at a 5 s meter the stale trip on B's held -110 W is a refusal " + "of B (one trip), not a repeating site stop", + len(st) == 1 and ref == st) # ============================================================================ # print("\n2. a healthy B with its offset is never refused or flagged")