Skip to content

fix(history): keep unseen optional PV out of load training - #1759

Merged
frahlg merged 1 commit into
masterfrom
fix/training-requires-optional-pv
Oct 20, 2026
Merged

frahlg merged 1 commit into
masterfrom
fix/training-requires-optional-pv

Conversation

@frahlg

@frahlg frahlg commented Oct 20, 2026

Copy link
Copy Markdown
Member

Problem

Codex's adversarial review of #1752–#1755 (high): History leaves an optional PV source out of Home use when it has never reported, because a hybrid inverter may have no panels (historyMeasurementOptions drops it; forecastMeasurementOptions requires it). Since #1754 both load models train on history intervals, so such a quarter could become a training label. Example: 1 kW grid import plus 2 kW of unseen PV becomes a 1 kW label for a 3 kW house. The old forecast collector never trained on it.

Change

  • telemetry.ForecastOptions.OptionalFlows carries the flows History does not require but a training label does. historyMeasurementOptions fills it. The field is omitempty, and only the forecast Options are hashed into the learning revision, so no site loses learning.
  • optionalPVUnread (beside fix(history): count unknown PV as 0 W after sunset #1755's dark-PV rule) marks a snapshot EstimatedLoad while an optional PV source has no live reading. Home use is unchanged; training skips the interval, per the two-layer contract.
  • Past civil dusk the PV is 0 W by physics, so a night still trains, as in fix(history): count unknown PV as 0 W after sunset #1755. Without a map pin nothing is inferred.

Evidence

  • TestHistoryOptionsKeepOptionalPVForTraining: History does not require the optional PV, carries it in OptionalFlows, and the forecast options' JSON (the revision input) has no new key.
  • TestOptionalPVUnreadKeepsDaytimeOutOfTraining: day and twilight are marked, past civil dusk is not, a night without a pin is, and a reporting PV is not; nothing changes what History shows.
  • go test ./cmd/ftw ./internal/state ./internal/telemetry ./internal/loadmodel ./internal/api: all pass. Telemetry-read guard: none added.

The other Codex finding (a rejected held value can return) is being fixed separately in the history writer.

🤖 Generated with Claude Code

History leaves an optional PV source out of Home use when it has never
reported, as a hybrid may have no panels. The forecast requires it, and
both load models now train on history intervals, so 2 kW of unseen PV
could become a 1 kW label for a 3 kW house (Codex review of #1754).

History options now carry the optional flows. While one has no live
reading, the snapshot is marked EstimatedLoad: Home use is unchanged
and training skips it. Past civil dusk the PV is 0 W by physics, so the
night still trains. Forecast revisions are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T05:06:44.012691Z 1ac43da PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@frahlg
frahlg merged commit bbaf0b3 into master Oct 20, 2026
23 checks passed
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