주기 실회기 검증과 G7 종료계약 보강

This commit is contained in:
Yun Chan 2026-08-09 23:37:19 +09:00
parent 83590e9ef7
commit 7b4955c3fc
23 changed files with 2916 additions and 117 deletions

View file

@ -179,8 +179,34 @@ class G7HumanVoiceGainEvidenceTests(unittest.TestCase):
self.assertEqual(result.intention_to_evaluate_imputations, 1)
expected_voice_accuracy = 1.0 - ((1.0 + (0.05 * 5)) / 6)
self.assertAlmostEqual(result.voice_enabled_one_minus_mae, expected_voice_accuracy)
self.assertEqual(result.paired_axis_observations, 5)
self.assertEqual(result.held_out_sessions, 1)
self.assertIn("production_observation_floor", result.failure_reasons)
self.assertIn("production_session_floor", result.failure_reasons)
self.assertFalse(result.passed)
def test_baseline_only_missing_cannot_inflate_candidate_gain(self) -> None:
complete = G7HumanVoiceGainEvidencePack.model_validate(_valid_payload())
complete_result = evaluate_human_voice_gain(
complete,
thresholds=_test_thresholds(),
)
payload = _valid_payload()
observations = payload["observations"]
assert isinstance(observations, list)
observations[0]["text_only_status"] = "missing"
observations[0]["text_only_score"] = None
missing = G7HumanVoiceGainEvidencePack.model_validate(payload)
missing_result = evaluate_human_voice_gain(
missing,
thresholds=_test_thresholds(),
)
self.assertLess(missing_result.paired_gain, complete_result.paired_gain)
self.assertEqual(missing_result.intention_to_evaluate_imputations, 1)
self.assertEqual(missing_result.paired_axis_observations, 5)
def test_duplicate_or_calibration_observation_is_rejected(self) -> None:
duplicate = _valid_payload()
duplicate_rows = duplicate["observations"]
@ -236,6 +262,64 @@ class G7HumanVoiceGainEvidenceTests(unittest.TestCase):
self.assertFalse(result.passed)
self.assertIn("reported_icc_matches_rows", result.failure_reasons)
def test_categorical_kappa_is_mandatory_and_recomputed(self) -> None:
missing_report = _valid_payload()
reliability = missing_report["reliability"]
assert isinstance(reliability, dict)
reliability.pop("reported_categorical_kappa")
with self.assertRaises(ValidationError):
G7HumanVoiceGainEvidencePack.model_validate(missing_report)
missing_category = _valid_payload()
observations = missing_category["observations"]
assert isinstance(observations, list)
labels = observations[0]["labels"]
assert isinstance(labels, list)
labels[0].pop("category")
with self.assertRaises(ValidationError):
G7HumanVoiceGainEvidencePack.model_validate(missing_category)
mismatched = _valid_payload()
reliability = mismatched["reliability"]
assert isinstance(reliability, dict)
reliability["reported_categorical_kappa"] = 0.8
pack = G7HumanVoiceGainEvidencePack.model_validate(mismatched)
result = evaluate_human_voice_gain(pack, thresholds=_test_thresholds())
self.assertIn("reported_kappa_matches_rows", result.failure_reasons)
weak = _valid_payload()
observations = weak["observations"]
assert isinstance(observations, list)
for observation in observations:
labels = observation["labels"]
assert isinstance(labels, list)
labels[0]["category"] = "low"
labels[1]["category"] = "high"
reliability = weak["reliability"]
assert isinstance(reliability, dict)
reliability["reported_categorical_kappa"] = -1.0
weak_pack = G7HumanVoiceGainEvidencePack.model_validate(weak)
weak_result = evaluate_human_voice_gain(
weak_pack,
thresholds=_test_thresholds(),
)
self.assertIn("recomputed_categorical_kappa", weak_result.failure_reasons)
def test_analysis_registration_must_strictly_precede_held_out_access(self) -> None:
payload = _valid_payload()
provenance = payload["provenance"]
assert isinstance(provenance, dict)
provenance["registered_at"] = provenance["held_out_labels_opened_at"]
with self.assertRaisesRegex(ValidationError, "must precede"):
G7HumanVoiceGainEvidencePack.model_validate(payload)
wrong_alpha = _valid_payload()
power_plan = wrong_alpha["power_plan"]
assert isinstance(power_plan, dict)
power_plan["alpha"] = 0.01
with self.assertRaises(ValidationError):
G7HumanVoiceGainEvidencePack.model_validate(wrong_alpha)
def test_custom_thresholds_require_explicit_test_factory(self) -> None:
pack = G7HumanVoiceGainEvidencePack.model_validate(_valid_payload())
with self.assertRaisesRegex(ValueError, "test-only"):