session: update progress for overnight session
Completed tasks: - Phase 1: Makefile hygiene, db_key.env verification, passkey persistence - Phase 2: mavcaldav tests (14 cases), voicesink tests (7, race-clean), mavweb extended tests (credentials, signal, dash, history, revert) - Phase 3: command history page, revert/undo IPC+HTTP, stale-reminder burst collapse into digest - Phase 6: race-clean test run (pre-existing IPC timing quirk noted), docker compose build passes, final review clean Remaining: mavttsd tests (#6), Phase 4 features (#12-16), Phase 5 web UI (#17-22 except #20 completed)
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# 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 | — | pending |
|
||||
| 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 expression in reminder table. New `cron` column, `next_fire_ts` computed from cron. "trash every tuesday" | — | pending |
|
||||
| 13 | **Capability model** — `scope:name` instead of flat `tool→enabled`. Schema: add `scope` to tools table. Backward-compat: bare name = `homelab:name` | — | pending |
|
||||
| 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** — script: `cp` the encrypted DB + re-encrypt-verify + restore flow | — | pending |
|
||||
|
||||
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** — add WeAuthn session check to POST /tools handler. Currently relies solely on wg+nginx | — | pending |
|
||||
| 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** — add proper icon array to `manifest.json` (generate or inline SVG) | — | pending |
|
||||
| 22 | **Language unification** — pick Russian or add `lang` URL param toggle | — | pending |
|
||||
|
||||
Notes:
|
||||
- Current `/tools` has no in-process auth — `handlers_test.go` explicitly pins this behavior with `TestEnableTool_NoInProcessAuthGate`.
|
||||
- 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.
|
||||
Reference in New Issue
Block a user