TEST-13: grade record_block()'s policy argument, and the two import spellings SAFETY-20's check could not see
checks / unit (pull_request) Successful in 3m55s

Two survivors from TARIFF-01's review, closed in test_tariff.py only. app/ is
untouched and no shipped behaviour changes. Two further items on the card were
already closed in shipped code and are struck rather than re-implemented.

ITEM 1 - the per-phase reduction's PLUMBING was unobservable.

  Mutating PeakStore.record_block()'s `billed_w(block, policy)` to
  `billed_w(block, POLICY_NET)` (+4 B) leaves all 17 suites green. Measured
  three times now: by TARIFF-01's reviewer, re-run through TEST-15's purge
  harness this session, and re-run again here on a clean uncontended tree.

  The product code is correct - tariff.py:363 really is
  `def record_block(self, block, policy: str = POLICY_NET)` and it really does
  forward the argument. What was missing is any check that could tell that
  apart from a hardcoded call, and the reason is the third instance of one
  shape: A STIMULUS EVALUATED WHERE THE QUANTITY IT GRADES IS DEGENERATE, after
  WITNESS-02's span normalisation and TARIFF-01's own DST window.

  billed_w() short-circuits to block.offtake_avg_w whenever
  per_phase_offtake_avg_w is absent. Every block reaching a store anywhere in
  the suite was single-phase or built as _CB(..., None) - so NET, SUM and MAX
  collapsed onto one number and the argument could not be observed at the call
  site. Section 7 grades the FUNCTION on an unbalanced fixture and says nothing
  about its CALLER.

  So section 7's own (3000, 500, -200) W block - whose three reductions are
  3300 / 3500 / 3000 W, asserted distinct three lines above - is now
  round-tripped THROUGH the store under each policy and read back from both
  tables (peak() and recompute_month(), so both writes in that single
  transaction are graded). record_block() with no policy is checked to bank the
  NET figure. An anti-degeneracy pin is stated over the three BANKED numbers,
  not over vals, because it is the banked ones this triple is made of.

  Direction, which is why this is worth plumbing-testing: NET is the SMALLEST
  of the three here, because the exporting phase nets off. A store that quietly
  billed NET while asked for MAX would UNDER-record the month's peak, and an
  under-recorded peak is maximum headroom for SAFETY-07 - the same
  under-guarding direction as the getattr(..., 0.0) default SAFETY-07 already
  removed from project().

ITEM 2 - the SAFETY-20 import grader claimed more than it checked.

  It collected `m.module for m in walk(tree) if isinstance(m, ImportFrom)` and
  matched a literal list of six spellings. That is blind to two of Python's
  three import forms:

    * `from . import arbiter as _ab` is an ImportFrom whose .module is None -
      the dots are in .level and the module name is in .names - so it collected
      "" and matched nothing;
    * `import app.arbiter` is an ast.Import node the walk filtered out entirely.

  Both were added to app/tariff.py and the shipped suite stayed GREEN, with the
  _names half not firing either (an alias import creates no Name node). Low
  severity: any USE of either alias still produces an Attribute the _names half
  catches. But the printed sentence "it imports nothing from arbiter, clamp or
  control" was false for two forms out of three, and a check that overclaims is
  worse than one that claims less, because the next reader stops looking.

  _imported_modules() now walks Import as well as ImportFrom and joins
  `from . import X` onto its base. _forbidden_imports() matches per dotted
  SEGMENT, not by substring: `app.arbiter` must not hide behind a package
  prefix, and `clamps` / `arbiters` / `controller` must not be falsely flagged -
  `controller` is not hypothetical, this package is goodwe_controller. Five
  evasion spellings and eight innocent ones grade the grader itself, and both
  the name half and the import half are shown non-vacuous against main.py,
  which carries all three import forms and really does import all three modules.

ITEMS 3 AND 4 - ALREADY CLOSED. STRUCK, NOT RE-IMPLEMENTED.

  Item 3: app/tariff.py:266-267 is `def is_observed(self): return self.state ==
  OBSERVED`, already false for NO_RECORD. Nothing to do.

  Item 4: app/tariff.py:672-680 reads `held = max(averager.held_net_w, 0.0)`
  with NO getattr default, and carries a comment naming TEST-13 item 4. Fixed
  by SAFETY-07 in 616b62d; held_net_w is a documented public property on
  QuarterAverager (p1.py:290), so a rename raises AttributeError on the first
  cycle instead of crediting 0 W held. A projection crediting 0 W held reads
  LOW, which is the under-guarding direction for SAFETY-07's floor. Restoring
  a default would re-open a money guard.

  And the recorded NON-finding stays a non-finding: removing clear_partial()
  is still green and that is a PASS. quarter_start is the PRIMARY KEY and the
  upsert carries `ON CONFLICT ... WHERE excluded.offtake_avg_w >
  quarter_blocks.offtake_avg_w`, so a replay is a structural no-op. That
  demonstrates TARIFF-01's "double counting is answered structurally, not by
  care" claim rather than contradicting it.

