- Python 3.13+ with uv:
uv sync --dev --frozen, thenbash scripts/check.sh(tests, then pylint; fails fast). Run from the root because audio tests usetests/test_audio.m4a. Focused test:uv run pytest tests/test_security.py::test_text_contract_and_legacy_email. tests/conftest.pysupplies fake credentials, authenticated TestClient headers, Whisper stubbing, and fresh fakeredis per test. No model downloads or paid API calls are needed. Remove the client's Authorization header explicitly when testing unauthenticated requests.app/main.pymountsapp/api/analyze.py:/textis primary,/emailis a deprecated alias, and/wsaccepts complete clips rather than partial audio streams. HTTP bearer dependencies document auth;app/middleware.pyalso rejects invalid tokens before multipart parsing.- Live startup requires
DEEPSEEK_API_KEYandSCAMSHIELD_API_KEYS(comma-separated random backend tokens, each >=32 characters). Redis 7+ is required forEXPIRE NX; quotas are per token, shared across transports. Browser extensions need a user-authenticated gateway, not an embedded shared token. - Audio requires the FFmpeg executable, not a Python FFmpeg wrapper. Whisper loads lazily unless
PRELOAD_WHISPER=true; Compose enables preloading and persists its cache. Linux uses the explicit CPU PyTorch index inpyproject.toml; preserve it when updatinguv.lock. - Deployment uses
docker compose up --build -dafter configuring.env; seedocs/src/content/docs/guides/deployment.md. Keepscripts/serve.shWebSocket size/queue limits aligned with upload settings./readychecks Redis, not DeepSeek or model accuracy. scripts/smoke.pyruns via stdin inside a running test container (docker exec -i <container> python < scripts/smoke.py); it exercises real Redis/FFmpeg with mocked inference and consumes the test token's quota. Do not run against a production instance.docs/is an independent Astro/Starlight site: runnpm ciandnpm run buildthere. CI checks Python, docs, and the container smoke path; live model/provider acceptance checks remain separate.