progress: refresh for overnight-jul5 (encryption, docker, digest, trace, web UI)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ASstMtsZWLSRcD1Tq8T68Q
This commit is contained in:
kami
2026-07-05 17:59:10 +04:00
parent 8d823000d1
commit a158ffd1d2
+57 -17
View File
@@ -1,11 +1,13 @@
## Maven — current state (2026-07-03)
## Maven — current state (2026-07-05)
Consolidated status. The reactive↔proactive core is closed and testable through
the web PWA. The SPEC's open items 17 are now landed (protocol doc, away-channel
the web PWA. The SPEC's open items 17 are landed (protocol doc, away-channel
fallthrough, CalDAV poller, quiet-hours schedule, tools enable/disable, note RAG,
passkey step-up); item 8 (multi-user) is deliberately deferred — see the tail.
Big untouched infra remaining: **at-rest security** (sqlcipher) and **systemd/
container deployment** (still scripts + tmux). ~13.1k LOC + ~5.3k test, 202 tests.
The two big infra gaps from the last revision are now closed on `overnight-jul5`:
**at-rest encryption** (AES-256-GCM, tmpfs working copy — not sqlcipher, see
`internal/store/crypt.go`) and **Docker deployment** (one image, six daemon
containers). ~14.6k LOC + ~8.1k test, 284 tests, `-race` in `make test`.
### Access model
@@ -91,24 +93,62 @@ Caveats / gotchas:
by flipping the sign; as a presence-*here* signal it's inverted. desk_active +
page_heartbeat cover home presence.
### Done since last revision (overnight-jul5, 2026-07-05)
The overnight session (`SESSION-05-07-2026.md`, 25 tasks) closed the previous
"not built yet" items 13 and added feature depth:
- **At-rest encryption** — the on-disk db is AES-256-GCM ciphertext; the daemon
works on a tmpfs (RAM) plaintext copy, sealed back atomically on close. Wrong
key / tamper ⇒ fail closed, never a plaintext fallback. Legacy plaintext dbs
upgrade on first clean shutdown. Key via config/env (`db_key_env`); no KDF —
raw 32-byte key, base64. The passkey cold-start unlock plugs into the same
`store.OpenEncrypted` seam later.
- **Docker deployment** — single image, one container per daemon
(`docker-compose.yml`); only mavend mounts the key + db volume; IPC over a
shared socket volume. `ipc.DialWait` (boot-order tolerance) + redial-on-drop
(core restarts don't kill modules). `deploy/README.md` has the runbook.
- **Tests** — mavcaldav, mavttsd, voicesink, mavweb main/handlers covered;
`make test` runs `-race -coverprofile`.
- **Recurring reminders** — `cron` + `next_fire_ts` on reminders; recurring ones
reschedule (instead of mark-fired) after successful delivery.
- **Notification digest/batching** — low-severity nudges queue and flush as one
digest per window/max-items (`digest` config block); stale-reminder bursts on
boot collapse into a single digest reminder, completed only after delivery.
- **Rule trace engine** — `ExplainTick`/`ExplainGate` record per-rule
predicate/gate/selection results each tick; served over IPC (`tick_trace`)
and rendered at mavweb `/trace` ("why didn't she nudge me").
- **Web UI** — new `/history` (facts + revert buttons), `/notifications` (nudge
history), `/trace` pages; nav links on `/dash`; RU/EN cheatsheet toggle in the
PWA; manifest icons (`icon.svg`). POST `/tools` now requires an in-process
passkey step-up when WebAuthn is configured.
- **Revert/undo** — `RevertFact` voids the latest fact for a key (append-only
void-marker, audit trail intact); exposed at `/api/revert` from `/history`.
- **Tool scopes** — `scope` column on tools, threaded through propose/enable/UI.
`DisableTool` raised to AuthStepUp alongside Enable.
- **Passkey persistence** — mavweb credentials in a JSON file (`-passkey-file`),
surviving restarts; rollback-on-persist-failure keeps memory and disk in sync.
- **STT silence gate** — min-duration + RMS floor drop non-speech before whisper
hallucinates on it (`-min-ms`, `-silence-rms` flags on mavsttd).
- **Housekeeping** — `db_key.env` gitignored (+`.env.example`), `build-caldav`
target, zero-timestamp "never" fix on /dash.
### Not built yet (ranked by ROI)
1. **At-rest encryption** — sqlcipher + cold-start unlock. Today the store is
plain sqlite: disk access = full read. Passkey step-up now gates *actions*,
but not the data at rest.
2. **`cmd/mavweb` / `cmd/mavcaldav` tests** — both are untested (0 test files).
mavweb now carries the passkey + tools HTTP flow (the webauthn *crypto* is
tested; the handlers and browser JS are not). Highest-value test gap.
3. **Deployment** — still `start-maven.sh` + tmux. systemd user units (one per
binary, socket-activated, `After=mavend.socket`, `Restart=on-failure`) are
specced, not written. Docker/Podman is a later phase.
1. **Purge + rotate the leaked db key** — a live AES key was committed at
`deploy/db_key.env` before it was gitignored. It must be scrubbed from git
history and rotated. Operator action, highest urgency.
2. **Step-up gate on `/api/revert`**it mutates the store (voids facts) but
has no passkey gate, unlike POST `/tools`. Inconsistent with the auth model.
3. **Cold-start unlock** — the at-rest key still comes from env/config; the
passkey→key L3 dance is a documented seam, not a feature. Until then the key
sits in the container env.
4. **Multi-user (SPEC item 8)** — deliberately deferred, see the tail.
Housekeeping: `go.mod` isn't tidied — `onnxruntime_go` and `coder/websocket`
are used but marked `// indirect`. Passkey credentials are mavweb in-memory
(re-enroll after a mavweb restart — acceptable for single-user, by design).
Housekeeping: `go.mod` isn't tidied — `onnxruntime_go`, `coder/websocket`, and
`robfig/cron` are used directly but marked `// indirect`.
Done since last revision: **act tool executor, store-backed, full flow**
Done earlier (2026-07-03): **act tool executor, store-backed, full flow**
(`internal/tool` + `internal/store/tools.go` + `tools` CoreAPI methods).
- **Execution:** IntentAct runs the matched fn against the store's ENABLED
allowlist. argv, no shell → STT text can't inject. Live store read, so a