CI-02 probe F: the ORIGINAL gate, unchanged, on the same unmergeable PR
checks / unit (pull_request) Successful in 3m38s
checks / unit (pull_request) Successful in 3m38s
This commit is contained in:
@@ -5,6 +5,13 @@ three refusable configurations are refused. The second asserts that everything
|
||||
on validate.py's "deliberately not refused" list still STARTS - because the way
|
||||
a validator dies is not by missing a fault, it is by refusing something harmless
|
||||
until somebody deletes the call.
|
||||
|
||||
⚠️ MUTATING THE MODULE THIS FILE GRADES? PURGE `__pycache__` FIRST - or run
|
||||
`tools/mutation_run.sh`, which does. `python3 -B` alone does NOT save you: it
|
||||
stops bytecode being WRITTEN, not a stale one being READ, and a size-preserving
|
||||
edit reverted inside one second is invisible to CPython's staleness test. That
|
||||
is TEST-15, and it has already turned one live mutation into a false survivor.
|
||||
Read MUTATION.md before you report a survivor.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
@@ -76,6 +83,40 @@ check("an unreachable device skips the range check rather than assuming",
|
||||
check("a non-numeric max_w is refused",
|
||||
why(validate_startup_config(base(max_w="lots"), -5000, 5000), "not a number"))
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 1b. SAFETY-20's AC4 decision, PINNED HERE RATHER THAN ONLY WRITTEN DOWN
|
||||
# --------------------------------------------------------------------------- #
|
||||
# AC4 asked whether a device rating that disarms SAFETY-18's freeze rail
|
||||
# additionally warrants a refusal of its own, the way `sign_disagree_w >= max_w`
|
||||
# is refused. THE ANSWER IS NO, AND THE REASON IS RULE 2 ABOVE: the configuration
|
||||
# is `max_w` above the device rating, which rule 2 already refuses on the
|
||||
# identical predicate. A rail-specific rule (`0.95 * max_w > dev_max`) would fire
|
||||
# on a strict SUBSET of what rule 2 refuses, so it could never be the rule that
|
||||
# stopped a start.
|
||||
#
|
||||
# ⚠️ THAT DECISION HAS A PREMISE, AND THIS IS THE PREMISE, EXECUTED. If rule 2 is
|
||||
# ever softened to a warning - which is exactly what main.py used to do before
|
||||
# CFG-01 - the reasoning recorded in validate.py's "deliberately not refused"
|
||||
# list silently stops being true, and SAFETY-18 is left with only its runtime
|
||||
# NOT COVERED row. Then somebody has to come back and re-decide AC4.
|
||||
from app.freeze import RAIL_FRAC # noqa: E402 - imported here, beside its use
|
||||
|
||||
_DEV = 4700.0 # the ticket's inverter
|
||||
_CEIL = 5000.0 # the ticket's configured ceiling
|
||||
check("SAFETY-20's premise: a rating below max_w disarms the freeze rail, so "
|
||||
f"{RAIL_FRAC:g} * max_w is unreachable on the ticket's install",
|
||||
_DEV < RAIL_FRAC * _CEIL)
|
||||
check("...and rule 2 REFUSES that whole configuration at startup, which is why "
|
||||
"SAFETY-20 added no rule of its own (AC4)",
|
||||
len(validate_startup_config(base(max_w=_CEIL), -_DEV, _DEV)) == 1)
|
||||
check("...on the rating side specifically, not incidentally through some other "
|
||||
"rule", why(validate_startup_config(base(max_w=_CEIL), -_DEV, _DEV),
|
||||
"THE DEVICE WINS"))
|
||||
check("...and the case the refusal CANNOT reach - the rating unread because "
|
||||
"ESPHome was not up - still starts, which is precisely why SAFETY-20's "
|
||||
"answer had to be a runtime status row and not a startup gate",
|
||||
validate_startup_config(base(max_w=_CEIL), None, None) == [])
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
print("2. an actuator to write to")
|
||||
# A controller with no actuator: write_setpoint() returns on the blank entity,
|
||||
|
||||
Reference in New Issue
Block a user