주기 실회기 검증과 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

@ -1,7 +1,9 @@
from __future__ import annotations
import importlib.util
import json
import sys
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
@ -50,8 +52,8 @@ def args(**overrides):
"microphone_device": "",
"confirm_physical_capture": False,
"duration_seconds": 3_120.0,
"runtime_interval_seconds": 100.0,
"topology_interval_seconds": 100.0,
"runtime_interval_seconds": 60.0,
"topology_interval_seconds": 60.0,
"human_voice_gain": Path("pack.json"),
"out_dir": Path("out"),
"rehearse": False,
@ -154,6 +156,8 @@ class HostAlignmentTest(unittest.TestCase):
self.assertEqual(MODULE.DEFAULT_BROWSER_ORIGIN, parsed.origin)
self.assertEqual(MODULE.DEFAULT_ADMIN_RUNTIME_URL, parsed.admin_runtime_url)
self.assertEqual(3_120.0, parsed.duration_seconds)
self.assertEqual(60.0, parsed.runtime_interval_seconds)
self.assertEqual(60.0, parsed.topology_interval_seconds)
self.assertIsNone(parsed.allowed_browser_origins)
help_text = parser.format_help()
for expected in (
@ -168,13 +172,13 @@ class HostAlignmentTest(unittest.TestCase):
class SamplePlanTest(unittest.TestCase):
def test_samples_cover_the_whole_window(self) -> None:
self.assertEqual(MODULE.sample_plan(3_120.0, 100.0), 33)
self.assertEqual(MODULE.sample_plan(3_120.0, 60.0), 53)
def test_fractional_interval_always_gets_a_terminal_sample(self) -> None:
self.assertEqual(MODULE.sample_plan(3_121.0, 100.0), 33)
self.assertEqual(MODULE.sample_plan(3_121.0, 60.0), 54)
def test_invalid_plan_fails_closed(self) -> None:
for duration, interval in ((0, 100.0), (3_000.0, 0)):
for duration, interval in ((0, 60.0), (3_000.0, 0)):
with self.subTest(duration=duration, interval=interval):
with self.assertRaises(MODULE.WindowError):
MODULE.sample_plan(duration, interval)
@ -226,6 +230,44 @@ class ConsentGateTest(unittest.TestCase):
def test_rehearse_relaxes_only_the_two_human_inputs(self) -> None:
MODULE.validate(args(rehearse=True, duration_seconds=30.0, human_voice_gain=None))
def test_child_sampling_intervals_are_bounded_before_capture(self) -> None:
for field in ("runtime_interval_seconds", "topology_interval_seconds"):
with self.subTest(field=field):
with self.assertRaises(MODULE.WindowError) as ctx:
MODULE.validate(args(**{field: 60.001}))
self.assertEqual(
f"{field.removesuffix('_seconds')}_out_of_bounds",
str(ctx.exception),
)
def test_human_pack_is_fully_validated_before_capture(self) -> None:
from app.test_g7_voice_gain_evidence import _valid_payload
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
missing = root / "missing.json"
with self.assertRaises(MODULE.WindowError) as ctx:
MODULE.validate_human_voice_gain_pack(missing)
self.assertEqual("human_voice_gain_pack_unreadable", str(ctx.exception))
malformed = root / "malformed.json"
malformed.write_text("{}", encoding="utf-8")
with self.assertRaises(MODULE.WindowError) as ctx:
MODULE.validate_human_voice_gain_pack(malformed)
self.assertEqual("human_voice_gain_pack_invalid", str(ctx.exception))
underpowered = root / "underpowered.json"
underpowered.write_text(
json.dumps(_valid_payload()),
encoding="utf-8",
)
with self.assertRaises(MODULE.WindowError) as ctx:
MODULE.validate_human_voice_gain_pack(underpowered)
self.assertTrue(
str(ctx.exception).startswith("human_voice_gain_pack_failed:")
)
self.assertIn("production_participant_floor", str(ctx.exception))
class LegCompositionTest(unittest.TestCase):
def test_expected_providers_default_to_the_decided_local_stack(self) -> None: