Commit Graph
6 Commits
Author SHA1 Message Date
Marc-André Bombeck da937718bc refactor(measurements): move the series readers out of their route
GET /api/measurements/series keeps authentication, the query and its
refusal; readSeries (lib/measurements/series/read-series.ts) picks the
reader in the old order (sleep nights, paired blood pressure, the bucketed
read of a dense kind, the raw rows) and adds the direction, change,
reference lines and stat strip. The kinds, units and point shape live in
kinds.ts. The route falls from 752 to 95 lines.

The parity walk recorded before the move is unchanged. The guards on the
verdict resolver, the spread, the pulse day mean and the unit literals read
the new files, the last two with their scope widened to the series folder.
2026-10-23 14:13:52 +02:00
Marc-André Bombeck 760f261a5f test(guards): count fixed-path reads through readSourceText in the source-read ratchet
The ratchet on tests that read a source file by path matched readFileSync
and readFile only, so a guard that called readSourceText with a fixed path,
directly or through a local read(rel) wrapper, read the file without the
anchors readSource demands and was never counted. The classifier now counts
both shapes, and leaves alone a readSource call with anchors and a sweep that
feeds the reader from a walk.

The twelve guards that read a fixed file that way now go through readSource
with an anchor each read asserts on, so the baseline stays where it was.
2026-10-22 19:08:15 +02:00
Marc-André Bombeck 4dc3bd46bf test(guards): read the source tree once per worker through a shared index
walkSourceFiles now lists each indexed folder (src, e2e, prisma) once
per worker and filters it by prefix, readSource and readSourceFolder read
through the same memoised file cache, and readSourceText is the cached
read for guards that read files themselves. The guards project shares a
module graph per worker, so a file is read once however many guards ask
for it. sourcesContaining adds the substring pre-filter for sweeps that
look for a few markers. Every guard over 1.5 s now reads through it;
anything outside the indexed folders is read from disk as before.
2026-10-22 10:30:50 +02:00
Marc-André Bombeck cb8ed92d78 feat(stats): add segmented regression with Newey-West intervals
A four-parameter interrupted time series fit (pre-trend, level change,
slope change) by OLS, with a Bartlett-kernel HAC covariance, the n/(n-k)
small-sample factor and Student t intervals. The tests pin the
coefficients, standard errors and intervals to independently computed
reference values on contiguous and gapped series.
2026-10-21 21:44:29 +02:00
Marc-André Bombeck f4262e2cc6 test(guards): see a squared two-argument distance as a hand-rolled spread 2026-10-20 09:51:13 +02:00
Marc-André Bombeck ac86199808 fix(stats): one standard deviation with its kind named at the call site
About a dozen hand-rolled spreads each picked population or sample
variance without saying so, and the two surfaces a person compares
picked differently: the series API reported the population SD of a
blood-pressure series, the MCP tools and the AI payload the sample SD of
the same readings, about 22 % apart at three readings.

`lib/stats/spread` holds `variance` and `standardDeviation` with an
explicit `population | sample` kind and `READING_SPREAD`, the kind every
surface uses to report the spread of a person's readings. The series
route and the feature payload both report it; the spreads that feed a
verdict (the normal-swing checks, the changepoint threshold) and the
clinical glucose SD stay the sample estimate, now said out loud. A guard
fails on a new hand-rolled spread and on the two surfaces drifting apart.
2026-10-20 04:36:54 +02:00