diff --git a/experiments/universality/two_parameter_cusp_population/GLOBAL_SELECTOR_CONTRACT.md b/experiments/universality/two_parameter_cusp_population/GLOBAL_SELECTOR_CONTRACT.md index adeb70dac..cabb2660b 100644 --- a/experiments/universality/two_parameter_cusp_population/GLOBAL_SELECTOR_CONTRACT.md +++ b/experiments/universality/two_parameter_cusp_population/GLOBAL_SELECTOR_CONTRACT.md @@ -184,6 +184,27 @@ the actual barcode, the population projection and disposition. `select_h0` or trusting its PASS flags. It returns named check results and rejects a changed root multiplicity, omitted component or swapped elder edge. +A standalone `verify_h0` status of `PASS` certifies **algebraic/incidence +replay only**, not the acceptance of a fixture or the complete experiment. +`run_attempt` separately requires selection `CERTIFIED` before verification. +Its expectation consumer requires selection and actual-barcode `CERTIFIED`, +verification `PASS`, and **every derived soundness gate** `PASS` before +reading the fixed expected values. In particular `critical_completeness` +requires a root-set status of `CERTIFIED` as well as successful root/height +replay. Changing just a selection, barcode or root-set status string can +leave standalone algebraic replay at `PASS`; those status values are +independent acceptance obligations, not replay evidence. + +A real selector withdrawal also changes the population-projection status, +which the raw verifier checks against its recomputed projection if replay +reaches that check. Driver-wide source-drift/deadline withdrawal retains +computed bars and records `computed_status_before_withdrawal`, but changes +current acceptance statuses to an inconclusive value. Historical computed +statuses never reauthorize acceptance, even if older algebraic replay was +`PASS`. The driver's normalized output wraps raw boolean/null predicates; +without an explicit forensic decoding contract it is **not** a raw +`Fraction`/boolean certificate to pass back into `verify_h0`. + Neither new executable module imports `population_certificate`, its runner, `critical_fixture`, a population CDF, or a lifetime/gap oracle. The driver may read literal comparison expectations only after a complete selection and diff --git a/experiments/universality/two_parameter_cusp_population/test_global_h0_runner.py b/experiments/universality/two_parameter_cusp_population/test_global_h0_runner.py index 7d483dc47..214a71b70 100644 --- a/experiments/universality/two_parameter_cusp_population/test_global_h0_runner.py +++ b/experiments/universality/two_parameter_cusp_population/test_global_h0_runner.py @@ -225,6 +225,32 @@ def test_missing_gate_incomplete_selection_or_failed_verifier_never_reads_expect self.assertEqual(result['status'], 'NOT_COMPARED') lookup.assert_not_called() + def test_previous_raw_replay_pass_never_restores_withdrawn_acceptance(self): + # The old raw replay can remain PASS as historical evidence, while + # the current driver admission must fail closed after withdrawal. + selection, verification, gates = synthetic_records() + row = {'status': 'CERTIFIED', 'selection': selection, + 'verification': verification, 'soundness': copy.deepcopy(gates), + 'test_only': True} + before = copy.deepcopy(row) + withdrawn = self.driver.withdraw_acceptance( + row, 'INCONCLUSIVE_SOURCE_DRIFT', phase='TEST_ONLY_postflight', + detail='TEST_ONLY source identity drift') + self.assertEqual(row, before) + self.assertEqual(withdrawn['computed_status_before_withdrawal'], 'CERTIFIED') + current = withdrawn['selection'] + self.assertEqual(current['status'], 'INCONCLUSIVE_SOURCE_DRIFT') + self.assertEqual(current['computed_status_before_withdrawal'], 'CERTIFIED') + self.assertEqual(current['actual_barcode']['status'], 'INCONCLUSIVE_SOURCE_DRIFT') + self.assertEqual(current['actual_barcode']['computed_status_before_withdrawal'], 'CERTIFIED') + self.assertEqual(current['actual_barcode']['finite'], selection['actual_barcode']['finite']) + self.assertEqual(verification['status'], 'PASS') + forbidden_lookup = mock.Mock(side_effect=AssertionError('Historical replay promoted acceptance')) + result = self.driver.compare_expectations( + 'TEST_ONLY', current, verification, gates, expected_lookup=forbidden_lookup) + self.assertEqual(result, {'status': 'NOT_COMPARED', 'mismatches': []}) + forbidden_lookup.assert_not_called() + def test_sound_comparison_reads_literal_expectation_once_without_mutating_numeric_evidence(self): selection, verification, gates = synthetic_records() before = copy.deepcopy(selection) diff --git a/experiments/universality/two_parameter_cusp_population/test_global_h0_selector.py b/experiments/universality/two_parameter_cusp_population/test_global_h0_selector.py old mode 100755 new mode 100644 index b2f245323..88be3091c --- a/experiments/universality/two_parameter_cusp_population/test_global_h0_selector.py +++ b/experiments/universality/two_parameter_cusp_population/test_global_h0_selector.py @@ -332,6 +332,27 @@ def test_verifier_replays_without_calling_selector(self): with patch.object(selector, "select_h0", side_effect=AssertionError("verifier called selector")): self.assertEqual(selector.verify_h0(u, v, certificate, budget=budget)["status"], "PASS") + def test_status_only_mutations_replay_without_acceptance_credit(self): + # Raw algebraic replay does not enforce these producer dispositions; + # the driver checks their acceptance separately. No scientific run. + u, v, certificate, _ = self.hostile() + original = copy.deepcopy(certificate) + for field in ("selection", "barcode", "critical_roots"): + with self.subTest(field=field): + altered = copy.deepcopy(certificate) + record = (altered if field == "selection" else + altered["actual_barcode"] if field == "barcode" else + altered["critical_roots"]) + self.assertEqual(record["status"], "CERTIFIED") + record["status"] = "INCONCLUSIVE_BUDGET" + frozen = copy.deepcopy(altered) + replay = selector.verify_h0(u, v, altered, budget=self.budget()) + self.assertEqual(replay["status"], "PASS") + self.assertEqual(altered, frozen) + self.assertEqual(altered["actual_barcode"]["finite"], + original["actual_barcode"]["finite"]) + self.assertEqual(certificate, original) + def test_changed_root_multiplicity_is_rejected_despite_pass_flags(self): u, v, certificate, _ = self.hostile() bad = copy.deepcopy(certificate)