Privacy-Period-Tracker/core
null 861738c4e9 fix: make the learning loop keep the samples it earns
Tracing the confirm -> score -> feed-back loop end to end turned up four
ways it lost or falsified its own evidence. None of them looked broken:
each produced plausible accuracy figures with something missing.

A forecast's generatedAt is now the date its LINEAGE began, not the date
its row was written. Every "Not yet", edit and delete revises the answer
to one standing question, so the replacement inherits the origin instead
of restamping today. Restamping moved the goalposts of the backfill
guard: a "Not yet" on the 29th, then a period logged on the 30th as
having started on the 28th, tripped the guard and the forecast the user
was actually shown was deleted unscored. The app learned nothing from
precisely the cycle it got wrong.

The standing snapshot is retired before the engine is consulted rather
than after, so a lineage dies with its history instead of waiting to be
scored against an unrelated one.

Scores now follow the period they are facts about. Editing a start
re-scores every snapshot recorded against it -- predictedStartDate stays
immutable, so a correction worsens the figure as readily as it improves
one -- and the same rule that refuses to score backfill retracts a score
whose start has moved behind its lineage, so an edit cannot smuggle in a
measurement the guard would have turned away. Deleting the period
retracts outright.

A confirm that becomes the newest start clears every "not yet", not just
the older ones: they all censor the same question. A date-bounded clear
left observations dated after a retroactively logged start alive to
depress the next cycle's confidence for a question already answered.

Also removes CycleData.repository's engine default. Nobody relied on it,
which is the point -- a caller who omitted the argument would compile
cleanly and ship the baseline prototype §11 calls unacceptable.

No schema change: all four fixes are queries and call order.

Six of the seven new tests were observed red against the unfixed source.
The seventh -- a deep backfill does not clear the observations censoring
the standing question -- passes both sides deliberately, pinning against
overshooting the not-yet fix.

closes #46
closes #47
closes #48
closes #49

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 16:13:53 -05:00
..
data fix: make the learning loop keep the samples it earns 2026-08-20 16:13:53 -05:00
database fix: make the learning loop keep the samples it earns 2026-08-20 16:13:53 -05:00
datastore ui: add discreet launcher alias 2026-08-20 02:37:29 -05:00
designsystem ui: fix dark welcome artwork 2026-08-20 01:59:30 -05:00
export feat: export my data, as one plaintext file the user places 2026-08-19 22:13:07 -05:00
notifications feat: the status bar shows this app's mark, not a framework glyph 2026-08-19 21:51:54 -05:00
security feat: app lock, with no way to reset a forgotten PIN 2026-08-19 04:02:47 -05:00