Wire the snooze read into the Gatherer and honour it for reminders (#364)

The Gatherer now fills State.SnoozeUntil from store.SnoozedUntil instead
of nil, so a snooze finally reaches the gate. RemindDecisions gains the
one restraint check that applies to a reminder — quiet hours, presence
and cooldown are still bypassed, so "wake me 7" is unchanged. Reviewer:
the two tests in internal/loop/gate_test.go are the contract.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGeSZxh1DCtRxmFVSYVGvJ
This commit is contained in:
kami
2026-07-31 02:32:24 +04:00
parent 8acb8a97c6
commit ee3e6a9eaf
3 changed files with 44 additions and 9 deletions
-2
View File
@@ -273,7 +273,6 @@ func TestRemindersBypassEverySuppressor(t *testing.T) {
// passes every due reminder straight through with no snooze check, so a snoozed
// reminder fires anyway. The test below is what the contract asks for.
func TestRemindersStillHonourSnooze(t *testing.T) {
t.Skip("snooze is not applied to reminders — RemindDecisions ignores SnoozeUntil, internal/loop/loop.go:120")
now := refTime()
s := State{
@@ -292,7 +291,6 @@ func TestRemindersStillHonourSnooze(t *testing.T) {
// unit tests above pass while nothing can ever populate the map. This asserts
// the Gatherer actually produces a snooze map.
func TestGathererPopulatesSnoozeUntil(t *testing.T) {
t.Skip("Gatherer never populates SnoozeUntil, so snooze cannot suppress anything at runtime, internal/loop/gather.go:153")
ctx := context.Background()
st, err := store.Open(ctx, t.TempDir()+"/m.db")