docs(planner): no-demand-window replay and price-block target design - #1052
Merged
Merged
Conversation
The tariff's demand charge is seasonal and the shoulder season has just started, but the planner's demand window is a clock window applied every day. Before changing that, measure what the planner does without it. scripts/replay_no_dw.py replays captured real days through the optimizer with the demand window removed from slot flagging, plus diagnostic arms that open the cheap-price gate and the min-cycle-saving hurdle, and a gateless arm where only the DP cost function decides. Results over ten days (2026-08-29..09-07) in simulations/replay-nodw/README.md: - nine sunny days are byte-identical with or without the window - on the one solar-deficit day (09-07) removing the window costs +$0.88: the demand-window water level was the only path admitting 7-8c morning slots for a 16-19c evening; the cheap-price gate cannot see the peak and the $0.25 hurdle rejects a 9c/kWh net spread - gateless with the hurdle at zero reproduces the demand-window plan to the cent, and no arm charged overnight at any hurdle (no #800 return) docs/PRICE_BLOCK_TARGET.md is the design that follows: split the window into a charge_window (demand charge, Amber's per-slot flag, drives only the import ban) and a forecast-derived target_block (the expensive evening, drives the deadline/target and useful period all year), with a load-sized target out of season and a separate block spread knob (default $0.08/kWh, decided 2026-09-08). Sliced vertically; slice 1 is gated on this replay plus a flap test and runs live in dry run first. Harness note: a fresh CoordinatorData carries forecast_horizon_hours=0, which the cheap-price calculation reads before the facade writes the real span, scaling the percentile by 0.1 on the first pass and sticking through the EMA hysteresis. The harness seeds the horizon before pass 1. The 2026-09-07 capture is committed as the load-bearing deficit day; the other captures are gitignored and regenerable while the recorder retains them.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…t slice 1
Three tasks for docs/PRICE_BLOCK_TARGET.md slice 1: the pure detector
module and its knobs, the planner wiring behind a default-off switch,
and the replay-harness block arm plus flap gate. Launch with
/routed-build-auto {"backlogFile": ..., "stack": true} once this PR
has merged; scope and gates are in the file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The tariff's demand charge is seasonal; the planner's demand window is a clock window applied every day. This PR lands the offline evidence for what the planner does without it, and the design that follows. No planner behaviour changes.
Related Issue
None yet — design PR. Slice 1 will get its own issue.
Changes
scripts/replay_no_dw.py: replays captured real days with the demand window removed, plus diagnostic arms (cheap gate open, hurdle open, gateless). Seedsforecast_horizon_hoursbefore the first pass (see harness note in the README).simulations/replay-nodw/README.md: results over 2026-08-29..09-07. Nine sunny days identical with or without the window; on the one deficit day removing it costs +$0.88 because the DW water level was the only funder of a 7c-morning-for-18c-evening pre-charge. Gateless with a zero hurdle reproduces the DW plan to the cent; no arm charged overnight at any hurdle.simulations/replay-nodw/2026-09-07.json: the deficit day, committed so recorder retention cannot lose it. Other captures gitignored.docs/PRICE_BLOCK_TARGET.md(+ INDEX link): split the window into acharge_window(demand charge, Amber's per-slot flag, drives only the import ban) and a forecast-derivedtarget_block(expensive evening, drives deadline/target/useful-period all year), load-sized target off-season, separateblock_min_spreadknob default $0.08 (decided 2026-09-08). Three vertical slices; slice 1 gated on this replay plus a flap test, live in dry run first.Testing
uv run scripts/replay_no_dw.py --arms dw,no_dw,gateless_mcs25,gateless_mcs10,gateless_mcs0reproduces the README table; ruff clean.Checklist