"""Evidence-specific projection into persisted session artifacts.""" from pathlib import Path from typing import TYPE_CHECKING from tht.evidence.corpus.store import CorpusStore from tht.evidence.search import resolve_citation if TYPE_CHECKING: from tht.decisions import DecisionRecord from tht.session.models import SchemaLinking def _resolve_session_citation(evidence_root: Path, evidence_id: str) -> str: # New deployments resolve only immutable materialized files from ACTIVE. Keep the # curated-tree fallback for sessions created before a canonical corpus exists. corpus_root = evidence_root.parent.parent / "corpus" if corpus_root.exists(): return resolve_citation( CorpusStore(corpus_root), evidence_id, materialized_root=evidence_root.parent / ".materialized-evidence", ) for match in evidence_root.rglob(f"{evidence_id}.md"): return str(match) return "" def project_session( decisions: list["DecisionRecord"], linking: "SchemaLinking", evidence_root: Path, ) -> list[dict]: """Project cited and reviewed Evidence into the session artifact shape.""" entries: dict[str, dict] = {} for candidate in linking.candidates: for evidence_id in candidate.evidence: entries.setdefault( evidence_id, { "id": evidence_id, "file": _resolve_session_citation(evidence_root, evidence_id), "esito": "usata", "decision_seq": candidate.decision_seq, }, ) for decision in decisions: if decision.type not in ("evidence_accepted", "evidence_rejected"): continue entries[decision.subject] = { "id": decision.subject, "file": _resolve_session_citation(evidence_root, decision.subject), "esito": "accettata" if decision.type == "evidence_accepted" else "scartata", "decision_seq": decision.seq, } return list(entries.values()) __all__ = ["project_session"]