mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
The Coach button showed its unread dot over an empty conversation, and opening the Coach neither showed anything nor cleared the dot. Two paths fed one indicator. The nightly sweep flipped a "remind me" reminder from active to due and stopped there — no conversation, no message, and `surfaced` had no writer at all. The launcher lit its dot off a second query that asked only whether anything was due. So the dot promised content that was never written, and because opening the Coach clears the message-based signal and not the reminder one, the only way out was to resolve the reminder in Settings, which nothing on the badge suggested. A reminder minted for a plan review put a user who had never typed in the Coach in exactly that state. The sweep now writes the reminder into the user's Coach thread as a real assistant message and marks it surfaced in the same transaction: no message, no status change, and nothing to point at. The badge derives from that message like every other proactive one, so opening the Coach shows the note and clears the dot. The launcher's second query is gone. Reminders an older build left stuck on due are picked up by the same pass, so an indicator that has been sitting on an empty conversation resolves into the message it always implied. No provider call and no push: the body is a deterministic localized template around the user's own note text, six languages. Proven end to end against Postgres — the row exists, the badge reads that row, opening clears it, a second tick writes nothing, and a failed write leaves the reminder untouched with the badge dark. All five fail against the previous sweep. The second indicator in the report, under the bottom bar's overflow entry, is the active-route marker for that group and not a badge. Refs #715