[verified] Add canonical harness test runner and enforce role collection
This commit is contained in:
@@ -15,7 +15,7 @@ def inventory_digest(ids, statuses):
|
||||
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':')).encode()).hexdigest()
|
||||
|
||||
|
||||
def test_inventory(ids=('case_a',), current=None):
|
||||
def make_test_inventory(ids=('case_a',), current=None):
|
||||
current = list(ids if current is None else current)
|
||||
ids = list(ids)
|
||||
old_status = {key: {'skip': False, 'expected_failure': False} for key in ids}
|
||||
@@ -157,84 +157,84 @@ class WorkflowGuardTests(unittest.TestCase):
|
||||
self.assertEqual(guard.compare_source(root, out, ['src/a.py'])['status'], 'block')
|
||||
|
||||
def test_new_regression_tests_do_not_require_deletion_authorization(self):
|
||||
self.assertEqual(guard.check_tests(test_inventory(current=['case_a', 'case_b']))['status'], 'pass')
|
||||
self.assertEqual(guard.check_tests(make_test_inventory(current=['case_a', 'case_b']))['status'], 'pass')
|
||||
|
||||
def test_collected_inventory_requires_provenance(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
del value['baseline_collection']
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_collected_inventory_digest_must_match_ids_and_statuses(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['baseline_collection']['inventory_sha256'] = '0' * 64
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_new_skip_requires_explicit_approval(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['current_status']['case_a']['skip'] = True
|
||||
value['current_collection']['inventory_sha256'] = inventory_digest(value['current_ids'], value['current_status'])
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_new_expected_failure_requires_explicit_approval(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['current_status']['case_a']['expected_failure'] = True
|
||||
value['current_collection']['inventory_sha256'] = inventory_digest(value['current_ids'], value['current_status'])
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_rename_requires_real_replacement_and_semantic_evidence(self):
|
||||
value = test_inventory(current=['case_b'])
|
||||
value = make_test_inventory(current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'rename', 'replacement_ids': ['ghost'],
|
||||
'reason': 'rename', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_approved_rename_preserves_mapped_test(self):
|
||||
value = test_inventory(current=['case_b'])
|
||||
value = make_test_inventory(current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'rename', 'replacement_ids': ['case_b'],
|
||||
'reason': 'rename', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assertEqual(guard.check_tests(value)['status'], 'pass')
|
||||
|
||||
def test_modified_test_requires_semantic_review(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['changed_tests'] = [{'test_id': 'case_a', 'baseline_sha256': 'a' * 64,
|
||||
'current_sha256': 'b' * 64, 'review_evidence': ''}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_finding_truthy_strings_are_not_red_green_records(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['findings'] = [{'id': 'finding-a', 'test_id': 'case_a', 'classification': 'assertion',
|
||||
'red': 'claimed-red', 'green': 'claimed-green'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_red_success_exit_cannot_demonstrate_failure(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
finding = finding_record()
|
||||
finding['red']['exit_code'] = finding['red']['expected_exit_code'] = 0
|
||||
value['findings'] = [finding]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_green_failure_exit_cannot_demonstrate_resolution(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
finding = finding_record()
|
||||
finding['green']['exit_code'] = finding['green']['expected_exit_code'] = 1
|
||||
value['findings'] = [finding]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_environment_failure_is_not_valid_red(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
finding = finding_record()
|
||||
finding['red']['failure_kind'] = 'environment'
|
||||
value['findings'] = [finding]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_finding_must_name_present_regression_test(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
finding = finding_record()
|
||||
finding['test_id'] = 'ghost'
|
||||
value['findings'] = [finding]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_named_red_green_records_with_provenance_pass(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['findings'] = [finding_record()]
|
||||
self.assertEqual(guard.check_tests(value)['status'], 'pass')
|
||||
|
||||
@@ -342,31 +342,31 @@ class WorkflowGuardTests(unittest.TestCase):
|
||||
self.assertEqual(json.loads(result.stdout)['status'], 'block')
|
||||
|
||||
def test_rename_empty_replacement_cannot_stand_in_for_deletion(self):
|
||||
value = test_inventory(current=['case_b'])
|
||||
value = make_test_inventory(current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'rename', 'replacement_ids': [],
|
||||
'reason': 'rename', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_unclassified_empty_replacement_cannot_stand_in_for_deletion(self):
|
||||
value = test_inventory(current=['case_b'])
|
||||
value = make_test_inventory(current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'replacement_ids': [],
|
||||
'reason': 'rename', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_explicit_approved_deletion_is_allowed(self):
|
||||
value = test_inventory(ids=['case_a', 'case_b'], current=['case_b'])
|
||||
value = make_test_inventory(ids=['case_a', 'case_b'], current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'delete', 'replacement_ids': [],
|
||||
'reason': 'approved obsolete case deletion', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assertEqual(guard.check_tests(value)['status'], 'pass')
|
||||
|
||||
def test_status_approval_cannot_authorize_removal(self):
|
||||
value = test_inventory(current=['case_b'])
|
||||
value = make_test_inventory(current=['case_b'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'status', 'replacement_ids': ['case_b'],
|
||||
'reason': 'approved status update', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
def test_explicit_status_approval_maps_same_current_id(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['current_status']['case_a']['skip'] = True
|
||||
value['current_collection']['inventory_sha256'] = inventory_digest(value['current_ids'], value['current_status'])
|
||||
value['authorized_changes'] = [{'old_id': 'case_a', 'kind': 'status', 'replacement_ids': ['case_a'],
|
||||
@@ -374,7 +374,7 @@ class WorkflowGuardTests(unittest.TestCase):
|
||||
self.assertEqual(guard.check_tests(value)['status'], 'pass')
|
||||
|
||||
def test_unhashable_authorization_id_fails_closed_api(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['authorized_changes'] = [{'old_id': ['case_a'], 'replacement_ids': [],
|
||||
'reason': 'fixture', 'approval': 'fixture-approval', 'evidence': 'fixture-review'}]
|
||||
self.assert_block(guard.check_tests, value)
|
||||
@@ -408,10 +408,10 @@ class WorkflowGuardTests(unittest.TestCase):
|
||||
|
||||
def test_declared_evidence_shape_does_not_authenticate_records(self):
|
||||
# Deliberately synthetic fixture claims: the main agent must check actual evidence separately.
|
||||
self.assertEqual(guard.check_tests(test_inventory())['status'], 'pass')
|
||||
self.assertEqual(guard.check_tests(make_test_inventory())['status'], 'pass')
|
||||
|
||||
def test_unknown_inventory_fields_are_rejected(self):
|
||||
value = test_inventory()
|
||||
value = make_test_inventory()
|
||||
value['pretend_verified'] = True
|
||||
self.assert_block(guard.check_tests, value)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user