feat(fase2): first-class Pydantic provenance stamp

This commit is contained in:
Kjell Tore Guttormsen 2026-06-24 13:26:55 +02:00
commit a0f263bf41
2 changed files with 104 additions and 0 deletions

47
tests/test_provenance.py Normal file
View file

@ -0,0 +1,47 @@
"""Step 6 tests — first-class Pydantic provenance stamp.
At least one citation is mandatory (the load-bearing NFR); a valid stamp exposes the
proposal's provenance fields; the annotation adapter yields MAF citation dicts for display.
Pattern: tests/spikes/test_c_validator.py (pydantic raises + field assertions).
"""
import pytest
from pydantic import ValidationError
from portfolio_optimiser.provenance import Citation, ProvenanceStamp
from portfolio_optimiser.retrieval import TextSpan
def _stamp() -> ProvenanceStamp:
return ProvenanceStamp(
citations=[Citation(file="asphalt.txt", locator=TextSpan(0, 10), snippet="0123456789")],
model="qwen3:4b",
role="proposer",
validator_decision="validated",
token_usage=42,
)
def test_zero_citations_is_rejected() -> None:
with pytest.raises(ValidationError):
ProvenanceStamp(
citations=[],
model="m",
role="proposer",
validator_decision="validated",
token_usage=1,
)
def test_valid_stamp_exposes_provenance_fields() -> None:
stamp = _stamp()
assert len(stamp.citations) >= 1
assert stamp.model and stamp.role
assert stamp.validator_decision in {"validated", "rejected"}
assert isinstance(stamp.token_usage, int) and stamp.token_usage > 0
def test_to_annotations_yields_citation_dicts() -> None:
anns = _stamp().to_annotations()
assert anns and all(a["type"] == "citation" for a in anns)
assert anns[0]["annotated_regions"][0]["type"] == "text_span"