Clara as a coworker — architecture

A quick, high-level map of how Clara works alongside the property-management system, not inside it — what talks to what, what exists for staff, and where the gaps are today.

2026-09-27 · owner: Trinity · for Fede · every "built" claim is footnoted to a file, every "missing" claim is stated as such

Clara is a coworker, not a feature of the property-management system (PMS). The PMS — AppFolio today — stays the system of record: the lease, the ledger, the unit, the guest card all live there. Clara is a separate system of work that sits beside it: she answers the phone, the text line and the inbox, decides what to do, and writes the outcome back into the PMS so the client's own staff see it where they already work. She never replaces AppFolio's data model; she operates it, the way an employee would, through the one door the client already gave her (the browser robot) and a read API.

On this page

  1. What Clara is
  2. Diagram — the pipeline (channels to tools)
  3. Diagram — how a staff member reaches Clara
  4. Tools and capabilities
  5. Channel parity
  6. What's missing
Full document

The pipeline — channels to tools

Every channel lands on one identity check, which hands off to whichever engine owns the intent. Nothing crosses a company (org) boundary — a property belongs to exactly one org, and every line, calendar, mailbox and login attaches to an org or to a property inside it.1

ORG / PROPERTY WALL — every line, calendar, mailbox and login attaches to one org or one property inside it CHANNELS IN Phone / voice SMS Email Web form /AppFolio guest card Identity /resolverphone is the login ENGINE Leasing Maintenance Escalation TOOLS AppFolio read API AppFolio robot writer / outbox Microsoft calendars Knowledge base Tour slots Staff notices (email/SMS) CHANNELS OUT Same channelvoice / SMS / emailreply, plus a personvia the escalation leg
Left to right: four inbound channels all pass through one identity check, which hands off to whichever engine owns the intent — leasing, maintenance, or escalation. Each engine reaches the same shared tool set (AppFolio read, the AppFolio robot writer, calendars, knowledge, tour slots, notices); results go back out the channel the person used, or to a human when escalation fires. The dashed border is the org/property wall.

How a staff member reaches Clara

Internal employees use two surfaces: the web app (typed, for records and settings) and a phone conversation with Clara herself (voice or text, no typing UI). The two don't overlap much — staff read in the web app and talk to Clara for anything that needs a decision or an action.

Web app (typed) Prospects (leasing) · Conversations Work orders (maintenance) · Tenants Vendors · Calendar · Costs Settings (knowledge, policies, team) read + configure — no notes editor Staff talks to Clara ask-by-text + reply · tour alerts · paging Escalation / notice engine Writes into AppFolio one robot outbox, one writer guest-card notes, showings, assignment — same path whether triggered from no path from the web app straight to AppFolio
What exists: the web app's Prospects/Conversations/Work-orders/Settings pages (read + configure), and a direct SMS/voice conversation with Clara for escalation asks and replies, tour alerts, and paging. What doesn't: there is no unified inbox merging the channels for staff to browse3. Prospect and tour notes are captured by Clara from voice and text (staff tell her, or reply to a tour text) and written to the tour record and the AppFolio guest card — by design, there is no notes editor on the website (Fede, 2026-09-17).2

Tools and capabilities Clara has

