How Clara should decide what a message is about, and when to stay quiet. For Gera and Fede, after the 10-27 call.
2026-10-27 · read-only audit of prod and code, plus a literature review · nothing changed yet
The collections bug is not the classifier. The check that decides whether Clara replies files "rent balance" under other, and other always sends. A bigger model would not stop it. The fix is to teach that check about money and make "unsure" mean "stay quiet".
248 real tenant messages, judged by hand against the conversation:
| Measure | Result |
|---|---|
| Overall, weighted by volume | 87.7% strict · 94% counting defensible calls |
| Leasing · maintenance · billing | 100% · 90% · 87% |
| General resident questions | 75% |
| Collections-like messages labelled as something else | ~1 in 7 |
Small samples, ±10–15 points per topic. Collections isn't its own topic today (it sits inside billing). The test suite has 102 cases and none for late rent or eviction.
Not as the main fix. Studies find a bigger model alone moves classification accuracy only a little, and the speed cost is real. Votes across several calls tell us more about confidence than model size does. Use the big model where it's cheap and it matters: the one reply-time check.
| Setup | Per month now | If today's spike lasted | Speed |
|---|---|---|---|
| Today (Haiku 4.5) | ~$9 | ~$78 | ~13s |
| Opus 5.5 for every label | ~$38–62 | ~$330–530 | ~20–60s |
| Cheap first, Opus only when unsure (~35%) | ~$23–29 | ~$195–245 | mixed |
| Opus on the reply-time check only | ~$0.004 per reply | needs a longer timeout | |
List prices, estimated from message sizes rather than measured. Opus speeds are estimates. "Classifying…" must clear in ~20s.
Stated confidence vs. sampling · Guaranteed error rates (conformal) · Models rarely abstain · Small fine-tuned vs. frontier models · Multi-intent messages · Intercom's escalation classifier · CFPB on chatbots · Claude API: no token probabilities
Code checked: the reply check's choices and its "rent balance → other" line are in classify-reply-topic.ts; supervised-reply-rule.ts maps "other" to no module, so it sends.