SAFETY-119 round 3c: the hidden-bound budget follows the cycle length
checks / unit (pull_request) Successful in 43m29s
infra-pin / fresh (pull_request) Successful in 1s

No single rolling budget met both cases in the sweep (8 false-alarmed on
2 s seed 25 and warned in 1 to 3 of 7 quarters at 15 s). The budget is
now 10 cycles up to a 3.5 s cycle, 8 up to 11 s, 6 up to 16 s, 4 beyond,
per rolling 15 minutes; 8 while the cycle length is unknown. A stop or a
gap over two minutes is not a cycle length. The unsourced "owner
accepted N=8" paragraph is removed from DECISIONS. test_safety119 part 4
now runs 2 s seed 25 and shows a fixed budget of 8 warns there; the
never case runs at 2 s and checks every other quarter at 15 s.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-10-21 00:57:43 +02:00
co-authored by Claude
parent e27e62ff72
commit 6fd0fa05f1
3 changed files with 129 additions and 76 deletions
@@ -19,65 +19,61 @@ decided always counts. No command changes, and no text was added or changed.
**A rolling budget (round 3).** The settle above is per hand-back, and
losing the wire restarts it. Across all hand-backs the bound is hidden on at
most 8 cycles in any 15 minutes (`ROLLING_BOUND_CYCLES`, `ROLLING_S`). A cycle
over the budget counts. Round 1 restarted the settle at
every hand-back, so a guard and a charge taking turns hid the bound for good
(0 warnings in 2 h where 28 were raised before). Round 2 gave each run of
most a budget of cycles in any 15 minutes (`ROLLING_BUDGET`, `ROLLING_S`); a
cycle over the budget counts. Round 1 restarted the settle at every
hand-back, so a guard and a charge taking turns hid the bound for good (0
warnings in 2 h where 28 were raised before). Round 2 gave each run of
hand-backs its own budget; at 10 s and 15 s meters each quarter then started
a fresh one and the loop's bound was never counted. A quarter-edge kick is a
few bound cycles in one quarter, a real bound that stays is many: a budget
per 15 minutes tells them apart.
**Why 8.** Measured over 2 h (`goodwe-addon-checks:1`), budgets 3 to 10, the
quarter-edge case (house 800 W, cap 2500 W, 1 to 15 s meters) and the case
below. 3, 4, 5 and 6 let the false alarm back (at 2 s, for each). 7 let it
back on 10 of 30 seeds at 2 s. 8: 1 of 30 seeds at 2 s, none at 1, 5, 10 and 15 s.
9 and 10: none, but the case below then misses quarters at 10 s. So 8 is the
largest budget that still warns every quarter at 2, 5 and 10 s, and the
margin is narrow: 7 and 9 each fail one side.
**The budget follows the cycle length.** 10 cycles up to a 3.5 s cycle, 8 up
to 11 s, 6 up to 16 s, 4 beyond. The cycle length is the time between two
decided cycles (a stop, or a gap over two minutes, is not one); until it is
known, and without a monotonic clock, the budget is 8. Without a monotonic
clock the budget never refills.
**What holds with 8.** Single hand-back, the loop at its rail: the first
counted bound cycle is the 9th, so 8 cycles after the hand-back (measured,
real Controller): 8 s at 1 s, 16 s at 2 s, 40 s at 5 s (default), 80 s at
10 s, 120 s at 15 s, 240 s at 30 s, 480 s at 60 s. Repeated hand-backs
(2 x 2500 W, cheap-window charge, no usable forecast, cap 5000 W, house
5050 and 5100 W, 2 h; 20 runs at 2, 5 and 10 s, 8 at 15 s):
**Why not one number.** Measured over 2 h (`goodwe-addon-checks:1`), the
quarter-edge case (house 800 W, cap 2500 W, no forecast, 30 seeds) and the
case below. No single budget held both at 1 to 15 s: 3 to 6 let the false
alarm back at 2 s; 7 on 10 of 30 seeds at 2 s; 8 on 1 of 30 (seed 25) at
2 s, and warned in only 1 to 3 of 7 quarters at 15 s; 9 and 10 miss quarters
at 10 s. A slow cycle needs a small budget to warn, a fast one a large budget
to stay quiet. Per band, the largest budget that still warns: up to 3.5 s,
10 (9 and 10 had no false alarm at 1 and 2 s; above 10 was not swept); up to
11 s, 8 (9 misses quarters at 10 s); up to 16 s, 6 (7 leaves two quiet
quarters in a row at 15 s, 4 false-alarms at 12 s on 7 of 30 seeds); beyond,
4 (3 false-alarms at 20 and 30 s on 14 of 30, 5 leaves five quiet quarters at
20 s).
**What holds.** Quarter-edge case, 30 seeds each: 0 notifications at 1, 2,
3, 4, 5, 10, 12, 15, 20 and 30 s. Repeated hand-backs (2 x 2500 W,
cheap-window charge, no usable forecast, cap 5000 W, house 5050 and 5100 W,
constant and with noise, 8 runs per meter):
| meter | warnings in 2 h | quarters warned (of 7 after the first) | without the fix |
|---|---|---|---|
| 2 s | 51 to 57 | 7 | 54 to 56 |
| 5 s | 19 to 25 | 7 | 28 |
| 10 s | 7 to 11 | 7 | 14 |
| 15 s | 1 to 3 | 1 to 3 | 14 |
| 30 s | 0 | 0 | 7 and 11 |
| 1 s | 56 to 63 | 7 | 56 to 63 |
| 2 s | 49 to 56 | 7 | 54 to 56 |
| 5 s | 19 to 23 | 7 | 28 |
| 10 s | 7 to 10 | 7 | 14 |
| 15 s | 4 to 10 | 4 to 7, never two quiet in a row | 14 |
| 30 s | 3 to 7 | 3 to 5, up to two quiet in a row | 7 to 11 |
At 15 s it warns in some quarters, not all. At 30 s it does not warn in this
case. For 60 s the rig's cycle is a different regime (the house is not over
the cap there), so nothing is claimed. The cap held at 2 s and 5 s; at 10 s
and 15 s the meter's lag puts the highest quarter 20 to 55 W over 5000 W,
the same with and without the fix. Quarter-edge case, 15 s meter: the highest
quarter is 2327 W to 2680 W, the same with and without the fix.
**Accepted limits (owner, 2026-10-20, with N=8).** The owner accepted N=8
knowing that:
- at a 2 s meter the quarter-edge false alarm still shows on about 1 of 30
seeds (one notification in 2 h);
- at a 15 s meter the case above warns in only 1 to 3 of the 7 quarters
(some runs are silent for more than one quarter in a row);
- at a 30 s meter and slower it gives no warning in that case (0 in 2 h,
against 7 and 11 without the fix): a real bound is suppressed there;
- the cap is exceeded at 10 s and slower in that case (and up to 2680 W of
2500 W at 15 s on the quarter edge), the same with and without the fix.
A budget that follows the cycle length (10 cycles up to 3.5 s, 8 to 11 s, 6
to 16 s, 4 beyond) met both cases on every swept seed at 1 to 20 s (at
30 s: no false alarm, 3 to 5 of 7 quarters) in the dev round-3 sweep; it was
not adopted. Without a monotonic clock the budget
never refills, so a bound that stays is counted after 8 hidden cycles.
At 30 s no budget does better: 4 leaves two quiet quarters, 3 brings back
the false alarm. Single hand-back, the loop at its rail, first warning after
the hand-back compared with no fix: 10 s at 1 s, 20 s at 2 s, 40 s at 5 s
(default), 80 s at 10 s, 90 s at 15 s, 80 s at 20 s, 120 s at 30 s, 240 s at
60 s. At 60 s the rig is a different regime (the house is not over the cap
in the case above), so nothing more is claimed there. The cap held at 1 to
10 s in the quarter-edge case and at 1 to 5 s in the case above; at slower
meters the meter's lag puts quarters over it, the same with and without the
fix (commands are identical).
**Kept.** The loop in charge at its rail warns on the same cycle as before.
The start and a restart after a stop are not hand-backs. The quarter-edge
kick of `test_safety119.py` part 1 stays hidden (0 warnings in 2 h at
1, 2, 5, 10 and 15 s meters).
kick of `test_safety119.py` part 1 stays hidden (see above).
**Re-pinned.** test_safety84 (all six) and test_safety87 (`n1_crossing`,
`n1_above`, `n1_charge_low`): only OUTPUT_CLAMP log rows differ; commands and