The staff have their assistant. Now the patient at the kiosk and the patient on the phone get theirs, and the difference between the two is the whole design: the patient assistant sees public documents only, calls no tools, and is asked its questions through a rate-limited endpoint that never accepts an audience from the client. This part builds it on the kiosk and in the season-three app, and the screenshot that matters is the one where it refuses.

The kiosk at tablet size. Above, the check-in card with a six-letter code entry and a Check in button. Below, an 'Ask a question' panel showing the question 'What should I bring to my appointment?' and the answer in large type: Bring your appointment code and a photo ID. First-time patients should also bring previous prescriptions and reports. Then 'From: Patient information > Before your appointment', an Ask another button, and a footer saying the answer comes from the clinic's own computer and is not medical advice. Kiosk, a public question
The same kiosk panel with the question 'What is the internal rate for home sample collection?' and the answer in large type: I don't know that; please ask reception. No source line. Kiosk, a staff-only question
Two questions at the kiosk. The first is answered from the public patient information page with its source shown. The second asks for a number that exists only in a staff document; Part 7's staff assistant answered it, and the kiosk cannot, because the query that fetches passages for a public question never sees that document. The refusal is the fixed sentence, with no source line, by rule.

One endpoint, with the audience decided by the server

The Pocket API from season three gains one route, a POST that takes a question and streams the answer back as plain text. The endpoint writes the audience itself, "public", and the request contract has no field for it; a client cannot ask to be staff. No tool is ever attached. Questions must be between 3 and 300 characters, and the built-in rate limiter allows ten per minute per address, which is generous for a person and enough to stop a script from turning the clinic's GPU into a public utility. The tenth request in a minute passed and the eleventh returned 429 in the live check.

The kiosk: giant type, one question, then reset

The kiosk runs inside the main application, so it calls the assistant service directly, with the public audience, below the check-in card. The panel follows the kiosk rules from season two: type large enough to read standing up, one action per screen, an "Ask another" button, and a reset after sixty seconds of nothing so the next patient does not read the last one's question. The footer says, in words a patient can act on, that the answer comes from the clinic's own computer and is not medical advice.

The app: a screen and a longer timeout

The Pocket app's Ask the clinic screen at phone size: an explanation that answers come from the clinic's own computer and never leave the building, the question 'Where can I park?' in the box, a Send button, a 'Not medical advice' note, and the answer card: Two-wheelers park in the basement, and cars should use the municipal lot opposite the clinic, which is paid. There is no car parking on the clinic premises. From: Patient information > Parking. The tab bar shows Home, My visit, Waiting room, Find us, Settings.
The web host of the Pocket app, at phone size. The same shared screen serves the Android and Windows hosts from season three; the Android build was not exercised in this part and is noted as such.

The shared Razor library gets an "Ask the clinic" screen reached from Home; the tab bar turned out to be five fixed links rather than a data-driven list, so a button on Home was the honest change. The typed API client reads the streamed text as it arrives. One detail that would have bitten a real patient: the app's HTTP client has a ten-second timeout for its other calls, and a model answer can take longer, so the assistant call uses its own two-minute client. If the request fails, the screen says the assistant needs a connection.

The rule, and the test that proves it

docs/private.md says the patient assistant never sees a staff chunk, enforced in SQL and tested in xUnit. The test uses the fake embedding generator so the exact text of a staff chunk is the question; with the public audience the query returns nothing, and the service returns the refusal without calling a model. That is the test. The kiosk screenshot is the same fact at human scale. Seventy-three tests pass, thirteen of them new.

What went wrong

The first live refusal on the kiosk came with two source lines under it. The model had written the refusal sentence and then, obediently, a Sources line, and the client's "is this the refusal" check read the raw text rather than the text the patient sees. The rule says citation or refusal, never both. Both clients now strip the Sources line before deciding, and a regression test pins the shape. A rule in a document is a wish until a test reads it the way a user would.

Perishable facts, as of September 2026: ASP.NET Core's built-in rate limiter with a fixed window; the Pocket API remains unauthenticated by design, with the confirmation code as the credential for visit data and no credential needed for public questions. The sixty-second kiosk reset mirrors the success screen's proven pattern and was not itself photographed.

Model pick: the visibility rule, the server-decided audience and the rate limit were in the brief at high effort; the cheaper model built three surfaces in twenty minutes, and found the double-citation bug by looking at its own screenshot.

What the AI got wrong: the local model appended a source line to a refusal; the coding assistant checked the wrong text. Neither reached a patient.

The meter: a patient question costs the same as a staff one, one embedding and one generation, and the rate limit caps the worst case at ten a minute per address. The build meter accumulates for the retro.

Checkpoint: tag private-09 in the repo. Open the kiosk, ask what to bring, then ask for the internal home-collection rate; the second answer must be the fixed sentence. Next: does it actually work, in numbers.