-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_evaluator.py
More file actions
144 lines (124 loc) · 5.26 KB
/
Copy pathtest_evaluator.py
File metadata and controls
144 lines (124 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""Determinism and safety invariants for evaluation and receipts."""
from typing import Any
from contextsafe.evaluator import evaluate
from contextsafe.models import OutcomeStatus
from contextsafe.receipt import build_receipt, render_receipt
from contextsafe.validation import parse_bundle
def _bundle(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> Any:
return parse_bundle(case_json, observations_json, rules_json)
def test_reference_fixture_passes_only_on_affirmative_evidence(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
outcomes = evaluate(_bundle(case_json, observations_json, rules_json))
assert len(outcomes) == 5
assert all(item.status is OutcomeStatus.PASSED for item in outcomes)
assert all(item.reason == "affirmative_evidence_match" for item in outcomes)
def test_missing_evidence_is_indeterminate_never_pass(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
observations_json["observations"] = observations_json["observations"][:-1]
outcomes = evaluate(_bundle(case_json, observations_json, rules_json))
missing = next(item for item in outcomes if item.rule_id == "A-I05")
assert missing.status is OutcomeStatus.INDETERMINATE
assert missing.reason == "missing_evidence"
assert missing.observed_sha256s == ()
def test_mismatched_evidence_fails(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
observations_json["observations"][4]["value"]["value"] = "ze/hir"
outcome = evaluate(_bundle(case_json, observations_json, rules_json))[-1]
assert outcome.status is OutcomeStatus.FAIL
assert outcome.reason == "semantic_mismatch"
def test_multiple_matching_observations_are_indeterminate(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
duplicate = observations_json["observations"][4].copy()
duplicate["observation_id"] = "OBS-I01-PRONOUNS-2"
observations_json["observations"].append(duplicate)
outcome = evaluate(_bundle(case_json, observations_json, rules_json))[-1]
assert outcome.status is OutcomeStatus.INDETERMINATE
assert outcome.reason == "ambiguous_evidence"
def test_predeclared_nonrequired_rule_is_not_applicable(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
rules_json["rules"][0]["required"] = False
outcome = evaluate(_bundle(case_json, observations_json, rules_json))[0]
assert outcome.status is OutcomeStatus.NOT_APPLICABLE
assert outcome.reason == "predeclared_not_applicable"
def test_deterministic_replay_is_byte_identical_and_order_independent(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
first_bundle = _bundle(case_json, observations_json, rules_json)
first = render_receipt(build_receipt(first_bundle, evaluate(first_bundle)))
observations_json["observations"].reverse()
rules_json["rules"].reverse()
second_bundle = _bundle(case_json, observations_json, rules_json)
second = render_receipt(build_receipt(second_bundle, evaluate(second_bundle)))
assert first == second
assert first.endswith("\n")
def test_receipt_contains_hashes_but_no_semantic_or_source_values(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
bundle = _bundle(case_json, observations_json, rules_json)
receipt = build_receipt(bundle, evaluate(bundle))
rendered = render_receipt(receipt)
assert set(receipt["hashes"]) == {
"input_sha256",
"rule_set_sha256",
"result_sha256",
}
for prohibited in (
"CSYN-ASTER",
"fixture-gender-1",
"fixture-context-1",
"they/them",
"government-id",
"source_pointer",
):
assert prohibited not in rendered
assert receipt["summary"]["pass"] == 5
assert receipt["scope"]["clinical_oracle_approved"] is False
assert any("cannot prove" in item for item in receipt["limitations"])
def test_hashes_change_with_inputs_rules_and_results(
case_json: dict[str, Any],
observations_json: dict[str, Any],
rules_json: dict[str, Any],
) -> None:
baseline = _bundle(case_json, observations_json, rules_json)
baseline_receipt = build_receipt(baseline, evaluate(baseline))
observations_json["observations"][4]["value"]["value"] = "ze/hir"
changed_input = _bundle(case_json, observations_json, rules_json)
changed_receipt = build_receipt(changed_input, evaluate(changed_input))
assert (
baseline_receipt["hashes"]["input_sha256"]
!= changed_receipt["hashes"]["input_sha256"]
)
assert (
baseline_receipt["hashes"]["result_sha256"]
!= changed_receipt["hashes"]["result_sha256"]
)
rules_json["rules"][0]["version"] = "0.1.1"
changed_rules = _bundle(case_json, observations_json, rules_json)
final_receipt = build_receipt(changed_rules, evaluate(changed_rules))
assert (
changed_receipt["hashes"]["rule_set_sha256"]
!= final_receipt["hashes"]["rule_set_sha256"]
)