Skip to content

feat: say on the dashboard when an install's fit lands far from the priors - #23

Merged
zebraengine merged 1 commit into
mainfrom
feat/fresh-install-prior-notice
Aug 27, 2026
Merged

feat: say on the dashboard when an install's fit lands far from the priors#23
zebraengine merged 1 commit into
mainfrom
feat/fresh-install-prior-notice

Conversation

@zebraengine

Copy link
Copy Markdown
Owner

Problem

DEFAULT_TAU_MIN = 12 and DEFAULT_RISE_REF_C = 36 come from one verified install. On a fresh install they govern the derate forecast and the amp controller until the first fits land, and once fitted the dashboard said only "fitted from N sessions" — a user whose charger has a 20-minute τ or a 25 °C rise had no way to know that the forecasts before that point were built on numbers that did not describe their hardware. Since #21, a fast-τ install also carries a standing cost that nothing surfaced: the fitter's identifiability gate is floored at the default τ, so short charges there never teach the model.

Item 3 of the "stop the priors from being per-one-install" follow-ups; independent of #22.

Code touched

  • wallmonitor/thermal.pyThermalParams.prior_deviation(): fitted τ and rise against the defaults as fractions, plus notable when either exceeds PRIOR_DEVIATION_FRAC = 0.30 (labelled a heuristic in the comment — it is roughly where the default-driven plateau error exceeds the fit's own noise, not a statistic). None until fitted. Included in as_dict() as model.prior_deviation, so /api/thermal and the SSE thermal frame carry it.
  • wallmonitor/static/app.js — the dashboard model note appends, once fitted and notable, which parameter differs and by how much, states that earlier forecasts were rough, and for τ more than 30% under the default adds that only charges ≥ 1.8 × default τ (≈ 22 min) at steady current teach the model. The unfitted note now says the defaults are "from one verified install".
  • docs/thermal-model.md — the model bullet says the same.
  • tests/test_wallmonitor.pytest_thermal_params_report_prior_deviation: unfitted → None; near the defaults → reported, not notable; far off → notable with the sign the UI keys on; round-trips through as_dict().

Risk

  • The note keys on 30% deviation, an arbitrary line. An install at 29% gets no note and one at 31% does; the numbers are in the API either way, and the note is informational — nothing else consumes notable.
  • The "≈ 22 min" figure in the note is 1.8 × DEFAULT_TAU_MIN, computed in the frontend from the served default, so it tracks a constant change in thermal.py — but MIN_SPAN_TAU itself is not served; if that multiple changes, the frontend's 1.8 must follow. One-line coupling, commented.
  • No behavioural change to forecasts, fits, or alerts. Purely an honesty surface.

Verification

  • python -m pytest -q (venv): 112 passed (111 on main + 1 new).
  • On the production install, prior_deviation reports τ 11.25 vs 12 (−6%) and rise 35.3 vs 36 (−2%): not notable, so this dashboard shows no note — correct, since the defaults are this install. A fresh install with τ = 20 would see "τ 20.0 min vs the 12 min default — forecasts before its first fitted session were rough"; one with τ = 6 additionally gets the short-charge caveat.

Deploy: restart the service; the note appears on the next dashboard load. No migration.

…riors

DEFAULT_TAU_MIN and DEFAULT_RISE_REF_C come from one install. They govern
the forecast until a fresh install has fits of its own, and nothing told
a user whose charger differs that those early forecasts were rough.

ThermalParams.prior_deviation() reports the fitted tau and rise against
the defaults (fractional, with a 30% "notable" heuristic) and rides along
in /api/thermal's model object. The dashboard's model note renders it
once fitted and notable, naming which parameter differs; for a fast tau
it also says that only charges of >= 1.8 x the default tau at steady
current teach the model, since the identifiability gate is floored there.
The unfitted note now says the defaults are from one verified install.

Co-Authored-By: Claude Fable 5 <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