Files
Maven/internal/store/tools_test.go
T
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

46 lines
1.3 KiB
Go

package store
import (
"context"
"testing"
"time"
)
// TestToolLifecycle covers propose → enable → disable, the states the authed
// /tools page drives. Disable must revert an enabled tool to 'proposed' (kept
// in the store, won't run) and be idempotent.
func TestToolLifecycle(t *testing.T) {
s := newTestStore(t)
ctx := context.Background()
now := time.Now()
if _, err := s.ProposeTool(ctx, "restart_svc", "restart the service", now); err != nil {
t.Fatalf("propose: %v", err)
}
if err := s.EnableTool(ctx, "restart_svc", []string{"systemctl", "restart", "x"}, true, now); err != nil {
t.Fatalf("enable: %v", err)
}
if tl, _ := s.LookupTool(ctx, "restart_svc"); tl.Status != "enabled" {
t.Fatalf("after enable: status=%q want enabled", tl.Status)
}
if err := s.DisableTool(ctx, "restart_svc"); err != nil {
t.Fatalf("disable: %v", err)
}
tl, err := s.LookupTool(ctx, "restart_svc")
if err != nil {
t.Fatalf("lookup after disable: %v", err)
}
if tl.Status != "proposed" {
t.Fatalf("after disable: status=%q want proposed", tl.Status)
}
// idempotent: disabling an already-proposed (or absent) tool is a no-op.
if err := s.DisableTool(ctx, "restart_svc"); err != nil {
t.Fatalf("disable idempotent: %v", err)
}
if err := s.DisableTool(ctx, "does_not_exist"); err != nil {
t.Fatalf("disable absent must be no-op: %v", err)
}
}