PRICE-02 round 2: require now, undo the test loosening, analyse ties
- TariffPlan.arbitrage(now=...) is required (keyword-only, no default); so are homeview.trade_verdict/refusal_key's now. Existing test calls pass one. - test_arbitrage.py: no module-level decide wrapper. Fixtures that probed a one-day plan after its extremes now hold two days (as a site does); the flap day gets a unique cheapest and dearest hour; the replay breaks its ties without direction. The flap bound is <= 4 and the replay check is len(_trades) < 365 again. 228 checks pass on the old and the new code. - test_price02.py part 6: ties (equal quarters, a real 15-minute day, alternating hourly prices) and the required now. - Identity pins: the masked digest is only for the older-tree comparison; this tree's own digests are pinned with nothing hidden. - DECISIONS: the tie analysis with numbers. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
2ff9be710c
commit
891ed7bdd7
@@ -67,27 +67,53 @@ A, B = "inverter-a", "inverter-b"
|
||||
# ============================================================================ #
|
||||
print("1. modes off: byte-identical to 7a00f12 on the trade path")
|
||||
# Printed on release/1.0 7a00f12 (2026-09-29), goodwe-addon-checks:1, 1080
|
||||
# cycles each; the trade CHARGEs and DISCHARGEs. PRICE-02 (2026-10-22): the
|
||||
# digest is `ident.trade_digest()`, which hides two things in the trade
|
||||
# sentence: the "above the cheapest" figure (the plan now drops price periods
|
||||
# that have ended, so it is another number once the first cheap period is
|
||||
# over) and "hour" -> "price period". Re-measured with it on 7a00f12, on
|
||||
# release/1.0 90bc901 and on this tree: the same four digests.
|
||||
# cycles each; the trade CHARGEs and DISCHARGEs.
|
||||
#
|
||||
# PRICE-02 (2026-10-22) changed two things in the trade sentence and nothing
|
||||
# else: the plan now drops price periods that have ended, so a sale's "N above
|
||||
# the cheapest" is another number once the first cheap period is over, and the
|
||||
# sentences say "price period" for "hour". So there are three pins:
|
||||
# AT_7A00F12_OLD the digests printed on 7a00f12, sentence included. They no
|
||||
# longer match, and the check below says so: that is what
|
||||
# makes the mask necessary.
|
||||
# AT_7A00F12 the same rows through `ident.trade_digest()`, which hides
|
||||
# exactly those two things (and only for this comparison with
|
||||
# an older tree). It equals what 7a00f12 gives through it.
|
||||
# AT_NOW this tree's own digests, sentence included, with nothing
|
||||
# hidden: any later change to a command, a sentence or a
|
||||
# figure moves it. The mask cannot hide a future drift.
|
||||
AT_7A00F12_OLD = {
|
||||
"n1": "71245b227ca40bada4f71f57ea6154475f4b0bd60239c9ad4f80bffb0094514c",
|
||||
"n2": "56cf28010b06765c29e5479abb815d7503d570b39240d82dfc818efa90c93722",
|
||||
}
|
||||
AT_7A00F12 = {
|
||||
"n1": "33886ef03f364852883f0370230e6e04823fbb46a4704f88ca75bf9082d98c01",
|
||||
"n2": "666a31f41491c22750720524853d95944d5fba395d1d14040c460d71414b275f",
|
||||
"n1_off": "33886ef03f364852883f0370230e6e04823fbb46a4704f88ca75bf9082d98c01",
|
||||
"n2_off": "666a31f41491c22750720524853d95944d5fba395d1d14040c460d71414b275f",
|
||||
}
|
||||
AT_NOW = {
|
||||
"n1": "939b3d47bbd64fa50e3d70538f092fb98e5c4bd5ead85a7fc696a1dbb514039e",
|
||||
"n2": "c51008213dd739e1e5142c236d9a950aa585992393e4af120086f1ba52ff3e0d",
|
||||
"n1_off": "939b3d47bbd64fa50e3d70538f092fb98e5c4bd5ead85a7fc696a1dbb514039e",
|
||||
"n2_off": "c51008213dd739e1e5142c236d9a950aa585992393e4af120086f1ba52ff3e0d",
|
||||
}
|
||||
_cmd_digest = ident.trade_digest
|
||||
_rows = {k: ident.run(**ident.SCENARIOS[k])[0] for k in AT_7A00F12}
|
||||
_got = {k: _cmd_digest(v) for k, v in _rows.items()}
|
||||
for k in AT_7A00F12:
|
||||
print(f" {k} {'same' if _got[k] == AT_7A00F12[k] else 'DIFFERS'} "
|
||||
f"{_got[k][:16]}")
|
||||
_full = {k: ident.digest(v) for k, v in _rows.items()}
|
||||
check("with battery modes off (option absent or false), every command, "
|
||||
"integrator, allocation and trade sentence equals 7a00f12's, at one "
|
||||
"inverter and at two", _got == AT_7A00F12)
|
||||
"integrator, allocation and trade action equals 7a00f12's, at one "
|
||||
"inverter and at two (the sentence masked as above)",
|
||||
_got == AT_7A00F12)
|
||||
check("...the mask is needed and nothing more: unmasked, n1 and n2 differ "
|
||||
"from 7a00f12's printed digests, and unmasked they equal this tree's "
|
||||
"own pins, so a later change to any sentence or figure fails here",
|
||||
all(_full[k] != AT_7A00F12_OLD[k] for k in AT_7A00F12_OLD)
|
||||
and _full == AT_NOW)
|
||||
_acts = {r[-1][0] for r in _rows["n2"] if r[-1]}
|
||||
check("...and the runs reach the trade P3 now skips with modes on: a charge "
|
||||
"and a sale", {arbitrage.CHARGE, arbitrage.DISCHARGE} <= _acts)
|
||||
|
||||
Reference in New Issue
Block a user