From 1448bd909b19baa4cde9992dd12f3c32c8772799 Mon Sep 17 00:00:00 2001 From: glenn schrooyen Date: Tue, 8 Sep 2026 04:38:18 +0200 Subject: [PATCH] SAFETY-43: the `no_account` switch was graded by nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review's remaining non-blocking finding, and it is B1's shape one level down - in the fix for B1. `wedged_loop`'s `no_account=True` was used in exactly ONE place: the cut-out fixture, where it PROVABLY cannot change the answer, because a pack at its own cut-out is never asked and the gate is never reached. Review neutered the switch so it removed nothing, and the file stayed GREEN while printing ...named=(nobody); with account() DELETED: 0/200 with `account()` not deleted. A line asserting a mechanism that did not happen. ⭐ THE SWITCH DOES BITE, ON A FIXTURE THIS HELPER COULD ALREADY REACH. At the same cut-out with EQUAL weights, `plan()` hands B a 50/50 share, so the account gate is the only thing keeping it silent. Measured: cut-out, OPT-09 weights gate on 0/200 gate DELETED 0/200 cut-out, EQUAL weights gate on 0/200 gate DELETED 200/200 Asserted. Driven: neutering the switch now goes RED on exactly that check, and nothing else. Two things this buys beyond closing the finding. It proves the switch removes the gate, so the printed "with account() DELETED" line is about a run in which something was. And it gives part 8b the end-to-end account-gate control ON A POSITIVE SHARE that the block previously had to outsource to test_delivery.py part 1 - the arm is no longer only true, it is locally demonstrated. Suite: 27 files, all pass. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU --- goodwe_controller/test_packshare.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/goodwe_controller/test_packshare.py b/goodwe_controller/test_packshare.py index d25f565..b7b5462 100644 --- a/goodwe_controller/test_packshare.py +++ b/goodwe_controller/test_packshare.py @@ -865,6 +865,31 @@ print(f" load 1500 W, B AT ITS OWN {FLOOR:.0f} % CUT-OUT, OPT-09 weights, " + ", named=" + (str(sorted(_sat_last[3])) if _sat_last[3] else "(nobody)") + f"; with account() DELETED: {_sat_nogate:3d}/200") +# ⚠️ AND THE `no_account=True` SWITCH ITSELF WAS GRADED BY NOTHING. It is used +# in exactly one place - the fixture above - where it PROVABLY cannot change the +# answer, because a cut-out pack is never asked and the gate is never reached. +# Review neutered the switch so it removed nothing: the file stayed GREEN and +# printed "with account() DELETED: 0/200" while `account()` had not been +# deleted. A line asserting a mechanism that did not happen - B1's shape, one +# level down, in the fix for B1. +# +# The switch DOES bite, on a fixture already reachable from this helper: at the +# cut-out with EQUAL weights, `plan()` hands B a 50/50 share, so the gate is the +# only thing keeping it silent. Measured: gate on 0/200, gate deleted 200/200. +# That proves the switch removes the gate, AND gives this part the end-to-end +# account-gate control on a POSITIVE share that it otherwise has to outsource to +# test_delivery.py part 1. +_eq_gate, _eq_last = wedged_loop(1500.0, False, b_soc=FLOOR) +_eq_nogate, _ = wedged_loop(1500.0, False, b_soc=FLOOR, no_account=True) +print(f" ...and the SWITCH is real: same cut-out, EQUAL weights so B IS " + f"asked ({_eq_last[1][Bee]:+d} W last cycle) - gate on {_eq_gate:3d}/200, " + f"gate DELETED {_eq_nogate:3d}/200") +check("⭐ THE `no_account` SWITCH ACTUALLY REMOVES THE GATE, on a fixture where " + "the gate is the only thing keeping the pack silent. Without this the " + "line above prints 'with account() DELETED' about a run in which nothing " + "was deleted - which is exactly the defect this block was rewritten for", + _eq_gate == 0 and _eq_nogate == 200 and _eq_last[1][Bee] > 0) + check("A PACK AT ITS OWN CUT-OUT IS NEVER ASKED, SO THE RELATIVE ARM IS NEVER " "REACHED. Its usable energy above its own cut-out is zero, `weights()` " "answers 0.0 for it, the healthy sibling covers the load so `_fill()`'s "