Stage 4: honest health, explicit error policy, event-bus integrity #4
Reference in New Issue
Block a user
Delete Branch "feature/stage4-honest-health"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stage 4 of the architecture-review roadmap (stacked on #3). The theme: the system stops pretending — no silent mock fallback, no "healthy while doing nothing", no swallowed service errors, no silently evicted subscribers.
Explicit engine mode (F7)
USE_MOCK_SIP=trueis now the only way to get the mock engine. An unconfigured/placeholder trunk host without it makesbuild_sip_engineraise and startup exit with guidance — no more silent degradation to mock.default_factoryonly reados.environ, never.env— none of the 8 sub-settings classes declaredenv_file. All 8 now do (env_file=".env", extra="ignore"), soSIP_TRUNK_HOSTetc. actually load.Honest /health
Reports
engine: sippy|mock, a liveSELECT 1DB ping, trunk registration state with a reason, and TTS/STT availability from their last real request.healthynow requires ready + db ok + sippy engine + registered trunk; anything less isdegraded. Verified live: mock boot reportsdegraded/engine: mock/database: ok.Error policy (F7)
tts,transcription,llm_client) raise on failure and trackavailable; returning""/Falseon error is gone.hold_slayer,receptionist) catch, publishEventType.ERRORnaming the failed service, and apply an explicit per-call fallback — a down STT now surfaces as an error event, not "the AI deciding badly".persist_call_on_end,_persist_recording) get one bounded 3× exponential retry, then an ERROR log naming what was lost._get_llm→ sharedget_llm()singleton (kills receptionist's private cross-service import).Event-bus integrity (F6)
droppedcounter, escalating log) instead of silently evicting a live WS subscriber whose socket then stays open forever, mute.subscribe(replay_last=N)delivers the docstring's advertised history replay, respecting type filters;/ws/eventsusesreplay_last=25.Receptionist correctness batch (F9)
TAKE_MESSAGErule now beats the LLM (previously the LLM could override an explicit rule).finally.RecordingSessionfinally keeps itsleg_idsargument, so stopping a recording actually detaches its audio taps.Dead code removed
models/contact.py+ the Contact ORM table,dtmf_buffer(captured, never read),transcribe_streamTODO stub, and the fully stubbed SMS path innotification.py.Tests
New
tests/test_health_policy.py: mock-only-when-asked, unconfigured-trunk-refuses, overflow-drops-oldest-keeps-subscription, replay_last seeding, replay-respects-filter. Updated receptionist/services/concurrency tests for the new semantics. 127 passed + the 2 pre-existing failures on main (test_complex_tone_as_music,test_trunk_status).Live verification: booted with
USE_MOCK_SIP=true— honest degraded health as above, 401 without token / 200 with, clean shutdown with no destroyed-task warnings.🤖 Generated with Claude Code