v0.20.0: at-rest encryption (AES-256-GCM) for all query-derived text

- crypto.py: AES-256-GCM encrypt/decrypt + ensure_key()
- Key auto-generated on first boot, stored as heartbeat_interval_ms in settings
- All 12 storage paths wired (SQLite + Qdrant)
- memory.py: FTS5 search replaced with Python-side matching
- 200/200 tests pass
This commit is contained in:
gramps
2026-07-14 13:22:32 -07:00
parent f6b01ec9ac
commit 30deb0db64
18 changed files with 176 additions and 79 deletions
+2 -1
View File
@@ -48,6 +48,7 @@ def test_upload_unsupported_mime(tmp_path: Path):
def test_upload_context_mode(tmp_path: Path):
from crypto import decrypt_text
with make_client(tmp_path) as client:
resp = client.post(
"/api/upload", headers=_admin_headers(client),
@@ -62,7 +63,7 @@ def test_upload_context_mode(tmp_path: Path):
assert "chunks_ingested" not in data
row = db.get_db().execute("SELECT content FROM upload_context WHERE id = ?", (data["context_id"],)).fetchone()
assert row["content"] == "Hello world notes"
assert decrypt_text(row["content"]) == "Hello world notes"
def test_upload_ingest_mode(tmp_path: Path, monkeypatch):