| """End-to-end smoke test in mock mode — the PRD's gate: prove clean turns from |
| the full loop (stance -> catch -> witness line -> voice), and a full win. |
| |
| Runs with no GPU / no Modal (offline mock backend), so CI can assert the whole |
| game flow on every commit. |
| """ |
| from witnessbox.backends import get_backends |
| from witnessbox.engine import WitnessBoxEngine |
| from witnessbox.state import Phase |
|
|
| CATCH_LINES = [ |
| "The wire cleared on March 6th — before the board approved it on the 14th.", |
| "Anything over $5 million requires the CFO's sign-off, and your credentials are on the authorization log.", |
| "You were cc'd on Meridian's incorporation filing two years ago — Dana Voss, your colleague.", |
| ] |
|
|
|
|
| def _new_engine(): |
| eng = WitnessBoxEngine(get_backends()) |
| eng.start() |
| return eng |
|
|
|
|
| def test_five_consecutive_clean_turns(): |
| eng = _new_engine() |
| for i in range(5): |
| res = eng.take_turn(typed_text=f"Just asking a harmless question number {i}.") |
| assert res.witness_text |
| assert res.witness_audio is not None |
| assert res.status["turn"] == i + 1 |
|
|
|
|
| def test_full_win_path_and_voice_crack(): |
| eng = _new_engine() |
| last = None |
| for line in CATCH_LINES: |
| last = eng.take_turn(typed_text=line) |
| assert last.evidence |
| assert last.events.won |
| assert eng.state.phase == Phase.WON |
| assert last.witness_audio is not None |
| assert last.epilogue_audio is not None |
|
|
|
|
| def test_confident_clip_does_not_crash_turn(): |
| import numpy as np |
| eng = _new_engine() |
| audio = (0.2 * np.random.RandomState(1).randn(24000)).astype(np.float32) |
| res = eng.take_turn(audio=audio, sr=16000, typed_text="Were you in the building that day?") |
| assert res.stance.tier in {"CONFIDENT", "NEUTRAL", "HESITANT"} |
| assert res.witness_text |
|
|