Right now, 72 different places in the code decide, on their own, whether to email or text a client's team. We're replacing that with one door everything goes through.
Proposed — pending review. 2026-10-03 · design + local replay · numbers independently re-graded; judge noise is ±7 rows
Not at the bar yet. The three hard rules held on every replayed case. The overall pass rate is 88–94% against a 98% bar. One defect is left (below). Turning it on is safe but partial: only some notice types go through the engine so far.
| Check | Result |
|---|---|
| Real situations replayed (30 days, JP&Co + Western Slope) | 2,786 |
| Planted controls (known-bad must fail, known-good must pass) | 12 / 12 |
| No message → no team email | 100% (with fixes; 85–90% on main) |
| Never an error email to the client | 100% |
| Automated senders (AppFolio, do-not-reply) get nothing | 100% |
| Summary model fails → no email, one engineering alert | 32 / 32 (with fixes; main sent two alerts on 16 of 39) |
| Overall pass rate, graded engine notices | 88–94% (bar 98%) |
The one defect left: the short topic the AI writes for a callback subject is checked for shape, not meaning. It can contradict the message: "unlock issue" when the caller asked for a unit to be locked, or "question about rent" when the caller only asked to talk. Fix options are a decision for Fede: use the existing subject (name + home) for callbacks, or add a second AI check.
What the switch covers today: voice messages and handoffs, missed transfers, tour-day updates. Renter questions forwarded to the team, held first emails, person-asks, after-hours notes, application failures and the action reminders still go out the old way, even with the switch on.
| Situation | How | Result |
|---|---|---|
| Voice message | Real call | One email, delivered (SendGrid); old email did not send |
| Missed call, no message | Real call | Nothing sent ✓ |
| Renter question | Harness, prod send | Ask email, delivered |
| Held first email | Harness, prod send | Ask email, delivered |
| AI summary fails | Harness | No email, one engineering alert ✓ |



Fixes from tonight: subject topic #16434 (merged), #16491, #16512; engine #16481–#16485; harness #16500.
Today, 72 separate code paths each decide on their own whether to email or text a client's team — which is why a fix in one place never reaches the other 71, and why the team gets emailed about things it never should.
We're building one door: every notice is one of three outcomes (handled, ask, or handoff), written through one composer, with one record of what was sent. On the 79 real email cases that needed a notice in the last 90 days, today's scattered code passes 0%. The new engine passes 68% (and 78% of the cases that are actually its job to decide). This is graded honestly now — the same strict grader scored before and after, and an independent check confirms it.
It ships off by default. We prove it on hundreds of thousands of real past situations, then on one real client (Willows), and only then does Fede turn it on, client by client. The old code stays live until he does.
Email only for now. Texting and phone routing come later, on client request — see "Not now."
One path, start to finish. Every stage is shared across clients and channels except the two marked "per channel."
| Rule | |
|---|---|
| Shared | decision, recipient, facts, reply matching — one sentence of what the person wants, each fact stated once, no internal details, failures go to engineering only |
| Text | ||
|---|---|---|
| Length | one sentence + “Callback number: …” | one short line |
| Subject | yes | no |
| Link to the conversation | yes | usually no |
| Reply | “Reply here” | plain words, no menus |
| Timing | — | quiet hours |
One setting, teamNotifyEngine: property, then company, then off. The old 72 paths stay live until Fede turns the new engine on, client by client.
Rollout: local replays (5,736 real past situations) → Willows test property, proven live → Fede turns it on per customer → the old paths and the setting get deleted.
| Piece | What it is | Status |
|---|---|---|
| Scoring tool | 13 automated checks that grade a notice against the real case, with planted-bad-notice controls | In review |
| Core | the typed intent, the three outcomes, the quote fallback, the general-team recipient | Merged |
| Engine + record + setting | decides the outcome, writes the TeamNotice record, the off-by-default setting, matches staff email replies back | In review |
| Summary sentence | the model-written sentence plus its fact-by-fact check against the source | In review |
| Replay runner, part 1 | runs real past cases through the decision step | In review |
| Replay runner, part 2 | grades every case and produces the before/after numbers below | In review |
| Wording + stricter grader | fails filler words; closed the gap between the old and new engine's scores | In review |
| Email-only fallback | when there's no phone on file, shows Email: … instead of a callback number | In review |
Every situation Clara can't finish alone sorts into exactly one of these. Nothing else.
core.md, Fede's 10-03 ruling (email only, one team address per client).We made the grader stricter (filler words now fail), and the engine caught up.
| Pass / 79 | |
|---|---|
| Old engine, old grader | 54 |
| Old engine, stricter grader | 12 |
| New engine, stricter grader | 51 |
Of the 28 misses: 14 the judge wanted more detail than the brevity rule allows, 4 small wording misses, 10 nothing was sent (being investigated).
First names and addresses below are placeholders, not real customers. The "after" side is shown as the actual rendered email: subject in bold, then the body.
Amy D. — left a message at 123 Example Street
Amy said: “Uh, something else. Application. Speak to a representative. Set up a callback.”
Amy D. — question about an application
Amy D. wants to talk to someone about an application at 123 Example Street.
Callback number: (555) 010-0142
Property: not identified yet Natasha called. The office was closed (after hours). Caller named Natasha is interested in renting out her house and having the property management company manage it for her. She is calling from the number ending in 0142. Office was closed when she called. Called at 9:45 AM. Can someone call Natasha back? (555) 010-0142 Clara
Natasha — wants to rent out a house
Natasha wants to have a house managed as a rental.
Callback number: (555) 010-0177
Prospect has arrived — Example Townhomes Jed Hammond has arrived for his 9:00 AM tour of Unit 405. Prospect: Jed Hammond Phone: (555) 010-0142 Tour: Thu, Oct 1 at 9:00–9:30 AM Unit: 405 Prospect detail: [link] — Clara by PropFlowAI
Taylor P. — here for a tour at 12 Test Street
Taylor is here for the 3:15 PM tour.
PROPFLOW · FORWARDED BY CLARA From: Unknown Status: Prospect Property: Example Apartments Intent: Lease info Why forwarded: Prospect asked about co-signer/guarantor acceptance — not covered in property data. Summary: Prospect interested in a studio wants to know if co-signers or guarantors are accepted. Message: Tomorrow, anytime, works for me. What would be the estimated move-in costs with everything included on studio?
Steven F. — question about 12 Test Street
Steven asked: “What would be the estimated move-in costs with everything included on the studio?”
Reply here and I'll get back to Steven.
Each notice can go by email or text. Text versions come with the text channel, next after the email side merges.
The "ask" outcome only matters if a real staff reply makes it back to the renter. Today it mostly doesn't.
Texting already closes the loop because it's one thread. Email doesn't yet — this is exactly what the new engine's reply-ingest step fixes before it goes live anywhere.
Recommendation: yes. Today that renter reply sits silently in the thread and the team can miss it; one short email ("Jordan replied — [link]") costs nothing and nobody has complained about getting too many of these. No other change to how takeover works.