Built for a New York practice that treats substance use, and for 42 CFR Part 2, the strictest privacy rule in American healthcare. The clinician reviews and signs a transcript labelled by speaker, and substance-use records live in databases of their own.
A counselor sees clients back to back. The notes wait until the last one leaves, and the two o’clock session is written up at the kitchen table as the third note of the evening.
Nothing was recorded, so the record of care is a reconstruction: what the counselor remembers hours later, after two more sessions and dinner. The sector has a name for it, pajama-time charting, and that after-hours load is a known driver of clinician burnout.
The reconstruction is the document a court, an auditor or the next clinician will treat as what happened. In a practice that treats substance use it carries a second weight: under 42 CFR Part 2, nearly every disclosure needs the client’s consent, even one to their own doctor outside the program.
The practice needed both at once: a faithful record of each session, and privacy controls it could defend.
Spoken, and nothing recorded
A memory of a memory, filed as the record.
With the system, every step from consent to signature leaves a record, and the clinician keeps the final word.
| Step | Before | With the system |
|---|---|---|
| Consent | Nothing was recorded, so there was nothing to consent to | The client signs a standalone AI consent before anything records. It names the vendors and the 988 crisis line, and any change to it asks for consent again |
| Recording | The counselor listens and remembers | The browser records the session and sends the audio straight to secure storage, never through the app’s own server |
| Who said what | Rebuilt from memory | Deepgram returns the transcript labelled by speaker. A transcript without speaker labels is refused |
| The record | Typed from memory, hours later | The clinician plays back any segment and fixes a word or a speaker. The first draft and every edit are kept, with what changed |
| Signature | The note is signed as remembered | The clinician holds to sign, the transcript locks, and the signature is written to the audit log |
| Substance-use records | In most systems, one database with the rest of the chart, split by a flag | Their own databases and their own audio storage. An unclassified client is treated as protected |
Version 1.1.0. Please read this before signing, and ask your clinician any question about it.
This is a draft. Edit anything that needs your touch. When it reads right, sign it at the bottom to add it to the record.
This transcript is locked. It can be read but not changed.
Press and hold until the bar fills. The download link works for 15 minutes, and the password opens the PDF.
I’d start by following one session through your practice, from the consent form to the signed note in the chart.
That shows which records fall under Part 2 and who may read each one, and those answers set the storage split and the access rules. The first version runs in the browser beside the EHR your clinicians already use, on infrastructure covered by your BAAs, and your privacy counsel reviews it before it records a real session.
Discuss a system like thisThe system is a sixteen-package TypeScript monorepo built as ports and adapters. Its domain core holds sixteen use cases, from capturing consent to purging audio, and does no input or output of its own.
Transcription, storage, records, sign-in, export and the audit log each sit behind a port with an in-memory fake and a real adapter. One contract suite per port runs against both, so the fakes obey the same rules as the vendors. Four run modes, from fully in-memory to real Cloudflare R2, Deepgram and Cloudflare Access, are chosen by environment variables in one composition root.
The linter enforces the dependency direction, from contracts to core to app, and a Next.js 15 app serves 18 routes. The planned move to services under a BAA, such as AWS Transcribe Medical, RDS and Cognito, is a new adapter and one composition-root line per port.
Sixteen use cases, from capturing consent to purging audio. No input or output of its own.
@transcription/coreThe prototype had to prove itself before anyone paid for HIPAA-grade infrastructure and BAAs, and the design had to survive that move without a rewrite.
Follow one synthetic session from the client’s consent to the chain that records it. The left edge of the drawing shows who acts at each step.
Nothing records until the client signs a standalone, versioned AI-use consent: plain English, the vendors named, the 988 crisis line, and a promise that nothing said trains an AI. An edit to the document raises its version and asks every client to consent again, so the consent works as a gate.
Each client is classified at intake, and the session opens in that class’s store, part2_db or non_part2_db, with its audio bound for the matching bucket. An unclassified client is treated as Part 2. shared_db holds the client registry and the meta-chain.
The browser records opus/webm and uploads it to R2 on a presigned URL, so audio bytes never pass through the application server. Deepgram Nova-3 fetches the file from storage and returns segments labelled by speaker. A response without speaker labels fails the use case: in a two-person room, who spoke is part of the record.
The clinician fixes a word or reassigns a speaker, and each edit is chained per transcript beside the machine’s first draft. Then they type their name and hold to sign: the transcript locks and becomes the record. Export is an AES-128 password-protected PDF on a 15-minute link, and the audio is purged within thirty days.
All thirteen session event types append to a hash chain, where each entry’s SHA-256 covers its sequence number, the previous hash and its own canonical form. Each store keeps its own chain, and a meta-chain in shared_db anchors both. The dashed arc is the check on every read: store and flag must agree, and a mismatch is written into the chain it protects.
The industry default for Part 2 is logical segregation: one database, a flag and discipline in every query. This practice treats substance use first, and more than half its clients are Part 2-protected, so a flag would guard most rows of every table.
AI-drafted clinical notes were the obvious demo. New York’s S.8484 bill welcomes AI for administrative work with consent, and bars AI from acting as a therapist or reading emotion; a note finalized without the clinician’s sign-off is a line this design never crosses.
Each row is a finding from review or browser verification, settled at its cause.
In a privacy system the lasting fix is a rule written down, so the same class of mistake cannot recur. Every row traces to an architecture decision record or the repository’s status log.
diarize=true became the primary adapter, with no change to domain code. The full accuracy benchmark became a gate before any pilot.type="button", which swallowed form submissions.non_part2_flag as the wall between them: the kind of boundary an engineer under deadline pressure crosses without noticing.audit.tamper_signal.The system takes a session from the client’s consent to a signed, locked transcript, with substance-use records stored apart and every step in a tamper-evident log.
A version for your practice keeps that machinery, moves it onto infrastructure covered by your BAAs and adds the Part 2 controls your records need. Your privacy counsel reviews it before the first real session.
If your clinicians write notes at night and your substance-use records sit behind a flag, the work starts with one session traced from consent to signature. Bring your consent form.