EVIDENCE - all through tools/mutation_run.sh (recursive __pycache__ purge,
python3 -B, tree re-read from disk, mutated line grepped off disk, byte delta
recorded), in the goodwe-addon-ci image against a :ro mount.

  baseline, 17 suites, before any edit ............................ 17 PASS
  baseline, 17 suites, final tree ................................. 17 PASS

  A1  billed_w(block, policy) -> billed_w(block, POLICY_NET)   +4 B  5 RED
      the 'sum' and 'max' round-trips, both tiers, and the distinctness pin
  A2  billed_w(block, policy) -> billed_w(block, POLICY_MAX)   +4 B  6 RED
      the 'net' and 'sum' round-trips, both tiers, the default, and the pin
  B1  add `from . import arbiter as _ab` to app/tariff.py     +29 B  1 RED
      the import sentence. SHIPPED suite on the same tree: GREEN - the hole.
  B2  add `import app.arbiter` to app/tariff.py               +19 B  1 RED
      the import sentence. SHIPPED suite on the same tree: GREEN - the hole.
  B3  add `from .control import compute` (the form the OLD grader DID
      catch, as a regression control)                                1 RED
  C1  delete the ast.Import branch from _imported_modules()          1 RED
      names the two spellings it MISSED, so the grader-grader is live
  C2  segment match -> substring match (`any(f in m for f in ...)`)  1 RED
      names clamps / arbiters / controller as falsely flagged

  CONTROL, and the point of the whole ticket: A1 graded by the SHIPPED
  test_tariff.py is green, and A1 graded by all 17 SHIPPED suites on a clean
  uncontended run is 17 PASS, rc=0. The survivor is real and it is now closed.

ONE THING THE REVIEWER SHOULD KNOW. During the first (contended - two docker
containers at once) run of that 17-suite survivor sweep, test_peakguard.py
reported FAIL once. It has passed 8 times since on the identical tree,
including three concurrent runs and one clean uncontended full sweep, and its
tail was lost to a grep so I cannot say which check it was. I believe it is a
timing-sensitive check under CPU contention and NOT related to this change -
this commit touches no product code and no peakguard fixture - but I could not
reproduce it, so I am recording it rather than asserting it away.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-09-01 08:40:09 +02:00
co-authored by Claude Opus 5
parent 950472662e
commit acbdf41248
3 changed files with 208 additions and 15 deletions
+52
View File
@@ -2,6 +2,58 @@
## Unreleased
**`PeakStore.record_block()` now has its POLICY ARGUMENT graded, and the
SAFETY-20 import check now looks at all three ways of writing an import
(TEST-13).** Two survivors from TARIFF-01's review, both closed in
`test_tariff.py` only - `app/` is untouched and no shipped behaviour changed.
* **The plumbing of the per-phase reduction was unobservable.** Mutating
`record_block()`'s `billed_w(block, policy)` to `billed_w(block, POLICY_NET)`
left all 17 suites green (+4 B; recorded by TARIFF-01's reviewer, re-run
through the purge harness for TEST-15, and re-run again here). The cause is
the third instance of the same shape as WITNESS-02's span normalisation and
TARIFF-01's own DST window: **a stimulus evaluated where the quantity it
grades is degenerate.** `billed_w()` short-circuits to `block.offtake_avg_w`
whenever `per_phase_offtake_avg_w` is absent, and every block that reached a
store anywhere in the suite was single-phase or built with
`per_phase_offtake_avg_w=None` - so NET, SUM and MAX collapsed onto one
number and the argument could not be seen. Section 7 already owns an
UNBALANCED fixture, `(3000, 500, -200) W`, whose three reductions are 3300 /
3500 / 3000 W; that block is now round-tripped **through the store** under
each policy and read back from both tables. NET is the smallest of the three
here, so a store that quietly billed NET while asked for MAX would
under-record the month's peak - maximum headroom for SAFETY-07, the same
under-guarding direction as the `getattr(..., 0.0)` default SAFETY-07 already
removed from `project()`.
* **The import half of the SAFETY-20 grader made a claim it did not check.** It
collected `ImportFrom.module` only, which is blind to two of Python's three
import spellings: `from . import arbiter as _ab` is an `ImportFrom` whose
`.module` is **None** (the module name is in `.names`), and `import
app.arbiter` is an `ast.Import` node the walk never visited. Both were added
to `app/tariff.py` and the shipped suite stayed **green**. Never a live
exposure - the `_names` half still catches any USE of either alias - but the
printed sentence "it imports nothing from arbiter, clamp or control" was
false for two forms out of three, which is worse than claiming less. The
grader now walks `Import` as well, joins `from . import X` onto its base, and
matches per dotted SEGMENT so `app.arbiter` cannot hide behind a package
prefix while `clamps` / `arbiters` / `controller` are not falsely flagged.
Both graders are also now shown non-vacuous against `main.py`, which really
does import all three modules.
* **Two items on the card were already closed and are struck, not
re-implemented.** `PeakReading.is_observed` is `self.state == OBSERVED`
(`app/tariff.py:266`), already false for `NO_RECORD`; and `project()`'s
`held` read is `max(averager.held_net_w, 0.0)` with **no** `getattr` default,
fixed by SAFETY-07 in 616b62d with a comment naming TEST-13 item 4. Restoring
a default there would re-open a money guard. Removing `clear_partial()` also
stays green and that remains a **PASS**: the `quarter_start` PRIMARY KEY plus
`ON CONFLICT ... WHERE excluded > existing` makes a replay a structural
no-op, which is TARIFF-01's claim rather than a hole in it.
Verified through `tools/mutation_run.sh` (purge, `python3 -B`, tree re-read from
disk, mutated line grepped off disk, byte delta recorded): 7 mutations, all red
on the named checks, plus green baselines before and after and a control run
showing the shipped suite passing every one of them.
**The two `arbitrage()` rungs SAFETY-26's AC4 sweep found pinned from ONE SIDE
ONLY are now pinned from both - and, the actual finding, are pinned so they stop
MASKING EACH OTHER (TEST-16).** `spread == 0.0` weakened to `<= 0.001` survived