- Voice realtime sessions — the OpenAI Realtime and Gemini Live WebSocket clients run for hours per session in production. A slow task / socket leak will not show up in a 30-second unit test, but pegs RSS within an hour of real traffic.
- Channel adapters — Telegram, Slack, and Discord all have rate limits that only bite once you have been chatting for a while. A back-off bug that re-tries too aggressively will cascade into 429s.
--runsoak pytest flag and the
@pytest.mark.soak marker, registered in feral-core/pyproject.toml
and feral-core/tests/conftest.py.
When to run
Local smoke check
The harnesses respect aFERAL_SOAK_DURATION_MIN env var so you do not
need to wait an hour to know they import cleanly:
[VOICE SOAK / openai] PASS: ...).
Expected metrics
Voice (tests/test_voice_soak.py / scripts/soak/voice.py)
Channels (tests/test_channels_soak.py / scripts/soak/channels.py)
Required env / secrets
Voice soak needs nothing — both peers are in-process fakes. Channel soak skips cleanly unless its env vars are set. In the nightly workflow these come from repo secrets:
Use personal staging bots in dedicated channels — never point the
soak at a production workspace, the 24-hour heartbeat will be very
visible.
Escalation path
The nightly workflow runs withcontinue-on-error: true so a single
red soak never blocks the morning’s regular CI on main. Triage steps:
- Pull the per-job artifact (
voice-soak-logsorchannels-soak-logs) from the failed run; the log contains the full pytest output and the one-line PASS/FAIL summary per test. - Voice failures — if
rss_growth_kbis the trigger, suspect a leaked task or unclosed WebSocket in the relevant client module (feral-core/voice/realtime_proxy.pyorgemini_realtime.py). Check recent commits to those files first. - Channel failures — if
auth_failures > 0, the staging bot token was rotated or revoked; re-issue and update the secret. Ifrate_limitedis the trigger, audit the adapter’s back-off logic inferal-core/channels/. - Open a release-impact issue tagged
release-impact:behaviorand page the on-call maintainer.
