외부 실증과 인증 화면 경계 보강
This commit is contained in:
parent
68fd8f65a3
commit
64e1b2210d
7 changed files with 64 additions and 10 deletions
|
|
@ -8,8 +8,9 @@ TLS WebSocket route. Full soak additionally captures a physical microphone throu
|
|||
ffmpeg.
|
||||
|
||||
The runner never writes raw audio, cookie values, session IDs, transcripts, or
|
||||
replies to its evidence. Its default soak duration is the contractual 50
|
||||
minutes. Use ``--preflight-only`` for a route/auth/provider-readiness audit that
|
||||
replies to its evidence. Its production soak duration is at least 3,120 seconds
|
||||
so the concurrent proof window can retain a full 3,000-second intersection. Use
|
||||
``--preflight-only`` for a route/auth/provider-readiness audit that
|
||||
never enumerates or opens a microphone. Full soak cannot enumerate or capture a
|
||||
microphone unless the operator passes ``--confirm-physical-capture`` explicitly.
|
||||
|
||||
|
|
@ -47,7 +48,8 @@ DEFAULT_ORIGIN = "https://vignette.chanpaca.net"
|
|||
DEFAULT_COOKIE_ENV = "VIGNETTE_PUBLIC_SESSION_COOKIE"
|
||||
DEFAULT_SESSION_ENV = "VIGNETTE_PUBLIC_VOICE_SESSION_ID"
|
||||
DEFAULT_COOKIE_NAME = "__Host-vignette_sid"
|
||||
DEFAULT_DURATION_SECONDS = 3_000.0
|
||||
MIN_PRODUCTION_DURATION_SECONDS = 3_120.0
|
||||
DEFAULT_DURATION_SECONDS = MIN_PRODUCTION_DURATION_SECONDS
|
||||
DEFAULT_TURN_INTERVAL_SECONDS = 60.0
|
||||
DEFAULT_HEARTBEAT_SECONDS = 20.0
|
||||
DEFAULT_CAPTURE_SECONDS = 3.0
|
||||
|
|
@ -902,7 +904,8 @@ def parser() -> argparse.ArgumentParser:
|
|||
result = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Physical-microphone and authenticated public /voice/ws soak. "
|
||||
"The default duration is the contractual 50 minutes."
|
||||
"Production requires at least 3,120 seconds so the concurrent "
|
||||
"proof retains a 3,000-second common window."
|
||||
)
|
||||
)
|
||||
result.add_argument("--preflight-only", action="store_true")
|
||||
|
|
@ -961,6 +964,13 @@ def validate_args(args: argparse.Namespace, cli: argparse.ArgumentParser) -> Non
|
|||
cli.error(str(exc))
|
||||
if args.duration_seconds <= 0:
|
||||
cli.error("--duration-seconds must be > 0")
|
||||
if (
|
||||
not args.preflight_only
|
||||
and args.duration_seconds < MIN_PRODUCTION_DURATION_SECONDS
|
||||
):
|
||||
cli.error(
|
||||
"--duration-seconds must be >= 3120 for a production physical soak"
|
||||
)
|
||||
if args.turn_interval_seconds <= 0:
|
||||
cli.error("--turn-interval-seconds must be > 0")
|
||||
if args.heartbeat_seconds <= 0:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class G7ExternalVoiceSoakTests(unittest.TestCase):
|
|||
def setUpClass(cls) -> None:
|
||||
cls.runner = load_runner()
|
||||
|
||||
def test_default_duration_is_contractual_fifty_minutes(self) -> None:
|
||||
def test_default_duration_preserves_the_common_window_margin(self) -> None:
|
||||
args = self.runner.parser().parse_args(
|
||||
[
|
||||
"--expected-stt-provider",
|
||||
|
|
@ -62,10 +62,37 @@ class G7ExternalVoiceSoakTests(unittest.TestCase):
|
|||
"Physical Microphone",
|
||||
]
|
||||
)
|
||||
self.assertEqual(3_000.0, args.duration_seconds)
|
||||
self.assertEqual(3_120.0, args.duration_seconds)
|
||||
self.assertFalse(args.preflight_only)
|
||||
self.assertFalse(args.confirm_physical_capture)
|
||||
|
||||
def test_full_soak_rejects_a_duration_without_overlap_margin(self) -> None:
|
||||
cli = self.runner.parser()
|
||||
args = cli.parse_args(
|
||||
[
|
||||
"--expected-stt-provider",
|
||||
"local_whisper",
|
||||
"--expected-stt-model",
|
||||
"small",
|
||||
"--expected-tts-provider",
|
||||
"melotts",
|
||||
"--expected-tts-model",
|
||||
"melotts-korean",
|
||||
"--microphone-device",
|
||||
"Physical Microphone",
|
||||
"--duration-seconds",
|
||||
"3000",
|
||||
]
|
||||
)
|
||||
with (
|
||||
patch.object(cli, "error", side_effect=ValueError) as error,
|
||||
self.assertRaises(ValueError),
|
||||
):
|
||||
self.runner.validate_args(args, cli)
|
||||
error.assert_called_once_with(
|
||||
"--duration-seconds must be >= 3120 for a production physical soak"
|
||||
)
|
||||
|
||||
def test_public_url_injects_session_without_changing_target_metadata(self) -> None:
|
||||
raw_session_id = "private-session-id"
|
||||
url = self.runner.with_session_id(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue