fix(evidence): preserve legacy formula migration boundaries

This commit is contained in:
2026-08-25 01:28:54 +02:00
parent cc30148b69
commit dcb5acc312
4 changed files with 135 additions and 27 deletions
@@ -24,3 +24,21 @@ def test_reviewed_formula_migration_has_deterministic_provenance_hash():
assert second is not None
assert first.provenance.source_sha256 == second.provenance.source_sha256
assert first.provenance.source_sha256.startswith("sha256:")
def test_incompatible_reviewed_legacy_formula_fails_closed_with_the_original_record():
formula = ConceptFormula(
concept="ablazione",
columns=["testo"],
sql="SELECT 2",
status="reviewed",
sources=["legacy manual"],
)
outcome = formula_store.legacy_formula_to_curated(
formula, legacy_path="formulas/ablazione-2.sql.md",
)
assert outcome.code == "legacy_formula_requires_manual_review"
assert outcome.legacy_path == "formulas/ablazione-2.sql.md"
assert outcome.formula == formula
+56 -1
View File
@@ -104,7 +104,7 @@ def test_reviewed_legacy_formula_becomes_curated_formula_with_stable_provenance(
)
assert migrated is not None
assert migrated.id == "evidence:fascia-pediatrica"
assert migrated.id.startswith("evidence:fascia-pediatrica-")
assert migrated.title == "Fascia pediatrica"
assert migrated.kind == "formula"
assert migrated.payload.concept == formula.concept
@@ -118,6 +118,34 @@ def test_reviewed_legacy_formula_becomes_curated_formula_with_stable_provenance(
).id == migrated.id
def test_reviewed_legacy_formulas_with_the_same_concept_keep_distinct_path_identities():
first = ConceptFormula(
concept="fascia pediatrica",
columns=["clinical.patient.birth_date"],
sql="CASE WHEN age < 18 THEN 'pediatrica' ELSE 'adulta' END",
status="reviewed",
)
second = ConceptFormula(
concept="fascia pediatrica",
columns=["clinical.patient.birth_date"],
sql="CASE WHEN age < 16 THEN 'pediatrica' ELSE 'adulta' END",
status="reviewed",
)
first_migration = formula_store.legacy_formula_to_curated(
first, legacy_path="formulas/fascia-pediatrica-1.sql.md",
)
second_migration = formula_store.legacy_formula_to_curated(
second, legacy_path="formulas/fascia-pediatrica-2.sql.md",
)
assert first_migration is not None
assert second_migration is not None
assert first_migration.id != second_migration.id
assert first_migration.id.startswith("evidence:fascia-pediatrica-")
assert second_migration.id.startswith("evidence:fascia-pediatrica-")
def test_session_formula_proposal_is_versioned_and_is_not_published_evidence(tmp_path):
linking = SchemaLinking(
question="Conta i pazienti pediatrici",
@@ -148,3 +176,30 @@ def test_session_formula_proposal_is_versioned_and_is_not_published_evidence(tmp
"sources": ["Sintetizzata nella sessione"],
"decision_seq": 9,
}]
def test_session_formula_proposals_require_an_unretracted_positive_f4_decision(tmp_path):
linking = SchemaLinking(
question="Conta i pazienti pediatrici",
concept_formulas=[
{"concept": "approvata", "columns": [], "sql": "1", "sources": []},
{"concept": "rifiutata", "columns": [], "sql": "2", "sources": []},
{"concept": "indecisa", "columns": [], "sql": "3", "sources": []},
],
)
decisions = [
DecisionRecord(
seq=3, ts=datetime(2026, 8, 25, tzinfo=UTC), type="concept_formula_approved",
subject="phase:4", detail="approvata",
),
DecisionRecord(
seq=4, ts=datetime(2026, 8, 25, tzinfo=UTC), type="concept_formula_rejected",
subject="phase:4", detail="rifiutata",
),
]
projected = project_session(decisions, linking, tmp_path / "evidence")
assert [(proposal["concept"], proposal["decision_seq"]) for proposal in projected] == [
("approvata", 3),
]