test(evidence): harden generation lifecycle boundaries

This commit is contained in:
2026-07-12 05:15:30 +02:00
parent 459ffa0bcd
commit 9e21cce036
7 changed files with 135 additions and 3 deletions
+1 -1
View File
@@ -405,7 +405,7 @@ class PgVectorStore:
return len(records)
def delete_generation(self, collection: str, generation: str) -> int:
if collection != "evidence" or not generation.startswith("gen:"):
if collection != "evidence" or re.fullmatch(r"gen:[0-9a-f]{32}", generation) is None:
raise VectorStoreError("Only exact Evidence generations may be deleted")
raw = None
try:
+3 -1
View File
@@ -1,5 +1,7 @@
"""Thoth vector HTTP adapter using distinct read and write clients."""
import re
from tht.ports.vector import (
VectorCapabilities,
VectorHealth,
@@ -154,7 +156,7 @@ class ThothHttpVectorStore:
raise VectorStoreError(str(exc)) from exc
def delete_generation(self, collection: str, generation: str) -> int:
if collection != "evidence" or not generation.startswith("gen:"):
if collection != "evidence" or re.fullmatch(r"gen:[0-9a-f]{32}", generation) is None:
raise VectorStoreError("Only exact Evidence generations may be deleted")
try:
return self._require_writer().delete_generation(collection, generation)
+10 -1
View File
@@ -6,6 +6,7 @@ Errori in italiano e azionabili, stile `rest/client.py`.
"""
import requests
import re
from tht.config import RestConfig
@@ -128,6 +129,8 @@ class VectorRestClient:
return len(rows)
def delete_generation(self, table_name: str, generation: str) -> int:
if table_name != "evidence" or re.fullmatch(r"gen:[0-9a-f]{32}", generation) is None:
raise ValueError("generation must be canonical")
try:
payload = self._call(
"delete_vector_generation",
@@ -155,4 +158,10 @@ class VectorRestClient:
"list_evidence_generations RPC is unavailable; deploy the cleanup migration"
) from None
raise
return sorted({row["generation"] for row in rows if isinstance(row, dict)})
if not isinstance(rows, list) or any(
not isinstance(row, dict)
or re.fullmatch(r"gen:[0-9a-f]{32}", str(row.get("generation", ""))) is None
for row in rows
):
raise VectorRestError("list_evidence_generations returned malformed data")
return sorted({row["generation"] for row in rows})