feat: implement memory and evidence administration with guided repairs
Publish documentation / publish (push) Successful in 1m27s
Publish documentation / publish (push) Successful in 1m27s
Add PostgreSQL-backed memory, editable evidence with source review and activation, and human-approved archive repairs across the harness, API, and UI. Include migrations, deployment support, regression coverage, and validation documentation. Refresh permissions from validated session roles so existing administrator logins can access newly deployed archive management features.
This commit is contained in:
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
@@ -10,7 +9,6 @@ import pytest
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from tht.cli import app
|
||||
from tht.memory import MemoryRecord, save_registry
|
||||
from tht.ports.vector import VectorStoreError
|
||||
|
||||
|
||||
@@ -102,22 +100,6 @@ def _write_catalog_snapshot(tmp_path: Path) -> None:
|
||||
}))
|
||||
|
||||
|
||||
def _memory_record() -> MemoryRecord:
|
||||
return MemoryRecord(
|
||||
id="mem-0001",
|
||||
ts=datetime(2026, 1, 1, tzinfo=UTC),
|
||||
session_id="s1",
|
||||
decision_seq=7,
|
||||
type="concept_clarified",
|
||||
subject="paziente attivo",
|
||||
detail="flag_attivo = TRUE",
|
||||
rationale="r",
|
||||
question_context="dammi i pazienti attivi",
|
||||
tables=[],
|
||||
concepts=["paziente attivo"],
|
||||
)
|
||||
|
||||
|
||||
def test_vector_index_schema_accepts_qdrant_only_runtime_config(tmp_path, monkeypatch):
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
_write_catalog_snapshot(tmp_path)
|
||||
@@ -196,42 +178,29 @@ def test_vector_index_schema_json_failure_is_pristine(tmp_path, monkeypatch):
|
||||
}
|
||||
|
||||
|
||||
def test_memory_promote_accepts_qdrant_only_runtime_config(tmp_path, monkeypatch):
|
||||
def test_memory_promote_adapts_qdrant_runtime_to_authoritative_service(tmp_path, monkeypatch):
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
store = _FakeVectorStore()
|
||||
promoted = [_memory_record()]
|
||||
snapshot = SimpleNamespace(manifest=SimpleNamespace(id="s1"))
|
||||
|
||||
snapshot = object()
|
||||
calls = []
|
||||
service = SimpleNamespace(close=lambda: None, promote=lambda source, seqs:
|
||||
calls.append((source, seqs)) or [{"indexed": True, "card": {"id": "mem-test"}}])
|
||||
monkeypatch.setattr("tht.cli.memory_cmd.load_snapshot_or_exit", lambda cfg, session: snapshot)
|
||||
monkeypatch.setattr("tht.memory.promote_snapshot", lambda *args, **kwargs: promoted)
|
||||
monkeypatch.setattr("tht.memory.load_registry", lambda path: promoted)
|
||||
monkeypatch.setattr("tht.adapters.factory.build_vector_store", lambda cfg, require_write: store)
|
||||
monkeypatch.setattr("tht.cli.vector_cmd.make_embedder", lambda _: _FakeEmbedder())
|
||||
|
||||
res = CliRunner().invoke(
|
||||
app,
|
||||
["memory", "promote", "--session", "s1", "--decision", "7", "--json", "-c", str(cfg)],
|
||||
)
|
||||
|
||||
assert res.exit_code == 0, res.output
|
||||
assert json.loads(res.stdout)["indexed"] is True
|
||||
assert store.upserts
|
||||
monkeypatch.setattr("tht.cli.memory_cmd.memory_service", lambda cfg: service)
|
||||
result = CliRunner().invoke(app, [
|
||||
"memory", "promote", "--session", "s1", "--decision", "7", "--json", "-c", str(cfg),
|
||||
])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert json.loads(result.stdout)["indexed"] is True
|
||||
assert calls == [(snapshot, [7])]
|
||||
|
||||
|
||||
def test_memory_index_accepts_qdrant_only_runtime_config(tmp_path, monkeypatch):
|
||||
def test_memory_index_rebuilds_only_through_authoritative_service(tmp_path, monkeypatch):
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
store = _FakeVectorStore()
|
||||
records = [_memory_record()]
|
||||
|
||||
save_registry(records, tmp_path / "artifacts" / "memory" / "registry.jsonl")
|
||||
monkeypatch.setattr("tht.adapters.factory.build_vector_store", lambda cfg, require_write: store)
|
||||
monkeypatch.setattr("tht.cli.vector_cmd.make_embedder", lambda _: _FakeEmbedder())
|
||||
|
||||
res = CliRunner().invoke(app, ["memory", "index", "-c", str(cfg)])
|
||||
|
||||
assert res.exit_code == 0, res.output
|
||||
assert "OK:" in res.output
|
||||
assert store.upserts
|
||||
service = SimpleNamespace(close=lambda: None, rebuild=lambda: [{"indexed": True}])
|
||||
monkeypatch.setattr("tht.cli.memory_cmd.memory_service", lambda cfg: service)
|
||||
result = CliRunner().invoke(app, ["memory", "index", "--json", "-c", str(cfg)])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert json.loads(result.stdout) == [{"indexed": True}]
|
||||
|
||||
|
||||
def test_vector_help_exposes_only_the_supported_qdrant_command():
|
||||
|
||||
Reference in New Issue
Block a user