# Conflicts: # goodwe_controller/CHANGELOG.md
This commit is contained in:
@@ -68,6 +68,61 @@ process; the unwiring mutation fails three checks there. The peak-guard call
|
||||
site's wiring is still ungraded — it sits behind `p1_enabled` and needs a fed
|
||||
averager to have any observable consequence — and that gap is named in the file
|
||||
rather than implied.
|
||||
**A mutation run could grade code that was not there, and the fix is a purge
|
||||
rather than a flag (TEST-15).** FCST-03's developer reverted `self.provisional`
|
||||
to `here.provisional`, re-ran, and reported a survivor; disassembly showed the
|
||||
source read `here` while the running code loaded `self`. CPython validates a
|
||||
`.pyc` on (source size, source mtime truncated to whole seconds), and a
|
||||
size-preserving edit reverted inside one second moves neither number, so the
|
||||
stale bytecode was reused. That does not make past results wrong - it made them
|
||||
unverified, and the distinction is the whole card.
|
||||
|
||||
Reproduced rather than reasoned about. `test_bytecode.py` builds a real package
|
||||
whose two return values are the same length, imports it in a real subprocess,
|
||||
rewrites it inside the same second and reads back which value ran. Part 1 shows
|
||||
the interpreter running `SELF` off a file that says `HERE`.
|
||||
|
||||
**And it shows the two obvious mitigations do not work.** `python3 -B` and
|
||||
`PYTHONDONTWRITEBYTECODE=1` are write-side only: neither stops an EXISTING stale
|
||||
`.pyc` being read, and a mutation run always has one because the previous run
|
||||
wrote it. The advice already in `test_control.py`'s coverage audit led with `-B`
|
||||
and is corrected here - the purge is the half that works, and `-B` earns its
|
||||
place by protecting the NEXT edit rather than this one. No `sleep` anywhere:
|
||||
one-second mtime resolution is the mechanism, and waiting it out would slow every
|
||||
run down while still only covering the edit somebody remembered to slow.
|
||||
|
||||
`goodwe_controller/tools/mutation_run.sh` is the harness the house adopts: it
|
||||
purges, prints a sha256/byte fingerprint of every `app/*.py` it is about to
|
||||
grade - so a mutation report can say WHICH source produced it - runs each suite
|
||||
under `python3 -B`, refuses a tree with no `test_*.py` (CI-01's rule), and fails
|
||||
if a cache appears during the run. It takes the tree as an argument so the infra
|
||||
repo's replay harnesses can call it.
|
||||
|
||||
`MUTATION.md` states the guarantee where a mutation gets written, and every one
|
||||
of the 16 suites now points at it from its docstring - a list `test_bytecode.py`
|
||||
derives from the tree, so a new suite joining without the pointer is red.
|
||||
|
||||
CI was already immune and is described that way rather than as a hole being
|
||||
closed: `checks.yml` mounts the checkout `-v "$WS:/w:ro"`, and a read-only tree
|
||||
cannot take a `__pycache__` at all - measured, and it fails silently, exit
|
||||
status 0 - while each job `rm -rf`s its workspace and clones afresh.
|
||||
`PYTHONDONTWRITEBYTECODE=1` is added as belt and braces, because the `:ro` is one
|
||||
character wide. The shipped add-on was never affected: `Dockerfile` has set
|
||||
`PYTHONDONTWRITEBYTECODE=1` since it was written.
|
||||
|
||||
**The survey of this week's mutation claims is in `MUTATION.md`, scoped by the
|
||||
property rather than by re-running everything.** The defect is one-directional -
|
||||
stale bytecode turns a red into a green survivor and never the reverse - so every
|
||||
"all red, no survivors" result in the window is not at risk, and the exposure is
|
||||
the recorded SURVIVORS from source-edit runs made before the purge discipline
|
||||
landed on 2026-08-31. Two of them were re-run here under the harness and both
|
||||
still stand (TARIFF-01's `record_block()` ignoring its `policy` argument;
|
||||
SAFETY-03's `abs()` on the clamp limit). The rest are labelled still-unverified
|
||||
rather than quietly assumed or noisily re-run.
|
||||
|
||||
Out of scope and recorded: the infra repo's `sim/` replay harnesses import the
|
||||
add-on and write bytecode into both trees. Anyone mutating a module graded by a
|
||||
replay must purge both by hand until that repo adopts the harness.
|
||||
|
||||
**`release/1.0` went red at midnight on a commit nobody had touched (TEST-17).**
|
||||
`Controller.checks()` read the capacity-tariff peak with `self.peak.peak()` - no
|
||||
|
||||
Reference in New Issue
Block a user