Skip to content

docs(debug-journal): fold in the 2026-09-25 queue slice; correct the #5103/#5186/#5053-adjacent entries - #5223

Merged
springfall2008 merged 1 commit into
mainfrom
bot/debug-journal-2026-09-25
Sep 26, 2026
Merged

springfall2008 merged 1 commit into
mainfrom
bot/debug-journal-2026-09-25

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

🤖 Automated journal flush — this PR was produced by the daily /journal-update run against the queue at /Users/treforsouthwell/predbat-triage-bot/journal-queue (slice: first 15 candidates in filename sort order, 2026-09-25). Every claim below was re-verified against origin/main (130596bc) before it went in. 33 candidates remain queued beyond this slice.

Queue candidates folded in (13 entries, 15 candidates)

Candidate What happened Why
5112-ml-model-status-signals Folded — extended the Load ML row with the model-status signals: is_valid() reports "active" for a never-trained model (model_initialized set before the first epoch; validation_mae/age skip None), training_timestamp is None is not a sound never-trained test (legacy saved models), and train() stamps at the end of every curriculum pass so an abort leaves fresh stamps that suppress the ml_max_model_age_hours retrain. The normalisation-statistics pairing stays marked suspected, not measured. Verified on main: is_valid() at load_predictor.py:2042-2066 still has the gap; PR #5112 is still an unmerged draft, so the entry says so explicitly.
5144-octopus-payment-method-variant-rows Folded as fixed — Octopus row now records the overlapping DIRECT_DEBIT/NON_DIRECT_DEBIT rows, minute_data()'s last-row-wins, the period-to-period flip ("always the higher rate" was API-ordering artefact), and the fix: filter_payment_method() (utils.py) from PR #5145, preferring DIRECT_DEBIT, keeping nulls. Verified: filter_payment_method() exists (utils.py:1313) and is applied on the day/night, component, annual and minute-data paths (octopus.py:1774/1775/2028/2937); added by 60db7e1c via b4edced9 (PR #5145). Its docstring itself records "not stable across periods" and the Agile null case.
5146-hold-for-car-gate-divergence + 5151-car-hold-skipped-during-export Folded together into the Car charging row: the two different "Hold for car" gates (live execute.py block vs prediction.py's (car_load_scale > 0) and (not car_charging_from_battery) and set_charge_window), the deliberate export-window exemption, and the diagnostic pointers. Verified: prediction.py:865-866 gate unchanged; execute.py carHolding block has if not isExporting: and the reserve bump; discharge_car_full_bat2 still in test_execute.py (moved :2324→:3160).
5150-control-active-restart-gate Folded into the Sunsynk/DEYE row: PR #5150's persistence + upgrade-cache inference, and the wrong "presses this on every cycle" comment (both inverter.py press sites are change-gated; the unconditional post-restart re-commit is is_hm_format-only, which excludes HH:MM:SS). The suspected #5138 link is not recorded as fact — the journal already credits #5142 with the confirmed mechanism. Verified: time_button_press: True for both types (config.py:2318/:2350) but the press sits inside if schedule_changed: (inverter.py:2820-2823) / if current_soc != soc: (:2079-2090); is_hm_format net at :2813-2818; SUNSYNK_RESTORE_MAX_CONTROL/DEYE_RESTORE_MAX_CONTROL live.
5152-solis-hold-timed-only-current Folded into the Solis row: the only discharge-suppression lever is set_current_from_power()'s timed current; the standing battery_discharge_current registers are never driven; GS has no reserve/pause alternative. Firmware-semantics claim stays marked not live-log confirmed. Verified: inverter.py:2985-2995 writes only timed_{direction}_current; grep for battery_discharge_current across the repo is empty; INVERTER_DEF["GS"] flags as the candidate said.
5153-predheat-weather-unit Folded into the Predheat row: no °F conversion in get_weather_data() (runaway-to-external mechanism), plus the second bug (minute_data_age includes optional heating_energy's age → target sensor ignored), plus the three investigation traps. Verified: predheat.py:186-201 passes temperature raw; minute_data_age = min(age_external, age_internal, age_target, age_energy) at :553.
5156-deye-tou-filler-truncates-windows Folded as fixed. The Deye filler truncation is repaired on main: build_tou_slots() now lives in the shared tou_schedule.py, and _padding_segments() places padding just after the slot it follows with the same state — "a real but inert interval" — with the docstring citing GH#5156 by name. Kept the pre-fix tell (stops at 00:00/04:00/08:00/12:00/16:00/20:00 while the plan shows charging). Verified: tou_schedule.py:146-174, docstring cites GH#5156; TOU_FILLER_TIMES no longer exists anywhere. The candidate's own one-line fix was superseded by the shipped rework.
5157-teslemetry-silent-drift-blind-reassert Folded as implemented into the Teslemetry row: the reporter's silent-drift evidence kept (read-back stays correct, restart recovered), and the fix — run() re-asserts the whole device tuple (export rule, grid charging, reserve, mode, not the tariff) every FORCED_ASSERT_SECONDS (2h) with the dedupe bypassed. Verified: FORCED_ASSERT_SECONDS = 2*60*60 (teslemetry.py:57), comments cite GH#5157, Info line names the re-assert; commit 077f5040 (2026-09-19).
5162-manual-soc-floor-inert-at-zero-rates Folded into the keep-mechanisms section: the floor penalty is weighted by the import rate at the deficit minute, so it is inert inside 0p windows; the ceiling is export-rate-weighted and survives; the ✍ marker is drawn regardless of whether the plan met the target; the manual_charge lookalike trap. Verified: prediction.py:1323-1328 + kernel mirrors; manual_soc_max/all_active_keep_max at fetch.py:935-959.
5166-edf-kraken-day-night-400 + 5166-kraken-rest-400-day-night + 5167-kraken-fetch-rates-error-contract Folded together as a new Kraken row (the journal had none): EDF 400-on-day/night vs Octopus 200-empty cross-provider trap; the fix shipped in PR #5167 (merged) — GraphQL fallback gate now (400, 404, 410) per direction, authenticated retry stays 404/410, standing-charge fallback stays 404/410 deliberately; the (None, None) tuple contract and the failures_total double-count are recorded as fixed-on-main with the mechanism kept. The "E-TOU on E.ON Next = 400" re-attribution the review reverted is not recorded. Verified on main: KRAKEN_REST_RATES_UNAVAILABLE_STATUSES/..._PRODUCT_NOT_FOUND_STATUSES (kraken.py:219-220), the (None, None) stash at :876-884, the counter snapshot at :900-906, the deliberate standing-charge gate at :999-1005.
5168-manual-rates-day2-extension-write Folded as fixed — new "Manual rates (fetch.py basic_rates())" row. The mechanism (last-rule-for-a-slice won on day+2; exactly 48h out) is kept with "fixed in PR #5173"; the final fix stamps the whole horizon per weekday (2139b063 from review), not just the day+2 gate the candidate described. Kept the end: "06:59:59" final-minute trap and the metric_future_rate_offset test pin. Verified: whole-horizon stamping at fetch.py:2290-2323 with the batpred#5168 comment; tests 13/14 + third-day assertions in 6/7 now pin every horizon day (the candidate's test blind spot is closed on main, so the entry says so as history).
5169-5053-cache-now-on-main Dropped as a duplicate — the journal already reflects #5053 merged (both the redaction entry and the GH#5063 premise-trap bullet), and this candidate added nothing beyond what is already there. The one durable nugget (the lock must be a shared class attribute, not lazily built) is now recorded on the redaction entry as a fact of the merged PR #5171 mixin. Verified: class Hass(LogRedaction) (hass.py:187), mixin in log_secrets.py:25.

Existing entries corrected (4)

  1. GE Cloud row, GH#5103 "still live" → corrected to fixed in PR fix(gecloud): re-read EMS battery inverter settings and warn on a slot 1 override #5109 (merged 2026-09-24): settings are re-read hourly (SETTINGS_SLOW_REFRESH_SECONDS), EMS/gateway devices every cycle, and check_ems_inverter_slots() now warns on a non-00:00–23:59 slot 1 — so the old entry's "nothing checks the per-inverter slot windows" and "there is no warning" are no longer true. Pre-fix(gecloud): re-read EMS battery inverter settings and warn on a slot 1 override #5109 signature kept, plus the settings_from_cache nuance.
  2. Teslemetry row, teslemetry_tbc_control "trial setting" → corrected to default on since PR feat(teslemetry): enable teslemetry_tbc_control by default #5188 (single source of truth in teslemetry.py, registry default components.py:635); verified by test_teslemetry_tbc_control_defaults_on_via_the_registry.
  3. Redaction entry + GH#5063 premise bullet → _invalidate_log_secret_pattern() no longer lives in hass.py; PR Move the log-redaction cache into a self-contained mixin (#5169) #5171 moved the cache into the LogRedaction mixin (log_secrets.py), shared class-attribute lock.
  4. Solis row → added PR Solis: cap slot currents at the inverter rating and distrust implausible recovery SOC #5189 (merged 2026-09-24, GH#5187): per-slot currents now also capped at the inverter's rated current on top of the sysCommand.max clamp. (Correction by merge-scan, not from a queue candidate.)

Left queued

33 candidates beyond the 15-candidate slice (5169-per-test-fixture… through 5222-soc-max-calculated…) — untouched, to be offered on a later day.

…5103/#5186/#5053-adjacent entries

Folded (13 entries from the 15-candidate slice, all re-verified against origin/main 130596b):
- Load ML row (GH#5075, PR #5112 open draft): is_valid() can report active for a never-trained
  model; training_timestamp is None is not a sound never-trained test (legacy saved models);
  train() stamps at the end of every curriculum pass, so an abort leaves fresh stamps that
  suppress the ml_max_model_age_hours retrain. Normalisation-statistics skew stays suspected.
- Octopus row: GH#5144 overlapping DIRECT/NON_DIRECT_DEBIT rows, minute_data last-row-wins and
  the period-to-period flip - fixed in PR #5145 (filter_payment_method, keeps nulls).
- Car charging row: GH#5146/GH#5151 the two different Hold-for-car gates (execute.py live block
  vs prediction.py plan gate), deliberate export-window exemption test-codified
  (discharge_car_full_bat2), read-only users never see the status sensor's annotation.
- Sunsynk/DEYE row: PR #5150 control_active persistence + upgrade-cache inference; the in-code
  press every cycle comment is wrong (both press sites change-gated, post-restart re-commit is
  is_hm_format-only); GH#5156 TOU padding truncation fixed in tou_schedule.py _padding_segments.
- Solis row: GH#5152 the hold lever is the window-scoped timed current (standing
  battery_discharge_current never driven); PR #5189 adds the rated-current cap (GH#5187).
- Predheat row: GH#5153 no Fahrenheit conversion in get_weather_data + the optional
  heating_energy age bug pinning minute_data_age to 0.
- Teslemetry row: GH#5157 forced re-assert implemented (FORCED_ASSERT_SECONDS = 2h, dedupe
  bypassed, tariff excluded); tbc_control default on since PR #5188.
