Commit Graph

8 Commits

Author SHA1 Message Date
kami a02e10fd11 ipc+mavweb: add revert/undo endpoint to void latest fact for a key
- New store.VoidLatestFact() method finds latest non-voided fact for
  a key and writes a void-marker row pointing at it (transactional).
- New IPC method MethodRevertFact with CoreAPI.RevertFact interface,
  storeAPI adapter, server dispatch, and client proxy.
- New HTTP endpoint POST /api/revert?key=<key> in mavweb.
- History page adds a 'revert' button per non-voided fact row with
  JS confirmation and optimistic UI (marks row voided on success).
- All existing store, IPC, and mavweb tests pass.
2026-07-05 02:18:39 +04:00
kami f8ba396fec mavweb: add /history page for command history
- New /history route displays recent facts in a dedicated page with
  voided-row styling (line-through + opacity + badge).
- Navigation link added to /dash page header.
- Handler calls core.RecentFacts(ctx, 200) and renders historyTmpl.
2026-07-05 02:13:13 +04:00
kami 44807b612c webauthn: persist credentials to JSON file instead of in-memory map
- New credentialStore type in credentials.go loads/saves
  map[id]localCred to a JSON file. Thread-safe with sync.RWMutex,
  writes to disk on every mutation.
- PasskeyHandle replaces sync.RWMutex+map with *credentialStore.
  Inline save/lookip/update closures delegate to store methods.
- newPasskeyHandle now takes a storePath parameter and returns an
  error; callers updated.
- New -passkey-file flag (default ./passkeys.json) configures the
  credential store path in main.go.
- Tests use os.CreateTemp in t.TempDir() so each test gets an
  isolated, auto-cleaned store file.
2026-07-05 02:09:56 +04:00
kami 7683a9b32c ipc: promote startup socket-wait to a shared DialWait; use in all modules
The cold-start crash-loop wasn't mavweb-specific — mavpoll and mavcaldav also
ipc.Dial + exit on failure, so they crash-looped until core booted too. Moved
the retry into ipc.DialWait (capped backoff, bounded) and switched mavweb,
mavpoll, mavcaldav to it. mavweb's local dialCoreWithRetry is gone.

Test: server appears after DialWait starts → it waits and connects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 00:17:10 +04:00
kami a38e733514 fix: local timezone for replies + quiet-hours; guard presence "ago" overflow
Timezone: the container ran in UTC, so mavend answered clock/date queries
(voice.go replySystem) and evaluated quiet-hours (gather.go) in UTC. Fixed at
the root — process TZ — rather than per-call: TZ=Europe/Samara in compose +
tzdata in the image (debian-slim strips it, without which Go ignores TZ and
stays UTC). One knob fixes replies and quiet-hours for every daemon; change the
zone in compose.

Overflow: the dash "ago" helper ran time.Since on a zero timestamp (no presence
yet / fresh db), saturating to ~292y and rendering "2562047h47m…". Guard zero →
"never".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 00:13:13 +04:00
kami 1a3ef572d1 mavweb: wait for core socket at startup instead of crash-looping
mavweb log.Fatal'd if mavend's socket wasn't up yet, so under compose it
crash-looped (relying on restart:unless-stopped) until core finished booting
its models. depends_on only orders container start, not socket readiness.
dialCoreWithRetry polls with capped backoff up to 60s; still fatal past the
deadline. Mid-life core restarts remain covered by ipc.Client's redial-on-drop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 00:08:56 +04:00
kami 6239eca243 items 5-7: passkey step-up, tools enable/disable, note RAG — end to end
Completes the three in-flight open items and fixes the away-fallthrough bug.

Item 7 — passkey step-up (WebAuthn):
- internal/webauthn: ES256/P-256 register + assert with real ecdsa signature
  verification, minimal CBOR/COSE decode, PasskeySession (L2→L3 on assert,
  decays after TTL). Drop the RS256 offer we can't verify (register-ok/
  assert-fail trap). Verify rpIdHash + UP/UV flags in FinishAssertion — UV is
  the step-up gesture. Round-trip test with negative cases (tampered sig,
  missing UV, wrong origin).
- cmd/mavweb: /auth/passkey enroll+assert page (the only surface that can do
  a WebAuthn gesture) + the four begin/finish endpoints. Without this the
  daemon's PasskeySession swap leaves /tools enable permanently blocked.
- daemon wires PasskeySession as the auth Session + srv.StepUp; policy gates
  MethodAssertStepUp at AuthRead.

Item 5 — tools page: DisableTool through store/ipc/client/wire; /tools grows a
disable action and a link to the passkey page. Lifecycle test.

Item 6 — note RAG: PhraseQuery on the phraser (LLM-composed answer over top-k
notes, raw-notes fallback); IntentQuery routes through it. Stub returns a
deterministic summary.

Item 2 — away-fallthrough: on ErrVoiceNoSession the dispatcher now reroutes
through the AWAY table (sev3→ntfy, sev4→telegram-repeat-til-ack, sev≤2→drop)
instead of silently dropping / mis-routing to the present-list remainder.
Covers DispatchNudge + DispatchReminder. 4 tests.

Also: re-add ProposeTool to CoreAPI (dropped in a comment rewrite), fix
missing imports + a duplicate block left mid-edit, drop dead AssertStepUpFunc,
gitignore /mavcaldav.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:13 +04:00
kami e00cb07658 fix zombie leak, add quiet-hours toggle, improve query reply, configurable router threshold, JS dashboard 2026-07-03 00:42:35 +02:00