ARCH-02: assert the invariant, because a fixture cannot enumerate arrangements
checks / unit (pull_request) Successful in 6m55s
checks / unit (pull_request) Successful in 6m55s
Review approved and then attacked part 5b, the control that stands between B1's
defect and a green suite. It got through in three edits:
A1 delete `END LEG` 5b CATCHES it 2 FAIL
A2 ...and reorder the legs 5b BLIND 1 FAIL
A3 ...and reword the closing summary 0 FAIL, "all checks passed"
with a splitter that closed
ZERO legs
⚠️ TWO OF THOSE THREE ARE ORDINARY REFACTORS - reordering report legs, rewording
a summary line - and neither reads as touching a safety check. 5b caught the
unclosed splitter only because the clean leg happened to be printed LAST, and
the backstop that saved A2 was a hardcoded transcription of the tool's own
sentence, so rewording that sentence blinded it too.
FIXED BY ASSERTING THE STRUCTURE RATHER THAN ADDING A FIXTURE: a leg may not
open while one is open, and every leg that opens must be explicitly closed.
Driven - deleting `END LEG` now fails on the FIRST edit, whatever the order or
the wording:
AssertionError: leg 'SAME-STEP' opened while 'STAGED' was still open - the
tool stopped closing its legs, and a splitter that never closes swallows the
closing summary into the last leg.
All three attacks include that edit, so one assertion kills the class. Clean
tree unchanged: 28/28, all checks passed.
⭐ AND THE RULE IN MUTATION.md IS EXTENDED, because review's finding is the
general case of it. It said "a per-thing check that has never seen the things
DISAGREE is a total". Part 5b DOES make them disagree, every run, and was still
blind. So:
...AND ONE THAT HAS ONLY SEEN THEM DISAGREE IN ONE ARRANGEMENT IS A TOTAL
OVER THAT ARRANGEMENT. When a fixture cannot enumerate the arrangements,
assert the invariant they share.
Also recorded, NOT fixed, with the reason: the reference carries `entity_id
unique_id device` and grades all three, but never the discovery TOPIC. Review
measured `homeassistant/... -> ha/...` exiting 0 with no findings while every
announced entity dies. `discovery_payloads()` already returns the topic and
`announced_rows` discards it, so a fourth column closes it - but the prefix is
HA's fixed contract rather than a name this project chooses, so it is not what a
tidy-up rename reaches. Lower LIKELIHOOD than the N1 gap it resembles, not lower
consequence, and it stops being a note the day the topic becomes configurable.
Two stale figures corrected: the tool claimed five migration mutations where
there are nine, and pointed at a DOCS.md heading that does not exist (the real
one is "Before you commission inverter B", verified present at DOCS.md:1577).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
This commit is contained in:
co-authored by
Claude Opus 5
parent
9c1a9e0f17
commit
22ca341459
@@ -37,13 +37,14 @@ lands on the copy. The scratch file is unique per invocation, which is habit 18.
|
||||
|
||||
⚠️ IT DOES NOT TOUCH THE LIVE BOX AND CANNOT. There is no SSH, no Supervisor
|
||||
call and no HTTP in this file. Fetching the state file is an OWNER STEP and it
|
||||
is written down in DOCS.md under "Rehearsing the roster switch (ARCH-02)".
|
||||
is written down in DOCS.md under "Before you commission inverter B:
|
||||
tools/rehearse_roster.py (ARCH-02)".
|
||||
|
||||
EXIT CODES
|
||||
0 the transition is clean: nothing vanished, nothing was stranded under a
|
||||
name no machine reads, no entity was orphaned, no history was lost.
|
||||
1 ⭐ AT LEAST ONE OF THOSE HAPPENED. This is the code that must be
|
||||
reachable: `test_rehearse.py` mutates the shipped migration five
|
||||
reachable: `test_rehearse.py` mutates the shipped migration nine
|
||||
different ways and requires this exit code for each.
|
||||
2 the rehearsal could not be performed (bad file, unparseable config, the
|
||||
entity-id model failed its own anchor). ⚠️ NOT A PASS.
|
||||
@@ -292,6 +293,26 @@ class Row:
|
||||
f"{self.device_id})")
|
||||
|
||||
|
||||
# ⚠️ WHAT THE REFERENCE STILL DOES NOT CARRY: THE DISCOVERY TOPIC.
|
||||
#
|
||||
# The three columns are `entity_id unique_id device`, and the payload is graded
|
||||
# against all three. The TOPIC is not. Measured by review:
|
||||
#
|
||||
# homeassistant/sensor/... -> ha/sensor/... exit 0, NO FINDINGS
|
||||
# sensor -> binary_sensor on the unit rows exit 0, NO FINDINGS
|
||||
#
|
||||
# In the first, HA never receives any discovery at all and every announced
|
||||
# entity dies - reported clean. `discovery_payloads()` already returns the
|
||||
# topic; `announced_rows` discards it, so a fourth column closes it.
|
||||
#
|
||||
# ⚠️ RECORDED AND NOT FIXED, deliberately, with the reason: the prefix is HA's
|
||||
# fixed contract rather than a name this project chooses, so it is not the kind
|
||||
# of value a tidy-up rename reaches - which is exactly the risk `mqtt.py`'s own
|
||||
# header warns about for `unique_id`. That makes it lower-likelihood than the
|
||||
# N1 gap it resembles, not lower-consequence. If the topic ever becomes
|
||||
# configurable, this stops being a note and becomes the same defect.
|
||||
|
||||
|
||||
def announced_rows(opts: dict) -> "dict[str, Row]":
|
||||
"""`{entity_id: Row}` for every row this add-on announces on `opts`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user