- Keep section: GH#5162 manual_soc floor penalty is import-rate-weighted, so inert inside 0p
  windows; the manual_soc_max ceiling is export-rate-weighted; manual_charge lookalike trap.
- New Kraken row: GH#5166/PR #5167 EDF 400-on-day/night vs Octopus 200-empty;
  KRAKEN_REST_RATES_UNAVAILABLE_STATUSES; the (None, None) tuple contract and the
  failures_total double-count, both fixed in the merged PR and kept as mechanisms.
- New Manual rates row: GH#5168 day_of_week stamped across the whole rate horizon, fixed in
  PR #5173; end ':59:59' final-minute trap and the metric_future_rate_offset test pin kept.

Dropped: 5169-5053-cache-now-on-main (already covered by the redaction entry and the GH#5063
premise bullet; its lock-lazy-init nugget is recorded as a fact of the merged PR #5171 mixin).

Corrected by the merge scan: GH#5103 fixed in PR #5109 (hourly settings refresh + the new
check_ems_inverter_slots warning); teslemetry_tbc_control default on (PR #5188); the
log-redaction cache moved into the LogRedaction mixin (log_secrets.py, PR #5171).

Co-Authored-By: Claude Code <noreply@anthropic.com>
@springfall2008
springfall2008 marked this pull request as ready for review September 26, 2026 08:22
@springfall2008
springfall2008 merged commit c2c74a3 into main Sep 26, 2026
1 of 2 checks passed
@springfall2008
springfall2008 deleted the bot/debug-journal-2026-09-25 branch September 26, 2026 08:22
springfall2008 pushed a commit that referenced this pull request Sep 26, 2026
Resolve debug-journal conflicts with #5223's fold of the same merge batch:
- Solis: keep this PR's #5189 detail and write-skip/test notes, then main's GH#5152 window-scoped hold lever
- GE Cloud: main's #5109 wording plus the once-per-episode ems_slot_warned warning and its log text
- Teslemetry: this PR's #5188 default-flip consequences plus main's GH#5157 forced re-assert
- Manual rates: fold both rows into one (#5173 fix, surviving :59:59 boundary-minute and offset traps, test lesson)
- Kraken, Sunsynk, Octopus, Car charging from main; Axle, GivTCP, Compare and the three new rows from this PR

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant