Store layer: ListReminders returns the n most recent reminders
(newest first). IPC: new MethodListReminders wired through server,
client, and lockedAPI. Web: /reminders page with table of created
time, fire time, status badge, and payload text; empty state with
prompt to ask maven for a reminder. Sidebar entry under Automation.
- Add CalendarEvents method to recordingAPI in auth_test.go
- Add CalendarEvents method to fakeCore in handlers_test.go
Co-Authored-By: opencode <opencode@anthropic.com>
- digest queue no longer dropped on failed dispatch (retry next tick)
- collapsed reminders marked fired/rescheduled only after digest delivers
- /tools step-up gate skipped when WebAuthn is not configured (was 403 forever)
- passkey credential store rolls back memory on persist failure
- auth_test fake updated for TickTrace (branch build break)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ASstMtsZWLSRcD1Tq8T68Q
Add cron expression support for recurring reminders using robfig/cron/v3.
Changes:
- Migration #2: ALTER TABLE reminders ADD COLUMN cron TEXT + next_fire_ts INTEGER
- Reminder struct: add Cron and NextFireTs fields
- scanReminder helper extracts full row including nullable cron
- CreateReminder: accept optional cron param, store next_fire_ts = fire_ts
- DueReminders: query on next_fire_ts instead of fire_ts
- RescheduleReminder: new method — parse cron, compute next fire, update
next_fire_ts or mark fired if no more valid times
- Dispatcher: call RescheduleReminder for cron reminders, MarkReminder for
one-shots (preserving existing behavior for ID=0 digest skip)
- ReminderCompleter interface: add RescheduleReminder method
- storeAPI adapter: forward RescheduleReminder
- All callers updated: CreateReminder signature includes cron param
- Tests: TestRecurringReminder (store), TestDispatchRecurringReminderReschedules
- Existing tests updated for new signature
worker/server.go: dispatch now receives a per-connection context instead of
context.Background(), so handler cancellation propagates on conn close.
voice/server.go: same — per-conn context fed through safeDispatch into
HandlePushToTalk instead of context.Background().
store/reminders.go: propagate LastInsertId error.
store/nudges.go: propagate LastInsertId and RowsAffected errors.
store/tools.go: propagate RowsAffected error.
config/config.go: applyDefaults now respects StateDir when set, using it as
the base for empty DBPath/SocketPath instead of silently ignoring it.
phraser/llmphraser.go: close stderr pipe fd when cmd.Start() fails.