The first Controller in test_opt34's run_night was built before the datetime patch, so Controller.init judged the stale_live latch (ends 2026-11-04 07:15 CET) against the real clock; it expired on 2026-11-04 and 'latch does charge both' failed on every branch. Now built after the patch with the clock at the scenario start (the restart path already did). Test-only, nothing under app/, no CHANGELOG.
The first Controller in test_opt34's run_night was built before the datetime patch, so Controller.__init__ judged the stale_live latch (ends 2026-11-04 07:15 CET) against the real clock; it expired on 2026-11-04 and 'latch does charge both' failed on every branch. Now built after the patch with the clock at the scenario start (the restart path already did). Test-only, nothing under app/, no CHANGELOG.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
The stale_live scenario stores a latch ending 2026-11-04 07:15 CET. The first
Controller was built before the datetime patch, so Controller.__init__ judged
that latch against the real clock and it expired on 2026-11-04. Build it after
the patch (clock = scenario start), as the restart path already did. Test-only.
Co-Authored-By: Claude <noreply@anthropic.com>
Scope: only goodwe_controller/test_opt34.py (+4 -1). Nothing in app/, no CHANGELOG, no config.yaml.
Cause and fix are right. Controller.__init__ reads datetime.now() once, for the stored latch (app/main.py:1041-1043). The first Controller in run_night was built before the clock patch, so it used the real clock. It is now built inside the patch at the scenario start. The restart path already worked this way. No check, tolerance or scenario date was changed. Proof that it still tests what OPT-34 meant: base 22d09f8 with the clock set to 2026-11-03 11:00 (before the latch ran out) and head today print identical test_opt34 output, apart from the run time.
My own runs in goodwe-addon-checks:1 (--network none, sim mounted, GOODWE_REQUIRE_HWSIM=1, using the dev's clock shim, which I read first):
base, today: FAIL, the same check as on the card ("control: the same latch ... does charge both", A 10.0 B 10.0)
head, today: all checks pass. With the clock at 2027-06-01 and 2030-01-01 the output is identical.
full suite on head, today: 94 files, 0 failed. At 2027-06-01: 94 files, 0 failed.
Scan spot-check: test_opt36, test_maint13, test_safety126 and test_arbitrage use the real clock only relative to now, or as a stopwatch. test_opt36 also builds its Controller before its clock patch, but it never stores a latch, so __init__ has nothing to expire. Only test_opt34 and test_opt36 store or read _charge_latch in __init__'s path. I agree with the dev: there are no other date bombs.
CI run 1528, job 2679, checks / unit (pull_request): success on 95bb214. In the log test_opt34 passes and the result is 94 files, 0 failed.
Note (no action): the clock is set to start when the Controller is built, then moves back to the evening reads. This is harmless, because the latch load is the only use of now() in __init__.
**TEST-37 review (head 95bb214): approved, merging.**
1. Scope: only `goodwe_controller/test_opt34.py` (+4 -1). Nothing in `app/`, no CHANGELOG, no config.yaml.
2. Cause and fix are right. `Controller.__init__` reads `datetime.now()` once, for the stored latch (`app/main.py:1041-1043`). The first Controller in `run_night` was built before the clock patch, so it used the real clock. It is now built inside the patch at the scenario start. The restart path already worked this way. No check, tolerance or scenario date was changed. Proof that it still tests what OPT-34 meant: base 22d09f8 with the clock set to 2026-11-03 11:00 (before the latch ran out) and head today print identical test_opt34 output, apart from the run time.
3. My own runs in `goodwe-addon-checks:1` (`--network none`, sim mounted, `GOODWE_REQUIRE_HWSIM=1`, using the dev's clock shim, which I read first):
- base, today: FAIL, the same check as on the card ("control: the same latch ... does charge both", A 10.0 B 10.0)
- head, today: all checks pass. With the clock at 2027-06-01 and 2030-01-01 the output is identical.
- full suite on head, today: 94 files, 0 failed. At 2027-06-01: 94 files, 0 failed.
4. Scan spot-check: test_opt36, test_maint13, test_safety126 and test_arbitrage use the real clock only relative to now, or as a stopwatch. test_opt36 also builds its Controller before its clock patch, but it never stores a latch, so `__init__` has nothing to expire. Only test_opt34 and test_opt36 store or read `_charge_latch` in `__init__`'s path. I agree with the dev: there are no other date bombs.
5. CI run 1528, job 2679, `checks / unit (pull_request)`: success on 95bb214. In the log test_opt34 passes and the result is 94 files, 0 failed.
Note (no action): the clock is set to `start` when the Controller is built, then moves back to the evening reads. This is harmless, because the latch load is the only use of now() in `__init__`.
admin
merged commit cfe1f06286 into hotfix-0.20.12026-11-05 13:56:39 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The first Controller in test_opt34's run_night was built before the datetime patch, so Controller.init judged the stale_live latch (ends 2026-11-04 07:15 CET) against the real clock; it expired on 2026-11-04 and 'latch does charge both' failed on every branch. Now built after the patch with the clock at the scenario start (the restart path already did). Test-only, nothing under app/, no CHANGELOG.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
TEST-37 review (head
95bb214): approved, merging.goodwe_controller/test_opt34.py(+4 -1). Nothing inapp/, no CHANGELOG, no config.yaml.Controller.__init__readsdatetime.now()once, for the stored latch (app/main.py:1041-1043). The first Controller inrun_nightwas built before the clock patch, so it used the real clock. It is now built inside the patch at the scenario start. The restart path already worked this way. No check, tolerance or scenario date was changed. Proof that it still tests what OPT-34 meant: base22d09f8with the clock set to 2026-11-03 11:00 (before the latch ran out) and head today print identical test_opt34 output, apart from the run time.goodwe-addon-checks:1(--network none, sim mounted,GOODWE_REQUIRE_HWSIM=1, using the dev's clock shim, which I read first):__init__has nothing to expire. Only test_opt34 and test_opt36 store or read_charge_latchin__init__'s path. I agree with the dev: there are no other date bombs.checks / unit (pull_request): success on95bb214. In the log test_opt34 passes and the result is 94 files, 0 failed.Note (no action): the clock is set to
startwhen the Controller is built, then moves back to the evening reads. This is harmless, because the latch load is the only use of now() in__init__.