mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Every interactive path, every import, MCP and Telegram checked an incoming measurement against VALUE_RANGES before storing it. The provider sync writers did not, so a decode slip or a glitched sensor landed a row the application itself calls impossible, and every mean, median and personal band derived from it inherited the impossibility. Filtering the read side hid the row. It kept landing. The gate is one module reading the domain the app already declares, applied at two kinds of seam. reconcileExternalMeasurement is the shared identity writer for Polar, Oura, WHOOP, the Withings sleep leg, the Apple export importer and the batch endpoint, so gating there means a provider added later inherits the refusal rather than having to remember a check it never knew about; the new rejected_range verdict carries no row, which is what makes the compiler force every caller to handle it. The five writers that hold Prisma themselves gate at their entry, before the existence probe decides insert versus overwrite, so an impossible reading can no longer replace a good stored value. An out-of-band value is dropped. Not clamped, because a clamp invents a reading nobody took. Not stored behind a flag, because a quarantined row is still a row and every consumer would have to learn the flag. Not fatal to the batch, because one bad sample must not strand the run's other readings behind a held watermark. Absence reads as absence. A silent drop, though, is indistinguishable from a provider that sent nothing, so every drop is tallied on the wide event under measurement.range_rejected with the metric, the provider and the edge it broke. Counts only: the reading itself is health data and never enters the log line, and the direction plus the metric's own declared bound is what a diagnosis actually needs. The tally accumulates rather than replacing, because a provider gates once per resource leg and the reconciler once per row. One warning per provider lifts the event to warn so a drop does not hide inside a green line. A structural guard enumerates all twenty measurement writers with the reason each is allowed to write, so a new one has to answer the question before it ships. scripts/diagnose-implausible-measurements.ts reports the rows already stored, aggregated per metric and source with no value beyond the bucket's own extremes. It repairs nothing: whether a stored impossible row is a decode slip or a band that is too narrow is not a call a script gets to make.