Skip to content

Commit 5f176d0

Browse files
authored
Refactor donor evidence intake tests and functions
1 parent 545d196 commit 5f176d0

1 file changed

Lines changed: 192 additions & 118 deletions

File tree

Lines changed: 192 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
15
from ix_cognition_kernel.wave6_contracts import (
26
WaveSixArtifactKind,
7+
WaveSixCapabilityArea,
38
WaveSixDecisionState,
49
WaveSixLoopStage,
510
WaveSixSourceSystem,
611
)
712
from ix_cognition_kernel.wave6_donor_evidence_intake import (
8-
WAVE_SIX_DONOR_EVIDENCE_INTAKE_ENGINE_ID,
13+
WAVE_SIX_SUPPORTING_DONOR_SOURCE_SYSTEMS,
914
WaveSixDonorEvidenceIntakeStatus,
1015
WaveSixDonorEvidenceReceipt,
1116
build_wave_six_donor_evidence_intake_bundle,
@@ -15,188 +20,257 @@
1520
canonical_wave_six_donor_profile_for_source,
1621
)
1722

18-
import pytest
19-
2023

2124
def _fingerprint(seed: int) -> str:
2225
return f"{seed:064x}"[-64:]
2326

2427

25-
def _receipt_for(
28+
def _receipt_for_source(
2629
source_system: WaveSixSourceSystem,
27-
artifact_kind: WaveSixArtifactKind | None = None,
2830
*,
2931
seed: int = 1,
30-
**overrides: object,
3132
) -> WaveSixDonorEvidenceReceipt:
3233
profile = canonical_wave_six_donor_profile_for_source(source_system)
3334
assert profile is not None
34-
selected_artifact = artifact_kind or profile.supplied_artifact_kinds[0]
35-
payload = {
36-
"receipt_id": f"receipt-{source_system.value}-{selected_artifact.value}",
37-
"source_system": source_system,
38-
"repo_name": profile.repo_name,
39-
"evidence_id": (
40-
f"donor-evidence:{source_system.value}:{selected_artifact.value}"
41-
),
42-
"artifact_kind": selected_artifact,
43-
"capability_area": profile.supplied_capability_areas[0],
44-
"loop_stages": (profile.supported_loop_stages[0],),
45-
"artifact_fingerprint": _fingerprint(seed),
46-
"summary": f"Metadata-only evidence receipt for {profile.repo_name}.",
47-
"produced_by_engine_id": f"{source_system.value}-evidence-exporter",
48-
}
49-
payload.update(overrides)
50-
return WaveSixDonorEvidenceReceipt(**payload)
51-
52-
53-
def _full_receipts() -> tuple[WaveSixDonorEvidenceReceipt, ...]:
35+
return WaveSixDonorEvidenceReceipt(
36+
receipt_id=f"receipt:{source_system.value}",
37+
source_system=source_system,
38+
repo_name=profile.repo_name,
39+
evidence_id=f"donor-evidence:{source_system.value}:primary",
40+
artifact_kind=profile.supplied_artifact_kinds[0],
41+
capability_area=profile.supplied_capability_areas[0],
42+
loop_stages=(profile.supported_loop_stages[0],),
43+
artifact_fingerprint=_fingerprint(seed),
44+
summary=f"{profile.repo_name} supplies bounded donor evidence.",
45+
produced_by_engine_id=f"{source_system.value}-evidence-engine",
46+
validation_notes=("metadata-only donor receipt",),
47+
)
48+
49+
50+
def _all_required_receipts() -> tuple[WaveSixDonorEvidenceReceipt, ...]:
5451
receipts: list[WaveSixDonorEvidenceReceipt] = []
55-
seed = 1
56-
for source_system in supporting_wave_six_donor_source_systems():
52+
seed = 10
53+
for source_system in WAVE_SIX_SUPPORTING_DONOR_SOURCE_SYSTEMS:
5754
profile = canonical_wave_six_donor_profile_for_source(source_system)
5855
assert profile is not None
5956
for artifact_kind in profile.supplied_artifact_kinds:
57+
seed += 1
6058
receipts.append(
61-
_receipt_for(source_system, artifact_kind, seed=seed)
59+
WaveSixDonorEvidenceReceipt(
60+
receipt_id=f"receipt:{source_system.value}:{artifact_kind.value}",
61+
source_system=source_system,
62+
repo_name=profile.repo_name,
63+
evidence_id=(
64+
f"donor-evidence:{source_system.value}:"
65+
f"{artifact_kind.value}"
66+
),
67+
artifact_kind=artifact_kind,
68+
capability_area=profile.supplied_capability_areas[0],
69+
loop_stages=(profile.supported_loop_stages[0],),
70+
artifact_fingerprint=_fingerprint(seed),
71+
summary=(
72+
f"{profile.repo_name} supplies {artifact_kind.value} "
73+
"evidence."
74+
),
75+
produced_by_engine_id=f"{source_system.value}-evidence-engine",
76+
)
6277
)
63-
seed += 1
6478
return tuple(receipts)
6579

6680

67-
def test_donor_evidence_intake_accepts_complete_supporting_receipts() -> None:
68-
bundle = build_wave_six_donor_evidence_intake_bundle(
69-
intake_id="wave6-supporting-donor-intake",
70-
receipts=_full_receipts(),
71-
notes=("Metadata-only donor evidence intake for Wave 6 review.",),
81+
def test_supporting_donor_sources_are_locked_to_expected_six() -> None:
82+
assert supporting_wave_six_donor_source_systems() == (
83+
WaveSixSourceSystem.IX_FUNCTION,
84+
WaveSixSourceSystem.IX_INTENT_REALITY_LOOP,
85+
WaveSixSourceSystem.IX_BLACKFOX,
86+
WaveSixSourceSystem.IX_BLACKFOX_COGNITION,
87+
WaveSixSourceSystem.IX_BLACKFOX_WORLDTWIN,
88+
WaveSixSourceSystem.IX_AUTONOMY_ASSURANCE_RUNTIME,
7289
)
7390

74-
assert bundle.source_systems_present == supporting_wave_six_donor_source_systems()
75-
assert bundle.missing_source_systems == ()
76-
assert bundle.missing_required_artifact_keys == ()
77-
assert bundle.status is (
78-
WaveSixDonorEvidenceIntakeStatus.READY_FOR_CANDIDATE_ASSEMBLY
91+
92+
def test_donor_evidence_receipt_accepts_metadata_only_supported_source() -> None:
93+
receipt = _receipt_for_source(WaveSixSourceSystem.IX_FUNCTION)
94+
95+
assert receipt.profile.repo_name == "IX-Function"
96+
assert receipt.human_review_required
97+
assert receipt.metadata_only
98+
assert not receipt.claims_agi
99+
assert len(receipt.fingerprint()) == 64
100+
assert receipt.fingerprint() == receipt.fingerprint()
101+
assert receipt.canonical_payload()["profile_fingerprint"] == (
102+
receipt.profile.fingerprint()
79103
)
80-
assert bundle.ready_for_candidate_assembly
81-
assert len(bundle.contract_artifacts) == len(bundle.receipts)
82-
assert len(bundle.fingerprint()) == 64
83-
assert bundle.fingerprint() == bundle.fingerprint()
84104

85105

86-
def test_donor_evidence_intake_reports_missing_supporting_sources() -> None:
106+
def test_donor_evidence_receipt_converts_to_contract_artifact() -> None:
107+
receipt = _receipt_for_source(WaveSixSourceSystem.IX_INTENT_REALITY_LOOP)
108+
artifact = receipt.to_contract_artifact()
109+
110+
assert artifact.artifact_id == "donor-evidence-artifact-receipt:ix-irl"
111+
assert artifact.source_system is WaveSixSourceSystem.IX_INTENT_REALITY_LOOP
112+
assert artifact.evidence_ids == (receipt.evidence_id,)
113+
assert artifact.produced_by_engine_id == "wave6-donor-evidence-intake-engine"
114+
assert artifact.decision is WaveSixDecisionState.NEEDS_MORE_EVIDENCE
115+
116+
117+
def test_donor_evidence_intake_bundle_reports_missing_coverage() -> None:
118+
receipt = _receipt_for_source(WaveSixSourceSystem.IX_FUNCTION)
87119
bundle = build_wave_six_donor_evidence_intake_bundle(
88120
intake_id="partial-donor-intake",
89-
receipts=(
90-
_receipt_for(
91-
WaveSixSourceSystem.IX_FUNCTION,
92-
seed=101,
93-
),
94-
),
121+
receipts=(receipt,),
122+
notes=("partial intake should remain blocked",),
95123
)
96124

97125
assert bundle.status is WaveSixDonorEvidenceIntakeStatus.NEEDS_MORE_DONOR_EVIDENCE
98126
assert not bundle.ready_for_candidate_assembly
99127
assert bundle.source_systems_present == (WaveSixSourceSystem.IX_FUNCTION,)
100128
assert WaveSixSourceSystem.IX_BLACKFOX in bundle.missing_source_systems
101-
assert "ix-function:falsification-record" in bundle.missing_required_artifact_keys
102-
assert "ix-blackfox:human-review-docket" in bundle.missing_required_artifact_keys
129+
assert bundle.missing_required_artifact_keys
130+
assert bundle.receipt_for_evidence_id(receipt.evidence_id) == receipt
131+
assert bundle.receipt_for_evidence_id("missing") is None
103132

104133

105-
def test_donor_evidence_receipt_converts_to_bounded_contract_artifact() -> None:
106-
receipt = _receipt_for(WaveSixSourceSystem.IX_BLACKFOX, seed=202)
134+
def test_donor_evidence_intake_bundle_ready_when_all_required_artifacts_present() -> None:
135+
bundle = build_wave_six_donor_evidence_intake_bundle(
136+
intake_id="complete-donor-intake",
137+
receipts=_all_required_receipts(),
138+
)
107139

108-
artifact = receipt.to_contract_artifact()
140+
assert bundle.status is WaveSixDonorEvidenceIntakeStatus.READY_FOR_CANDIDATE_ASSEMBLY
141+
assert bundle.ready_for_candidate_assembly
142+
assert bundle.missing_source_systems == ()
143+
assert bundle.missing_required_artifact_keys == ()
144+
assert len(bundle.contract_artifacts) == len(_all_required_receipts())
145+
assert bundle.fingerprint() == bundle.fingerprint()
109146

110-
assert artifact.artifact_id == f"donor-evidence-artifact-{receipt.receipt_id}"
111-
assert artifact.kind is receipt.artifact_kind
112-
assert artifact.source_system is WaveSixSourceSystem.IX_BLACKFOX
113-
assert artifact.loop_stages == receipt.loop_stages
114-
assert artifact.evidence_ids == (receipt.evidence_id,)
115-
assert artifact.produced_by_engine_id == WAVE_SIX_DONOR_EVIDENCE_INTAKE_ENGINE_ID
116-
assert artifact.decision is WaveSixDecisionState.NEEDS_MORE_EVIDENCE
117-
assert not artifact.allows_autonomous_execution
118-
assert not artifact.claims_agi
119-
assert not artifact.self_validated
120147

148+
def test_donor_evidence_intake_bundle_payload_is_deterministic() -> None:
149+
receipts = tuple(reversed(_all_required_receipts()))
150+
bundle = build_wave_six_donor_evidence_intake_bundle(
151+
intake_id="complete-donor-intake",
152+
receipts=receipts,
153+
)
121154

122-
def test_donor_evidence_intake_rejects_ix_main_as_supporting_donor() -> None:
123-
with pytest.raises(ValueError, match="supporting donor sources"):
124-
_receipt_for(WaveSixSourceSystem.IX_MAIN, seed=303)
155+
payload = bundle.canonical_payload()
125156

157+
assert payload["schema_version"] == (
158+
"ix-cognition-kernel-wave6-donor-evidence-intake-bundle-v1"
159+
)
160+
assert payload["status"] == "ready-for-candidate-assembly"
161+
assert payload["receipt_count"] == len(_all_required_receipts())
162+
assert payload["receipt_count"] == len(bundle.receipt_ids)
163+
assert payload["receipt_count"] == len(bundle.evidence_ids)
164+
assert bundle.receipt_ids == tuple(sorted(bundle.receipt_ids))
126165

127-
def test_donor_evidence_intake_rejects_repo_name_mismatch() -> None:
128-
with pytest.raises(ValueError, match="repo name must match"):
129-
_receipt_for(
130-
WaveSixSourceSystem.IX_FUNCTION,
131-
repo_name="Wrong-Repo",
132-
seed=404,
133-
)
134166

167+
def test_donor_evidence_receipt_rejects_wrong_repo_name() -> None:
168+
profile = canonical_wave_six_donor_profile_for_source(WaveSixSourceSystem.IX_FUNCTION)
169+
assert profile is not None
135170

136-
def test_donor_evidence_intake_rejects_unsupported_artifact_kind() -> None:
137-
with pytest.raises(ValueError, match="artifact kind is not supplied"):
138-
_receipt_for(
139-
WaveSixSourceSystem.IX_FUNCTION,
140-
WaveSixArtifactKind.HUMAN_REVIEW_DOCKET,
141-
seed=505,
171+
with pytest.raises(ValueError, match="repo name"):
172+
WaveSixDonorEvidenceReceipt(
173+
receipt_id="bad-repo",
174+
source_system=WaveSixSourceSystem.IX_FUNCTION,
175+
repo_name="WrongRepo",
176+
evidence_id="donor-evidence:bad-repo",
177+
artifact_kind=profile.supplied_artifact_kinds[0],
178+
capability_area=profile.supplied_capability_areas[0],
179+
loop_stages=(profile.supported_loop_stages[0],),
180+
artifact_fingerprint=_fingerprint(99),
181+
summary="Wrong repo name.",
182+
produced_by_engine_id="engine",
142183
)
143184

144185

145-
def test_donor_evidence_intake_rejects_unsupported_loop_stage() -> None:
146-
with pytest.raises(ValueError, match="loop stage is not supported"):
147-
_receipt_for(
148-
WaveSixSourceSystem.IX_FUNCTION,
186+
def test_donor_evidence_receipt_rejects_unsupported_source_or_artifact() -> None:
187+
with pytest.raises(ValueError, match="supporting donor sources"):
188+
WaveSixDonorEvidenceReceipt(
189+
receipt_id="ix-main-not-supported",
190+
source_system=WaveSixSourceSystem.IX_MAIN,
191+
repo_name="IX",
192+
evidence_id="donor-evidence:ix-main",
193+
artifact_kind=WaveSixArtifactKind.MASTER_LOOP_CONTRACT,
194+
capability_area=WaveSixCapabilityArea.MASTER_LOOP,
149195
loop_stages=(WaveSixLoopStage.INTENT,),
150-
seed=606,
196+
artifact_fingerprint=_fingerprint(100),
197+
summary="IX main is handled by handoff ingestion, not donor intake.",
198+
produced_by_engine_id="engine",
199+
)
200+
201+
with pytest.raises(ValueError, match="artifact kind"):
202+
WaveSixDonorEvidenceReceipt(
203+
receipt_id="unsupported-artifact",
204+
source_system=WaveSixSourceSystem.IX_FUNCTION,
205+
repo_name="IX-Function",
206+
evidence_id="donor-evidence:unsupported",
207+
artifact_kind=WaveSixArtifactKind.BLACKFOX_HANDOFF_RECEIPT,
208+
capability_area=WaveSixCapabilityArea.TRANSFER_GENERALIZATION,
209+
loop_stages=(WaveSixLoopStage.TRANSFER_CHECK,),
210+
artifact_fingerprint=_fingerprint(101),
211+
summary="Unsupported artifact for IX-Function.",
212+
produced_by_engine_id="engine",
151213
)
152214

153215

154-
def test_donor_evidence_intake_rejects_authority_and_overclaims() -> None:
216+
def test_donor_evidence_receipt_rejects_authority_and_overclaim_flags() -> None:
155217
with pytest.raises(ValueError, match="must not grant execution"):
156-
_receipt_for(
218+
_receipt_for_source(
157219
WaveSixSourceSystem.IX_BLACKFOX,
220+
seed=200,
221+
).__class__(
222+
receipt_id="bad-authority",
223+
source_system=WaveSixSourceSystem.IX_BLACKFOX,
224+
repo_name="IX-BlackFox",
225+
evidence_id="donor-evidence:bad-authority",
226+
artifact_kind=WaveSixArtifactKind.BLACKFOX_HANDOFF_RECEIPT,
227+
capability_area=WaveSixCapabilityArea.HUMAN_AUTHORITY_PRESERVATION,
228+
loop_stages=(WaveSixLoopStage.TRIAL,),
229+
artifact_fingerprint=_fingerprint(201),
230+
summary="Bad authority receipt.",
231+
produced_by_engine_id="engine",
158232
allows_autonomous_execution=True,
159-
seed=707,
160233
)
234+
161235
with pytest.raises(ValueError, match="must not claim AGI"):
162-
_receipt_for(
236+
_receipt_for_source(
163237
WaveSixSourceSystem.IX_BLACKFOX_COGNITION,
238+
seed=300,
239+
).__class__(
240+
receipt_id="bad-agi-claim",
241+
source_system=WaveSixSourceSystem.IX_BLACKFOX_COGNITION,
242+
repo_name="IX-BlackFox-Cognition",
243+
evidence_id="donor-evidence:bad-agi-claim",
244+
artifact_kind=WaveSixArtifactKind.COGNITION_REVIEW_RECORD,
245+
capability_area=WaveSixCapabilityArea.HUMAN_AUTHORITY_PRESERVATION,
246+
loop_stages=(WaveSixLoopStage.HUMAN_REVIEW,),
247+
artifact_fingerprint=_fingerprint(301),
248+
summary="Bad AGI claim receipt.",
249+
produced_by_engine_id="engine",
164250
claims_agi=True,
165-
seed=708,
166-
)
167-
with pytest.raises(ValueError, match="must require human review"):
168-
_receipt_for(
169-
WaveSixSourceSystem.IX_BLACKFOX_WORLDTWIN,
170-
human_review_required=False,
171-
seed=709,
172251
)
173252

174253

175-
def test_donor_evidence_intake_rejects_duplicate_evidence_ids() -> None:
176-
first = _receipt_for(WaveSixSourceSystem.IX_FUNCTION, seed=808)
177-
second = _receipt_for(
178-
WaveSixSourceSystem.IX_INTENT_REALITY_LOOP,
179-
evidence_id=first.evidence_id,
180-
seed=809,
181-
)
254+
def test_donor_evidence_intake_rejects_duplicate_receipts() -> None:
255+
receipt = _receipt_for_source(WaveSixSourceSystem.IX_FUNCTION)
182256

183-
with pytest.raises(ValueError, match="Duplicate evidence_id"):
257+
with pytest.raises(ValueError, match="Duplicate receipt_id"):
184258
build_wave_six_donor_evidence_intake_bundle(
185-
intake_id="duplicate-evidence",
186-
receipts=(first, second),
259+
intake_id="duplicate-receipts",
260+
receipts=(receipt, receipt),
187261
)
188262

189263

190-
def test_donor_evidence_intake_can_lookup_receipts() -> None:
191-
bundle = build_wave_six_donor_evidence_intake_bundle(
192-
intake_id="lookup-intake",
193-
receipts=_full_receipts(),
264+
def test_donor_evidence_intake_filters_receipts_by_source() -> None:
265+
receipt_a = _receipt_for_source(WaveSixSourceSystem.IX_FUNCTION, seed=1)
266+
receipt_b = _receipt_for_source(
267+
WaveSixSourceSystem.IX_INTENT_REALITY_LOOP,
268+
seed=2,
194269
)
195-
196-
receipt = bundle.receipt_for_evidence_id(
197-
"donor-evidence:ix-function:transfer-novelty-record"
270+
bundle = build_wave_six_donor_evidence_intake_bundle(
271+
intake_id="partial-donor-intake",
272+
receipts=(receipt_b, receipt_a),
198273
)
199274

200-
assert receipt is not None
201-
assert receipt.source_system is WaveSixSourceSystem.IX_FUNCTION
202-
assert bundle.receipts_for_source(WaveSixSourceSystem.IX_BLACKFOX)
275+
assert bundle.receipts_for_source(WaveSixSourceSystem.IX_FUNCTION) == (receipt_a,)
276+
assert bundle.receipts_for_source(WaveSixSourceSystem.IX_BLACKFOX) == ()

0 commit comments

Comments
 (0)