Commit graph

12 commits

Author SHA1 Message Date
Viktor Barzin
1c0193f011 fix(recall): cap default limit to 30 + relevance-bound OR-broadening
Some checks failed
ci/woodpecker/push/deploy Pipeline failed
ci/woodpecker/push/build Pipeline failed
memory_recall was returning almost the entire store instead of a small
set of relevant matches. Two compounding causes, both fixed here:

1. Default limit was 10000 (commit d03a77a "effectively unlimited").
   recall_memories/MemoryRecall and the memory_recall MCP tool now
   default to 30 (ceiling stays 10000 for callers that opt in).

2. The OR-broadening fallback (fires when the precise AND-match is
   sparse) ordered by the importance hybrid and padded up to `limit`,
   so with limit=10000 it flooded results with high-importance but
   irrelevant memories. It now orders OR-matches by ts_rank(relevance)
   DESC and applies a minimum-rank floor (OR_BROADEN_MIN_RANK=0.01) to
   drop rows that merely contain a query word incidentally.

Tests: add test_recall_default_limit_is_capped (asserts 30 passed to
fetch) and test_recall_or_broadening_is_relevance_bounded (asserts the
OR query is relevance-ordered + rank-floored). Full suite 176 green,
ruff + mypy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 18:48:11 +00:00
Viktor Barzin
43a5513f6c feat: make all memories public by default
All memories are now visible to all users in recall/list/count queries.
Each memory still has an owner (user_id) who retains exclusive delete
rights. This removes the need for explicit sharing — wizard and emo
automatically see each other's memories.

Changes:
- recall/list: single query without user_id filter, added owner field
- count: counts all memories globally
- REST categories/tags: show all users' data
- Delete/update: unchanged (owner-only or write-share)
- Sync: unchanged (stays user-scoped)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:27:58 +00:00
Viktor Barzin
c130bcff33
feat: sharing tests, property tests, tag-share UI, inline errors, route fix
- Add 10 sharing endpoint tests (share/unshare memory, tag shares, shared-with-me,
  my-shares, recall with shared, update permission checks)
- Add hypothesis property-based tests for model validation (roundtrip, bounds,
  enum, sort_by, limit)
- Tighten model validation: sort_by Literal, limit ge=1/le=500, tags/keywords max_length
- Fix dashboard shared_with_me stat to include tag-based shares
- Add tag-sharing management UI (share/remove tags, user typeahead)
- Replace alert() with inline error messages
- Fix route ordering bug: share-tag routes before {memory_id} parameterized routes
2026-03-22 23:36:13 +02:00
Viktor Barzin
e6dd89346f
fix: update tests for recall query changes and mypy asyncpg import
- Add shared_by/share_permission to mock row defaults
- Update recall tests to handle 3+1 fetch calls (own, shared, tag-shared, OR-fallback)
2026-03-22 15:45:38 +02:00
Viktor Barzin
e47efee6b6
resilient memory sync: decouple push/pull, startup full resync, auth failure handling
- Decouple push and pull in _sync_once() so pull always runs even if push fails
- Add startup full resync to catch drift from other agents and schema changes
- Add periodic full resync every ~10 minutes for continuous drift correction
- Add auth failure detection (401/403) with graceful SQLite-only degradation
- Add /api/auth-check endpoint for lightweight key validation
- Add retry cap (5 attempts) on pending ops to prevent infinite queue buildup
- Add orphan reconciliation: push local-only records with content dedup
- Add memory_count MCP tool for sync diagnostics
- Add version-based SQLite schema migration (PRAGMA user_version)
- Fix API key in ~/.claude.json to match server
- Update README with sync resilience docs, test structure, project layout
- Add 30 new tests covering all new behaviors (155 total, all passing)
2026-03-16 18:37:59 +00:00
Viktor Barzin
dbbacd75c2
fix delete tests to match idempotent endpoint behavior
The delete endpoint intentionally returns 200 (not 404) when a memory
is already deleted, to prevent retry loops in old clients. Tests were
asserting 404 incorrectly.
2026-03-15 22:41:10 +00:00
Viktor Barzin
e08486f2bd
fix: parse since param to datetime for asyncpg compatibility
asyncpg requires datetime objects, not strings, for timestamptz params.
Also use Z suffix in tests to avoid URL-encoding issues with +00:00.
2026-03-14 13:13:48 +00:00
Viktor Barzin
0a4aed9e1b
fix: resolve ruff lint errors (unused imports and variables) 2026-03-14 13:04:40 +00:00
Viktor Barzin
cd80a67dfa
feat: add local SQLite cache with background sync and HA deployment
- Add SyncEngine for background sync between local SQLite cache and
  remote API with pending_ops queue for offline resilience
- Refactor MCP server to support three modes: SQLite-only, hybrid
  (local cache + sync, new default), and HTTP-only (legacy)
- Add GET /api/memories/sync endpoint for incremental sync
- Change DELETE to soft delete (set deleted_at) for sync support
- Add deleted_at IS NULL filters to all read queries
- Scale API deployment to 2 replicas with pod anti-affinity, PDB,
  and startup probe for high availability
- Add migration 003 for deleted_at column and updated_at index
- Add comprehensive tests for sync engine and API sync endpoint
2026-03-14 12:42:39 +00:00
Viktor Barzin
58ea218044
fix: add preview to delete response for MCP server compatibility 2026-03-14 11:14:05 +00:00
Viktor Barzin
4c75e9d801
fix: wrap recall/list responses in {memories: []} and update README
- API recall and list endpoints now return {"memories": [...]} matching
  the format expected by the MCP server
- Rewrote README with comprehensive setup instructions for new agents,
  accurate API reference, migration docs, and multi-user setup guide
2026-03-14 10:39:12 +00:00
Viktor Barzin
0ed5e1e016
feat: standalone claude-memory-mcp with multi-user support and Vault integration
Extracted from private infra repo into standalone open-source project.

Three operating modes:
- Local: SQLite + FTS5 (zero dependencies)
- Server: PostgreSQL via HTTP API with multi-user auth
- Full: PostgreSQL + HashiCorp Vault for secret management

Features:
- MCP stdio server with 5 tools (store/recall/list/delete/secret_get)
- FastAPI HTTP API with multi-user Bearer token auth (API_KEYS JSON map)
- Regex-based credential detection with auto-redaction
- AES-256-GCM encryption fallback for non-Vault deployments
- Vault KV v2 client (stdlib urllib, K8s SA auto-auth)
- Per-user data isolation (all queries scoped by user_id)
- Secret migration endpoint for existing plain-text credentials
- Backward-compatible env var aliases (CLAUDE_MEMORY_API_URL)

Infrastructure:
- Docker + docker-compose (API + PostgreSQL + optional Vault)
- Woodpecker CI (test → build → push → kubectl deploy)
- GitHub Actions CI (Python 3.11/3.12/3.13) + Release (GHCR + PyPI)
- Helm chart + raw Kubernetes manifests

96 tests passing across 6 test files.
2026-03-14 09:42:05 +00:00