# SAFETY-83 - the peak guard outranks the maintenance drain at N=1 **Status: DECIDED 2026-09-29 (owner go, P1).** Follows SAFETY-78's "Not changed" list. Tests: `test_safety83.py`. **The defect.** At N=1 the drain is the site SET at `P_MAINTENANCE` (60). The peak floor is a limit at `P_PEAK` (50), and clause 2 applies only limits at or above the winner, so the floor was ignored and the house imported what the drain left. A 5000 W house under a 2500 W limit and a 2000 W drain banked 3000 W quarters; on the owner's settings (limit 3500, drain 2500, margin 50) a breach starts at about 5950 W. **The fix.** While a drain owns the setpoint at N=1 and the peak floor asks for more than the drain rate, `main.py` (`_peak_over_drain()`) refiles that peak claim at `P_MAINTENANCE`. The arbiter then applies it: the target is the floor, still inside the safety limits, and a safety SET (100) still parks everything. Where the floor is at or below the drain rate nothing changes. - The order in effect is now the same at N=1 and N=2: safety limits and the SAFETY-73 refusal > peak guard (with the SAFETY-79 margin) > maintenance > modes > trade > loop (`arbiter.py`, beside the priorities). - The drain keeps counting: the battery discharges at least the drain rate on every cycle, so the cycle is not reset or stalled; it only ends sooner. - Below the drain rate the rest is still exported (owner, 2026-09-29). - Identity: `tools/safety78_identity.py --diff` against 35cdffe changes only cycles where the guard asked for more than the drain; after such an episode the commands are identical again and only the log and the idle loop's integrator differ. N=2 is unchanged. **Not changed.** - Between the drain rate and the peak aim, the house still imports what the drain leaves (N=1 behaviour kept by the identity). At N=2 the loop covers it. - A maintenance HOLD (0 W, 120 min, battery full) still outranked the peak guard at N=1. Fixed by [[SAFETY-86]].