IRON LAKE

Product · Private practices

Riley

An AI revenue agent for private practices. It answers every inquiry the practice receives, works out who the person already is, and hands the front desk one decision instead of an afternoon of tab-switching.

Running today in a multi-location aesthetics practice.

The problem

1. The money leaks between the click and the chart.

A practice runs ads, has a website, and books patients in a practice management system. None of the three talk to each other. So nobody can answer the two questions that decide the marketing budget: which spend produced a patient, and how many people asked for an appointment and never got one. The gap between a click and a booked chart is where the revenue goes, and it is invisible in every system the practice already owns.

2. Speed decides the outcome, and nobody is watching the clock.

Someone fills in a form at 2pm wanting to know about a treatment. If the practice replies within the hour, they usually book. If they reply tomorrow, that person has already called somewhere else. Most practices find out about the inquiry on a nightly report, which is to say after the decision was made without them.

3. And the obvious fix is the dangerous one.

"Let the AI book the appointment" is one prompt injection away from a stranger writing into a clinical system, and one bad match away from two charts for the same person — which splits a patient's medical history in half and can go unnoticed for months. The answer is not a better model. It is a gate.

What Riley actually does

Four jobs, in order.

Sees everything
Connects the practice management system, the website forms, and the ad and search accounts into one tenant-isolated warehouse. Every record lands verbatim and is never overwritten, so the history is an audit trail rather than a snapshot.
Knows who they are
Resolves an inbound inquiry against the practice's own patient roster before anything else happens — by email first, then phone, because an address is personal and a phone number is shared across a household. If more than one record matches, it attaches nothing and asks a human. Guessing here is how a chart gets attached to the wrong person.
Puts it in front of staff
An inbox ordered by what is waiting, with the age of every inquiry on the row and a visible clock against the practice's own response target. One obvious next action per lead. The promise a patient was made is shown where it is kept.
Acts, once a human says so
Checks live availability against the practice's real calendar, then books. That last step is gated, audited, and idempotent — a retried request returns the original attempt instead of booking a patient twice.

How the gate works

Riley is not a prompt with tools attached. Every unit of work is a declared capability that states its own authority before the system will let it run — what it touches, what data classes it may see, whether a person must approve it, and whether the effect is safe to retry.

;; every unit of work states its authority before it may run
(capability book-consultation
  (kind          act_external)
  (risk-class    high)
  (approval      operator_required)
  (phi-classes   (limited_phi))
  (redaction     staff_safe_summary)
  (idempotency   required)
  (side-effects  (creates_appointment))
  (metrics       (booked_consults)))

;; omit any line and the plan will not lower into a saga.
;; undeclared is unrunnable.

The declaration is the enforcement. A capability that has not named its risk class, its data classes, and its approval requirement cannot be lowered into an executable plan, so it cannot run at all. A model never inherits authority because a prompt asked nicely.

Anything that can affect the real world ships switched off and returns a refusal until someone with authority turns it on:

;; what a refusal looks like. the write path ships OFF.
$ POST /schedule/consultations

{
  "status":     "disarmed",
  "attempt_id": "bk_9f2c04ab...",
  "message":    "The booking write path is disabled.
                 The request was validated and audited;
                 no appointment was created."
}

;; the audit row is written BEFORE any external call,
;; because the failure that matters is the one where
;; we acted and cannot account for it.

Under Riley

Three layers, one product.

A practice buys one thing. Underneath it, the data layer handles ingestion, identity resolution and the warehouse; the control plane compares what the practice wants against what is observed and emits the difference as typed, approvable work; and the agent carries the practice-specific protocols — frozen, tested, versioned — that decide what good operation looks like in this speciality. Each layer runs isolated per practice.

What is running, and what is not.

Ingestion, identity resolution, the change feed, the triage inbox, live availability reads and the audit trail run in production today. The clinical write path is built, tested, and disabled by default — arming it is a decision with a signature attached, not a deploy flag. The general substrate this is being extracted into is research in progress and is not claimed as shipping.

Run a practice?

We are taking a small number of practices in 2026. If you spend on acquisition and cannot say which spend produced a patient, that is the conversation.