77
88from ix .assurance import AssuranceProfileRegistry , assess_ix
99from ix .cli import main
10+ from ix .cognition import cognition_obligation_ids
1011from ix .parser import parse_ix
1112
1213
13- VALID_COGNITION_CONTRACT = '''
14- attempt wave6_measured_cognition {
15- purpose "Test whether measured reality corrects future reasoning"
16- non_goal "Do not claim AGI"
17- claim_boundary "Research candidate only"
18- require human_approval reason "Human review required before advancement"
19- handoff_contract IX-CognitionKernel schema ix.cognition.contract.v1
14+ def build_cognition_contract (
15+ obligation_ids : tuple [str , ...] | None = None ,
16+ * ,
17+ handoff_target : str = "IX-CognitionKernel" ,
18+ ) -> str :
19+ selected_obligations = obligation_ids or cognition_obligation_ids ()
20+ lines = [
21+ "attempt wave6_measured_cognition {" ,
22+ ' purpose "Test whether measured reality corrects future reasoning"' ,
23+ ' non_goal "Do not claim AGI"' ,
24+ ' claim_boundary "Research candidate only"' ,
25+ ' require human_approval reason "Human review required before advancement"' ,
26+ f" handoff_contract { handoff_target } schema ix.cognition.contract.v1" ,
27+ "" ,
28+ ]
29+
30+ for obligation_id in selected_obligations :
31+ lines .extend (
32+ [
33+ f" obligation { obligation_id } {{" ,
34+ f" evidence_required { obligation_id } _record" ,
35+ f" falsify_if { obligation_id } _missing" ,
36+ " }" ,
37+ "" ,
38+ ]
39+ )
40+
41+ lines .append ("}" )
42+ return "\n " .join (lines )
2043
21- obligation prediction_before_trial {
22- evidence_required prediction_record
23- falsify_if prediction_missing
24- }
25- }
26- '''
44+
45+ VALID_COGNITION_CONTRACT = build_cognition_contract ()
2746
2847
2948class TestIXCognitionAssuranceProfile (unittest .TestCase ):
@@ -69,22 +88,22 @@ def test_cognition_profile_requires_attempt_contract_not_loose_statements(self):
6988 self .assertNotIn ("assertions.missing" , check_ids )
7089 self .assertNotIn ("trace_statements.present" , check_ids )
7190
72- def test_cognition_profile_accepts_core_complete_contract (self ):
91+ def test_cognition_profile_accepts_complete_canonical_contract (self ):
7392 program = parse_ix (VALID_COGNITION_CONTRACT )
7493
7594 report = assess_ix (program , profile = "cognitionkernel-wave6" )
7695 check_ids = {check .check_id for check in report .checks }
7796
7897 self .assertEqual (report .status , "pass" )
7998 self .assertEqual (report .metrics ["attempts" ], 1 )
80- self .assertEqual (report .metrics ["obligations" ], 1 )
99+ self .assertEqual (report .metrics ["obligations" ], 20 )
81100 self .assertEqual (report .metrics ["purposes" ], 1 )
82101 self .assertEqual (report .metrics ["non_goals" ], 1 )
83102 self .assertEqual (report .metrics ["claim_boundaries" ], 1 )
84103 self .assertEqual (report .metrics ["approvals_required" ], 1 )
85104 self .assertEqual (report .metrics ["handoff_contracts" ], 1 )
86- self .assertEqual (report .metrics ["evidence_requirements" ], 1 )
87- self .assertEqual (report .metrics ["falsification_gates" ], 1 )
105+ self .assertEqual (report .metrics ["evidence_requirements" ], 20 )
106+ self .assertEqual (report .metrics ["falsification_gates" ], 20 )
88107 self .assertIn ("cognition_contract.attempt_present" , check_ids )
89108 self .assertIn ("cognition_contract.purpose.present" , check_ids )
90109 self .assertIn ("cognition_contract.non_goal.present" , check_ids )
@@ -93,6 +112,8 @@ def test_cognition_profile_accepts_core_complete_contract(self):
93112 self .assertIn ("cognition_contract.handoff_contract.present" , check_ids )
94113 self .assertIn ("cognition_contract.kernel_handoff.present" , check_ids )
95114 self .assertIn ("cognition_contract.obligations.present" , check_ids )
115+ self .assertIn ("cognition_contract.required_obligations.present" , check_ids )
116+ self .assertIn ("cognition_contract.obligations.canonical" , check_ids )
96117 self .assertIn ("cognition_contract.obligation_evidence.present" , check_ids )
97118 self .assertIn ("cognition_contract.obligation_falsification.present" , check_ids )
98119
@@ -116,25 +137,51 @@ def test_cognition_profile_fails_missing_core_contract_parts(self):
116137 self .assertIn ("cognition_contract.claim_boundary.missing" , check_ids )
117138 self .assertIn ("cognition_contract.human_review.missing" , check_ids )
118139 self .assertIn ("cognition_contract.handoff_contract.missing" , check_ids )
140+ self .assertIn ("cognition_contract.required_obligations.missing" , check_ids )
119141 self .assertIn ("cognition_contract.obligation_falsification.missing" , check_ids )
120142
121- def test_cognition_profile_fails_wrong_handoff_target (self ):
143+ def test_cognition_profile_fails_missing_required_obligations (self ):
144+ incomplete_ids = tuple (
145+ obligation_id
146+ for obligation_id in cognition_obligation_ids ()
147+ if obligation_id != "future_reasoning_change"
148+ )
149+ program = parse_ix (build_cognition_contract (incomplete_ids ))
150+
151+ report = assess_ix (program , profile = "cognitionkernel-wave6" )
152+ check_ids = {check .check_id for check in report .checks }
153+ missing_checks = [
154+ check
155+ for check in report .checks
156+ if check .check_id == "cognition_contract.required_obligations.missing"
157+ ]
158+
159+ self .assertEqual (report .status , "fail" )
160+ self .assertIn ("cognition_contract.required_obligations.missing" , check_ids )
161+ self .assertEqual (len (missing_checks ), 1 )
162+ self .assertIn ("future_reasoning_change" , missing_checks [0 ].data ["missing_obligations" ])
163+
164+ def test_cognition_profile_fails_unknown_obligation_ids (self ):
122165 program = parse_ix (
123- '''
124- attempt wave6_measured_cognition {
125- purpose "Test measured correction"
126- non_goal "Do not claim AGI"
127- claim_boundary "Research candidate only"
128- require human_approval reason "Human review required"
129- handoff_contract OtherKernel schema ix.cognition.contract.v1
130- obligation prediction_before_trial {
131- evidence_required prediction_record
132- falsify_if prediction_missing
133- }
134- }
135- '''
166+ build_cognition_contract (cognition_obligation_ids () + ("custom_gap_label" ,))
136167 )
137168
169+ report = assess_ix (program , profile = "cognitionkernel-wave6" )
170+ check_ids = {check .check_id for check in report .checks }
171+ unknown_checks = [
172+ check
173+ for check in report .checks
174+ if check .check_id == "cognition_contract.obligations.unknown"
175+ ]
176+
177+ self .assertEqual (report .status , "fail" )
178+ self .assertIn ("cognition_contract.obligations.unknown" , check_ids )
179+ self .assertEqual (len (unknown_checks ), 1 )
180+ self .assertIn ("custom_gap_label" , unknown_checks [0 ].data ["unknown_obligations" ])
181+
182+ def test_cognition_profile_fails_wrong_handoff_target (self ):
183+ program = parse_ix (build_cognition_contract (handoff_target = "OtherKernel" ))
184+
138185 report = assess_ix (program , profile = "cognitionkernel-wave6" )
139186 check_ids = {check .check_id for check in report .checks }
140187
@@ -172,9 +219,11 @@ def test_cli_assure_json_can_select_cognition_profile(self):
172219 self .assertEqual (payload ["profile" ], "cognitionkernel-wave6" )
173220 self .assertEqual (payload ["status" ], "pass" )
174221 self .assertEqual (payload ["metrics" ]["attempts" ], 1 )
222+ self .assertEqual (payload ["metrics" ]["obligations" ], 20 )
175223 self .assertIn ("profile.selected" , check_ids )
176224 self .assertIn ("program.non_empty" , check_ids )
177225 self .assertIn ("cognition_contract.attempt_present" , check_ids )
226+ self .assertIn ("cognition_contract.required_obligations.present" , check_ids )
178227
179228 def test_cli_assure_execute_fails_closed_for_cognition_profile (self ):
180229 ix_file = self ._write_ix (VALID_COGNITION_CONTRACT )
0 commit comments