Independent product · Voice AI + backend

A voice system that only confirms what really happened.

DentSignal connects calls, speech, booking, records, and handoff without hiding failed work.

My work
System design, backend, voice orchestration, reliability, operator experience
Core stack
Python, FastAPI, PostgreSQL, React, voice and telephony integrations
Evidence
Real interface; synthetic fixtures; historical bounded regression runs
Status
Independent engineering work—not a client deployment claim

One call, without the architecture wallpaper

The useful path is the one the bytes actually take.

Patient traffic uses Azure ACS. The Telnyx lane was a separate no-PHI sales/self-call experiment. They are intentionally not drawn as one magical telephone cloud.

Caller → Azure ACS → FastAPI bridge ↔ Deepgram → tool decision ↔ PostgreSQL → verified confirmation. Uncertain outcomes hand off; the historical no-PHI Telnyx test lane reaches the bridge separately.

Scroll to explore the map, or open the full-size workflow diagram.

Separate guarded lane: Telnyx → no-PHI sales/self-call smoke tests → same backend safety gates. Not the patient-call path.

Why these repairs are here

Three bugs exposed three trust boundaries.

These examples show how DentSignal protects call quality, honest booking numbers, and server memory. Each one pairs the broken behavior with the code that fixed it.

Repair 01 · Call audio

Do not send audio before the speech service is ready.

What was broken

Audio was downsampled too early.

The bridge forced higher-rate audio to 8 kHz and could send before the speech session was ready.

What changed

Preserve rate and wait.

Keep the source rate, buffer briefly, then flush only after settings are accepted.

What it fixed

No premature audio send.

An open socket is no longer treated as a ready speech session.

Broken
rate = 8_000
buffer_ms = 200
send(audio)
Fixed
rate = acs_rate
await settings_applied.wait()
send(buffered_audio)
What the bounded retest established

Settings acceptance now gates buffered-audio flush. Mocked provider paths and synthetic audio only; no claim about real PSTN jitter, room noise, listening quality, or production deployment.

Repair 02 · Booking numbers

Count booking success against real booking intent.

What was broken

The denominator changed the story.

Booking rate divided by every call and fixed multipliers looked like recovered revenue.

What changed

Definitions moved into one source of truth.

Use appointment intent as the denominator and label configured values as modeled.

What it fixed

The UI can no longer overstate what storage proves.

Labels, fields, numerator, and denominator now describe the same event.

Broken
booking_rate = booked / every_call
recovered = booked * 350
Fixed
completion = booked / appointment_intent
modeled_value = sum(call.value for call in booked_calls)
What the bounded retest established

Booking-rate definitions now stay tied to booking intent and basis labels. The current data model still cannot attribute a later booking to an original missed call.

Repair 03 · CSV uploads

Reject oversized files before reading all of them.

What was broken

The size check happened after the cost.

The route loaded the whole file before checking its 10 MiB limit.

What changed

Read only enough to decide.

Read the limit plus one byte before parsing.

What it fixed

Application memory now respects the application policy.

Oversized files stop with HTTP 413 before an unbounded read.

Broken
content = await file.read()
if len(content) > MAX_CSV_SIZE:
    reject()
Fixed
content = await file.read(MAX_CSV_SIZE + 1)
if len(content) > MAX_CSV_SIZE:
    raise HTTPException(status_code=413)
What the bounded retest established

The application reads only enough bytes to decide whether the file is over the limit. This supplements reverse-proxy limits; it does not replace edge enforcement.

Evidence boundary

Engineering proof, not customer proof.

Independent engineering work with synthetic evidence. No claim of clinic outcomes, production uptime, or certification.

What this demonstrates

Voice is a systems problem.

Next system

Acquisition AutopilotEvidence-ranked research with human-controlled action →