CapabilityStatusEvidence
Read AppFolio (units, tenants, work orders, renewals, vendors…)BuiltRead API + browser-agent integration, dozens of read tools (e.g. appfolio.list_work_orders, appfolio.get_tenant_details)4
Write guest card / note / showing / vendor assignment (robot)BuiltOne robot write outbox, one writer5
Send application linkBuiltDedicated lambda + prospect follow-up flow6
Book / reschedule / cancel tours on real calendarsBuiltMicrosoft Graph calendar client + tour tools (leasing.schedule_tour, leasing.reschedule_tour, leasing.cancel_tour)7
Knowledge-base lookup (policy, property facts)Builtleasing.get_property_details, org/portfolio knowledge sections, voice knowledge gate8
Transfer / connect a caller to a personBuiltcomms.connect_caller, non-looping dial-target resolver9
Take a message / page a human on escalationBuilthandle-escalate-to-human.ts — every escalation pages a human, no silent tier10
Ask a staff member a question by text, and read the replyBuiltCompany-level switch, off by default; ask + reply-intent + release modules11
Staff notices (email / SMS) on bookings, renewals, escalationsBuiltNotice modules under domain/leasing/*notice*, delivered-event proof required12
Concession watcher (auto-flag pricing changes)Builtlambda/concession-watcher13
Prospect / tour notes capture (voice & text, no dashboard editor)BuiltNotes come from a voice or text turn with Clara and are written to the tour record and the AppFolio guest card; no notes-editor UI, by design2
Rating prompts after a maintenance visitPartialSetting + atomic claim exist on branches; not confirmed live on main at time of writing14
Self-guided / unattended toursMissingNo matching tool, handler, or lambda found in the checkout
Unified staff inbox across channelsMissingMarketing copy names it; no corresponding app surface found3

Channel parity

Filled from the tool catalog and channel-adapter status doc, not memory.15

CapabilityVoiceSMSEmailWeb-form / guest card
Greet / identify a repeat contact✅✅✅◐ card lookup only
Answer from knowledge base✅✅✅✗ no dialogue
Offer tour slots✅✅✅✗
Book a tour✅✅✅✗
Guest-card create / update✅✅✅✅ source, not target
Send application link✅✅✅✗
Hand off to a person✅ transfer✅ staff text✅ staff email✗
Take a message✅✅✅✗
Reminders / follow-up cadence◐ triggers, not carries✅✅✗
Staff notices✅ triggers one✅✅✗

Telegram is a real production channel too, but only as an SMS fallback and the team's own end-to-end test channel — it is not a customer-facing channel and is left out of the table above.15

What's missing

  1. Database-enforced org wall. Company isolation today is a filter in application code, not a constraint the database enforces — a documented, proposed-but-not-shipped redesign puts the org above the property as the real wall.1
  2. No unified inbox. Each channel (voice, SMS, email) has its own conversation record; there is no single screen merging them for a staff member to browse.3
  3. Web-form / guest-card channel is read-only for the prospect. A guest card can create or update a lead, but nothing dialogues back through that channel — the reply always goes out by email, text or a call.
  4. Self-guided tours don't exist yet. No tool, handler or lambda in the checkout supports an unattended/self-guided showing; every tour today is booked onto a person's calendar.

Footnotes

  1. Org/property wall, current state = code filter; proposed database wall: ~/.claude/propflow-docs/artifacts/portfolio-architecture-how.html ("what keeps one customer's data away from another's is a filter in our code, not a wall in the database" — status: proposed, pending Gera and Fede).
  2. Notes captured by Clara from voice/text, written to the tour record and AppFolio guest card; no dashboard notes editor, by design: ~/.claude/propflow-docs/artifacts/leasing-engine-designs.html#notes-field-audit; ruling in project memory feedback_notes_via_voice_text_never_website_2026_09_17.md (Fede, 2026-09-17).
  3. "Unified inbox" appears in marketing copy only: src/app/(public)/platform/page.tsx, src/content/home.ts; the design doc that would build it is still a brainstorming memo: docs/planning/channel-adapter-design.md. No corresponding app route found under src/app/(workspace)/(operations).
  4. Read integrations: src/lib/integrations/appfolio, src/lib/integrations/appfolio-api, src/lib/integrations/appfolio-browser-agent; read tool examples in src/lib/tools/appfolio.ts (e.g. appfolio.list_work_orders:619, appfolio.get_tenant_details:434).
  5. Robot write outbox: src/lib/domain/leasing/guest-card-write-back-outbox.ts, src/lib/domain/leasing/guest-card-outbox-writer-real.ts, src/lib/domain/leasing/guest-card-outbox-writer.ts.
  6. Calendar client: src/lib/domain/calendar/outlook-client.ts, src/lib/domain/calendar/provider/outlook.ts; tour tools in src/lib/tools/leasing.ts (leasing.schedule_tour:539, leasing.reschedule_tour:744, leasing.cancel_tour:844, leasing.book_tour:1132).
  7. Knowledge lookup: src/lib/tools/leasing.ts (leasing.get_property_details:43); src/lib/domain/leasing/knowledge/, src/lib/domain/portfolio/knowledge/, src/lib/domain/escalation/voice-knowledge-gate.ts.
  8. Transfer: src/lib/tools/comms.ts (comms.connect_caller:270); loop guard: src/lib/domain/properties/clara-line-loop.ts (firstNonLoopingDialTarget).
  9. Escalation always pages a human (ADR-0057): src/lib/tools/handlers/handle-escalate-to-human.ts.
  10. Staff ask-by-text: src/lib/domain/escalation/staff-ask-by-text-switch.ts (company-level, default off), src/lib/domain/escalation/open-matter.ts (sendStaffAskSms, openMatterAndAsk), src/lib/domain/escalation/staff-reply-intent.ts, src/lib/domain/escalation/reply-release.ts.
  11. Staff notices: src/lib/domain/leasing/team-notice-send-claim.ts, src/lib/domain/leasing/held-first-email-team-notice.ts, src/lib/domain/leasing/send-pending-notice.ts; delivered-event requirement in project memory feedback_staff_notices_on_needs_delivered_event_2026_09_17.md.
  12. Concession watcher: lambda/concession-watcher/handler.ts.
  13. Rating prompt: branch names only (feat/maintenance-rating-prompt-setting, fede/rating-prompt-atomic-claim) — not verified as merged/live on main during this pass.
  14. Channel status: docs/planning/channel-adapter-design.md ("Complete for the channels that still exist, as of 2026-09-19" — voice, SMS/Twilio, email/SES inbound wired; Telegram = SMS fallback + internal test channel; WhatsApp/iMessage externally gated, not built).
PropFlow Docs