Files
Maven/SESSION-05-07-2026.md
T
kami 354990fed0 nudge: add digest/batching mode for care nudges
When enabled, eligible nudges (sev ≤ ceiling) are queued in memory
instead of sent immediately. Every 'window' duration (or when
'max_items' reached), the queue is flushed as a single digest
notification with concatenated bodies.

Config:
  digest:
    enabled: true           # default false
    window: 30m             # flush window (default 30m)
    max_items: 5            # flush at this count (default 5)
    severity_ceiling: 2     # max sev batched (default 2; sev3+ bypass)

Changes:
- config.go: add DigestConfig struct with defaults
- tick.go: QueuedNudge type, digest queue/flush in TickLoop,
  shouldQueue/maybeFlush/flushDigest helpers
- main.go: pass cfg.Digest to newTickLoop
- tick_test.go: 6 new tests covering queue, flush, bypass, dedup
2026-07-05 13:07:28 +04:00

131 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Overnight Session — 2026-07-05
Branch: `overnight-jul5` (from `infra/spine-migrations-encryption-mavweb`)
Architect: `.opencode/agent/architect.md`
---
## Phase 0 — Setup
- [x] Branch `overnight-jul5` created from `infra/spine-migrations-encryption-mavweb`
- [x] `.opencode/agent/architect.md` — orchestrator agent
- [x] `SESSION-05-07-2026.md` — this file
---
## Phase 1 — Housekeeping
| # | Task | Commit | Status |
|---|------|--------|--------|
| 2 | **Makefile hygiene**`-race -coverprofile` in `make test`, add `build-caldav` target | b9248ef | done |
| 3 | **db_key.env hygiene** — remove live key from repo, add to `.gitignore`, keep `.env.example` | already-done | done |
| 4 | **Passkey persistence** — store credentials on disk (JSON file) instead of in-memory map | 44807b6 | done |
Notes:
- Live AES-256 key in `deploy/db_key.env` must be removed from git history. Rotate after.
---
## Phase 2 — Test Coverage Gaps
| # | Task | Commit | Status |
|---|------|--------|--------|
| 5 | **mavcaldav tests**`cmd/mavcaldav/` (314 lines, 0 coverage). CalDAV polling, iCal parsing, value-change filtering | 6daa96b | done |
| 6 | **mavttsd tests**`cmd/mavttsd/` (Piper handler). TTS worker protocol round-trip | a80b919 | done |
| 7 | **voicesink tests**`internal/delivery/voicesink/`. Voice channel dispatch, ErrNoSession mapping | ffef44f | done |
| 8 | **mavweb tests** — extend to cover `main.go` routes (server setup, template parsing, route registration, startup flags) | 185f4f5 | done |
Notes:
- mavweb `handlers_test.go` exists (14 cases). The gap is the non-handler code in `main.go` (549 lines) and `webauthn.go` (213 lines).
- voicesink has 0 tests but is critical — it's the bridge between delivery routing and voice sessions.
---
## Phase 3 — Easy Features (from feature ranking)
| # | Task | Commit | Status |
|---|------|--------|--------|
| 9 | **Command history** — read-only query over existing facts. New endpoint or /dash section | f8ba396 | done |
| 10 | **Revert / undo** — void the latest row for a fact key. Wrapper around existing append-only void mechanism | a02e10f | done |
| 11 | **Stale-reminder burst collapse** — digest overdue reminders on boot instead of firing all at once. Cosmetic: group into a single notification | ca081ce | done |
Notes:
- Command history: the data is already there (`RecentFacts`). This is exposing it better.
- Revert: `internal/store` already supports voiding (`VoidFact`). This is a thin API + confirm gate.
- Burst collapse: the `DueReminders` query in `internal/store/reminders.go` already returns all pending due reminders. The fix is in `internal/loop/gather.go` to collapse them.
---
## Phase 4 — Doable Features
| # | Task | Commit | Status |
|---|------|--------|--------|
| 12 | **Recurring reminders** — cron+next_fire_ts cols, RescheduleReminder, dispatcher logic | 1eca17f | done |
| 13 | **Capability model**`scope` column on tools table, migration, UI, tests | 6b80fd0 | done |
| 14 | **Notification batching / digest mode** — morning/evening rollup instead of per-event nudges. Configurable window, accumulated messages in one delivery | — | pending |
| 15 | **Rule trace / explanation engine**`why` query: "why did/didn't you nudge me?" Reads predicate eval log. New `/trace` page or CLI query | — | pending |
| 16 | **Backup/restore automation** — scripts/maven-backup.sh with backup/restore/verify/list | 3f09cdb | done |
Notes:
- Recurring reminders: needs schema migration (#1). Add `cron TEXT` and `next_fire_ts INTEGER` to reminders table.
- Capability model: ranking says "cheap now, expensive to retrofit once tools surface passes ~15 entries."
- Rule trace: the data is ephemeral — can log predicate results per tick to a ring buffer or a `rule_evals` table.
---
## Phase 5 — Web UI Re-imagination
| # | Task | Commit | Status |
|---|------|--------|--------|
| 17 | **In-process auth gate for /tools** — local PasskeySession check on POST, returns 403 if unasserted | 5afff00 | done |
| 18 | **Digest / notification history UI** — section on `/dash` showing batched notifications | — | pending |
| 19 | **Rule trace page** — new `/trace` route showing predicate eval results per rule per tick | — | pending |
| 20 | **Command history page** — new `/history` route showing recent facts/commands | f8ba396 | done |
| 21 | **PWA icons** — SVG icon + manifest.json icons array | 00a3bba | done |
| 22 | **Language unification** — bilingual cheatsheet with RU/EN toggle in nav + ?lang= param | c225ba3 | done |
Notes:
- In-process auth gate added for POST /tools (5afff00). Digest UI (#18) depends on #14; trace page (#19) depends on #15.
- PWA manifest currently has `"icons": []` — no icons, mobile add-to-home-screen shows a blank tile.
---
## Phase 6 — Final Pass
| # | Task | Commit | Status |
|---|------|--------|--------|
| 23 | Run `make test` with race detector — fix any races | ccb1d78 | done |
| 24 | `docker compose build` — verify all six daemons compile | ccb1d78 | done |
| 25 | Final review pass — check for debugging artifacts, commented code, TODO stubs | ccb1d78 | done |
---
## Cross-reference: feature ranking → this session
| Ranking item | Session task |
|---|---|
| Infra #2 (mavweb/mavcaldav tests) | #5, #8 |
| Easy: command history | #9 |
| Easy: revert/undo | #10 |
| Easy: capability model | #13 |
| Easy: stale-reminder collapse | #11 |
| Doable: recurring reminders | #12 |
| Doable: passkey persistence | #4 |
| Doable: backup/restore | #16 |
| Doable: testing infra | #2 |
| Doable: rule trace/explanation | #15 |
| Doable: notification batching/digest | #14 |
---
## Caveats & Gotchas
- **Destroy-confirm policy** is listed as "mandatory" in ranking but already shipped in tool executor (PROGRESS.md confirms). No action needed.
- **Quiet-hours definition** is listed as "mandatory" but already shipped (`3623305`). No action needed.
- **At-rest encryption** is listed as infra #1 in ranking but already done (`047a813`). No action needed.
- **Schema migrations** — `migrations.go` exists and is wired. Any new schema change (recurring reminders) uses it.
- **Docker** is already deployed and build-tested (commits `04c8dd1``7683a9b`). The "not build-tested" comment in Dockerfile is stale.
- **Systemd** is explicitly replaced by Docker per commit `04c8dd1`: "Chosen Docker over interim systemd units."
- Race detector may surface pre-existing races in the IPC or worker packages — fix them but don't scope-creep into a full refactor.
- Passkey persistence has a chicken-and-egg problem with cold-start unlock (needs passkey to unlock, passkey needs re-enroll after restart). Fix just the mavweb credential storage; the cold-start unlock flow is a separate feature.