A former tenant texted the AppFolio inbox about her deposit; Clara replied from her own line. Read-only inspection of every path where a tenant, former tenant, or unknown person can reach Clara, and the fixes.
Inspection done; when-to-reply re-architecture is Phase 3 of clara-lane-order-2026-10 (Fede's lane since Oct 23) · audit of main at 06c73d2e5f · 2026-10-23 (MT morning) · session 001
Rule going forward: Clara speaks only to a positively identified prospect or applicant, or to a tenant at a company whose tenant switch is on. A former tenant is a tenant. Unknown role means silence: no reply, no action, no team note.
8:57 AM MT: a former Western Slope tenant (Pomona Park, lease ended Aug 31) texted the company's AppFolio texting inbox about her deposit. Our copy of that inbox woke Clara. Clara replied from her own number (not AppFolio), emailed the leasing team a "could not answer" note, and closed the thread. Nobody turned tenant comms on. Kat answered the tenant in AppFolio at 9:31. The tenant is muted on every channel at Western Slope (undo: unmute, same identifier). The mirror fix is in a PR.
src/lib/domain/pms-mirror/file-message.ts:207, 303, 329)src/lib/domain/pms-doors/thread-party.ts:26, agents/clara/lib/messaging/dispatcher.ts:570-579)| Western Slope | Situs | |
|---|---|---|
| Tenancy records | 384 | 562 |
| People whose lease ended before today | 81 | 18 |
| … still marked active (the incident shape) | 72 | 15 |
| … already marked former | 10 | 3 |
Some stale-active rows may be real month-to-month holdovers. A check against AppFolio's own status was not done.
"Tenant" below means status-based (active or month-to-month). No path reads the lease end date.
| Path | Former tenant today | Unknown role today | Leak |
|---|---|---|---|
Text to Clara's line, maintenance stepinbound-dispatcher.ts:2121, property.ts:1496, 1714-1747 | Stale-active main tenant: work order + reply. Co-tenant or former: falls to the default lane | Clara converses | yes |
Text, default laneinbound-router.ts:783-806, identity/resolve.ts:918-1066 | Unknown (the incident shape) | Reply, by design: unknown = prospect | yes |
Mirrored AppFolio textingpms-mirror/file-message.ts:205-209, 303, 329 | Prospect, when anyone else shares the number | Reply (no "unknown" label exists) | PR in flight |
Phone call, caller lookuphandle-identify-caller.ts:283-400, 830-883 | Stale-active former co-tenant with name + unit = verified tenant, can file a work order | Reply + action + team note | yes |
Phone call, caller contextvoice/personalization/route.ts:949, 1925, 2866, 3252 | Stale-active gets full tenant context | Message desk takes a note | yes |
"How did it go?" rating textmaintenance/rating.ts:773 | Texted when their work order closes | n/a | narrow |
| Renewal / month-to-month notices | Not verified | n/a | module off at both |
Leasing or company mailbox, questionsprocess-inbound-message.ts:2344-2365, email-reply-scope.ts:65-105 | "Former" counts as prospect: full leasing reply | Reply as prospect; a failed lookup = prospect | yes |
Same mailbox, repair emailresident-repair-email.ts:51-74 | Stale-active = verified resident: reply + work order | Silent, filed | if switch = door |
Mail to Clara's own addressprocess-inbound-email.ts:1257-1401 | Skipped unless the building is switched on | Same | no |
Mirrored AppFolio emailguest-card-message.ts:515-568, 958-971 | "Former" with any old inquiry: woken as prospect | Silent | yes |
Listing-site / relayed leadsprocess-inbound-message.ts:2124 | Full prospect reply, no gate | Reply | yes |
First email to a new guest cardguest-card.ts:3384 | Skips the known-tenant guard; appears to get the email | Card = prospect | likely, not verified |
Text asking for a tenant's emailhandle-tenant-email-capture.ts:294-353 | Stale-active: captured + reply | Falls to Clara | narrow |
"Could not answer" team noteconversation-manager.ts:16295-16346 | Fires | Fires (no role check) | yes |
Which line the reply uses. By design, any tenancy (past included) and any unknown thread keep the text on Clara's own line; the AppFolio door is leasing-only unless maintenance.pms_inbox_tenant_door is on (absent at both companies). Email has no door. Once tenants and unknowns are silent, this only matters where the switch is on.
Fede, 2026-10-23: "this needs to be extremely air tight to never reply to tenants by accident, and we are going to be doing controlled testing of that (when to reply, when not)." Also: a guest card a staff member typed by hand never gets Clara (fix PR in flight).
One check. Every path (Clara's text line, mirrored AppFolio text, leasing mailbox, mirrored AppFolio email, phone call, listing-site lead, team note) asks the same function "may Clara speak to this person here?" before it wakes Clara. No path keeps its own answer. The matrix below is that function's spec and its test.
| Who reached us (one shared read) | Tenant switch off | Tenant switch on |
|---|---|---|
| Current tenant | silent file only | reply on the tenant door |
| Former tenant: ended lease, "former" status, or co-tenant on an ended lease | silent | reply same as tenant |
| Number shared by a tenant record and a prospect/applicant record | silent tenant wins | reply as tenant |
| Prospect from a listing site, website or phone intake (system-created card) | reply | reply |
| Prospect from a card a staff member typed by hand | silent | silent |
| Applicant | reply leasing lane | reply |
| Unknown: no record, or the lookup failed | silent | silent |
| Staff member, vendor, muted person | silent (vendor: vendor lane) | silent |
| Any of the above, a teammate spoke last on the thread | silent | silent |
Situs adds its listed lead sources on top of the prospect rows; Western Slope replies to every source. D2 (former tenant sending a real listing lead) stays open.
The controlled test, three rungs, in order.
| # | Question | Options | Recommendation |
|---|---|---|---|
| D1 | What is "the tenant switch"? | (a) the existing AppFolio-door setting · (b) the Maintenance module · (c) one new company setting "Clara talks to residents" that every path reads | (c): one switch, visible on the company page, default off. The door setting stays only for which line the reply uses. |
| D2 | A former tenant sends a real listing-site lead (Zillow) | (a) returning prospect, reply · (b) silent, team holds it | (a), on the lead path only: a listing inquiry is a positive prospect signal. |
| D3 | Build order | one PR per fix below | as ranked |
inbound-router.ts:783, inbound-dispatcher.ts:2095-2122).conversation-manager.ts:16295).email-reply-scope.ts:65-69, 103); the repair lane reads the switch (resident-repair-email.ts:63).rent-roll/apply-entity-sync.ts:232-348); then reconcile the 87 stale-active records against AppFolio, read-only.Not traced: gated-inbound-team-notice.ts, the full forward-to-team path, the sender address on the Clara-address email lane.