Clara as a coworker — the staff loop, v2

How Clara asks the team for help, hands a customer to a person, and understands what staff write back. Honest state first, then a phased plan where each phase is gated by the previous phase's proof.

Proposed — pending Fede's decisions (2026-09-28) · Evidence: staff loop review (Steven / Kat, Western Slope, 9/27–9/28) · QA script: Fede-as-Kat at Willows

On this page
  1. Where we are
  2. The model
  3. What bit us before: real cases
  4. Architecture
  5. The judge: model and tuning
  6. What the data says
  7. Staff with two numbers
  8. Phased plan
  9. Who gets the hand-off
  10. Prior art: how others hand off to humans
  11. Switch cleanup (2026-09-29)
  12. Decisions for Fede
  13. Not doing
  14. One reader for everything staff write to Clara (2026-10-27)

Bottom line: the staff side of Clara is buggy today. It was built for one kind of escalation ("ask the team, save the answer") and never exercised, because Camellia staff never replied to Clara. Western Slope is its first real use, and the first real reply (Kat: "I called them") broke it. The fix is four phases, each gated by the previous phase's proof (harness green, QA pass); Fede can turn it on at Western Slope once Phase 2 passes, then it bakes on real traffic. What limits speed is judgment and testing, not typing.

PhaseWhatGate
0Stop the bleeding (bug fixes, live)none
1The two paths (dark)Phase 0 green
2Prove it (harness, Fede-as-Kat QA)Phases 0–1, corpus mining
3Staff memory (dark)Phase 2 baked

Nine decisions for Fede

1. Where we are (honest)

Seven defects, all seen on one real thread. Four are code bugs. Three are wrong assumptions in the design, which is why patching keyword lists will not hold.

#DefectWhat Kat (or Fede) sawRoot cause
1A keyword list decides what a staff reply means; only two outcomes, "answer" or "question""I called them… will find out when someone will be down there" was read as a questionwrong assumption every reply is an answer or a question
2Clara answers staff by running the customer's own conversationGot a reply written to Steven, not to her; her words landed in Steven's threadwrong assumption customer thread doubles as staff thread
3Fixed re-ask wording ("So — what should I tell them about…?")Asked again after she said she had itbug
4Expiry guessed from dates in the question text, and only runs at two test propertiesAn ask about a finished 10:00 tour stayed openbug + wrong design (not linked to the tour)
5Nags never stop because someone took it; the "human owns it" state exists but nothing enters itKept getting reminderswrong assumption "takeover is rare" built as "never"
6Clara escalated something she could answer (company video-tour link)Pulled into a question Clara had the answer tobug no "can I answer this myself?" check
7Conversation page labels Kat's reply "Staff asked Clara"; nothing shows that staff repliedFede only noticed Kat replied by accidentbug label ignores direction; matter owner not shown
2. The model

Most important rule: escalation is about a matter, never the person. Clara keeps helping with everything else; she never brings up the pending matter unless the customer does.

"The team is still looking into it" is said only when the customer re-asks about that same matter and it's truly still open. Once staff answered, the tour moved, or the topic is over, Clara never mentions it again — no per-turn reminders. Real past transcripts where Clara got stuck or kept repeating that line become harness fixtures.

What bit us before: real cases

14 real cases in 9 conversations (12 Camellia, 2 Western Slope) were pulled from production to build this model.

Case / PropertyDateWhat Clara didWhat a human would do
Voucher answer walked back, Camellia2026-08-28Two minutes after correctly telling a prospect vouchers are accepted, Clara took it back and said she had no answer on file."That's great — go for it. And yes, we accept housing vouchers, so you're all set to apply."
Repeating the same line, Camellia2026-08-28Clara said "I've checked with the team... I'll follow up tomorrow either way" three times in six minutes, even after the prospect said "no need to repeat.""You're welcome!"
Silence at the door, Camellia2026-08-29A prospect standing outside asking for the entry code got no reply, because an unrelated open promise had the whole thread on hold. He had to call in."It's [code]. Enter it at the main entrance, and the office is on the right."
West-facing unit question, Camellia2026-09-03A prospect who had moved on to touring a specific unit still got "still no word on the west-facing / floor 3+ question" tacked onto four unrelated replies in a row.Just book the tour and let him in: "See you at 4:45. The buzz code is [code] and the office is on the right."

Three causes, in plain words:

  • A fixed sentence about "waiting on the team" gets added to every turn while a matter is open, and nothing records that it was already said — so Clara repeats it even after the customer asks her to stop.
  • A hand-sent answer from a staff person never closes the question in Clara's eyes, so she keeps treating it as open and can walk it back.
  • Putting a thread "on hold" blocks every message on it, not just the ones about the pending matter — so an unrelated question, like a door code, goes unanswered too.

These fixes are shipping as bug fixes, live, no gate; the 14 cases above are now permanent test fixtures so they never come back.

The unit is the matter: one thing Clara is stuck on for one customer. When stuck, Clara judges which path applies using reasonable defaults, never a hard-coded list. Hand-off: a person must act (show up, get on a call, sign, negotiate, calm someone down). The guest card is assigned to that person, Clara steps back, no nags. The customer hears only Clara's own follow-up line. Knowledge question: a policy, process or price Clara lacks. She asks, keeps serving the customer, and saves the answer to the knowledge base with who said it.

 Clara handles the customer
        │  stuck
        ▼
 ┌─ judge (defaults, not a list) ──────────────────────────────┐
 │ knowledge q.    → ask team ──► WAITING_ON_STAFF (one reminder) │
 │ hand-off        → assign card to person ──► HUMAN_OWNED     │
 └─────────────────────────────────────────────────────────────┘

 staff reply on WAITING_ON_STAFF, judged by meaning:
   answered        → relay to customer + save to KB  → RESOLVED
   has it          → thank once, stop nags           → HUMAN_OWNED
   question back   → answer in the STAFF thread      → WAITING_ON_STAFF
   declined        → tell customer Clara's own line  → RESOLVED
   out of office   → ask the next person in chain    → WAITING_ON_STAFF
   unrelated       → no transition, no re-ask

 HUMAN_OWNED  → back to Clara only when the customer writes again
 any state    → EXPIRED when the linked tour / appointment has passed
One matter, three owners over time: Clara, "waiting on staff", or a named human. "I've got it / I called them" means human-owned on either path. A hand-off is never saved as policy.

After a hand-off

No staff typing as Clara, no new staff screen.

While waiting on staff

One reminder per matter, ever. If the prospect asks again, Clara tells them the team is still looking into it — she does not re-ask staff.

If the answer was already in the knowledge base or settings, Clara was never stuck; a case like that is a red harness case against her answering, fixed there, never routed.

Rules kept from earlier rulings: staff talk to Clara like a person, over email first, with no new staff screen. Clara keeps working while she waits. She never promises on a named person's behalf. Staff answers become property policy directly, with provenance. No review queues, no engineering flags.

3. Architecture
ENTRY POINTSEVENTSREADSOUTPUTSEmail from staffor prospectText from staffor prospectAfter a phone call9 AM reminder job(questions stillwaiting on staff)Other events(staff replied, tourtime passed, customerwrote again)Staff texting Clara(book, move, cancel,tour notes)eventeventeventeventeventeventStaff loop engine = one Temporal workflow per matterstays alive after a hand-off, until the matter is doneState + ownerClara · waiting onstaff · a named personEvent historyevery event keptOne remindera timerSTEPS IT RUNSJudge stuckask or hand offJudge staff replysix outcomesLook up ownertask → role → personAssign guest cardin AppFolioMessage staffthe hand-off packetOne line to customerno nameSave knowledgeanswer + who said itWrite the matter recordcopy for the screensOne directory holds the workflow, its events, its timer and its stepsTeam page (roles → people)Company / property settingsHuman in the loop, default personAppFolio guest card assignedText / email to staffOne line to prospectKnowledge base entryMatter record (for the screens)Harness + eval set52 real cases + 24 variations · gate on every PR
One workflow per matter. Six entry points deliver events into it; it keeps the state, the owner, every event and the one reminder, and runs the steps that make five outputs. The harness gates every change.

Temporal is the engine we already use to keep long-running processes, such as a booked tour, alive for days and wake them when something happens. The workflow stays alive after a hand-off, so while a person has the matter we still know who owns it and keep every event. This extends today's escalation-matter workflow rather than starting a new one, the same pattern the renewals process already uses.

Where the code lives: one directory holds the workflow, its events (signals), its timer and its steps (activities). The matter row in the database is written by the workflow, as a copy for the screens to read. Every entry point feeds the one workflow; nothing keeps its own copy of a decision (Fede's rule, 2026-09-28). Once the timer owns the reminder, the 9 AM reminder job goes away.

4. The judge: model and tuning

The two judgments (stuck, and what a staff reply means) are LLM calls to Claude. They run only when Clara is stuck or when staff reply, a few calls a day, so quality matters more than cost.

Judge model: decided 2026-09-28

ModelReproduced incidents (25)Other real cases (17)Decisions filed as questionsClears the bar
Sonnet 5.525/2517/170yes, picked
Sonnet 525/2516/170no
Opus 5.525/2517/170yes, costs more
Haiku 4.525/2516/170no

The bar: 100% on the reproduced incidents, at least 95% on the rest, and zero decisions swallowed as questions.

Sonnet 5's one miss sent an application-process question to a person instead of treating it as a fact question, the safe direction.

The judge is not called from the live path until the hand-off step routes on its verdict; a compute-and-log-only mode was rejected as shadow mode.

Today's default for replies: Clara's email and text replies to prospects use Sonnet 5 (claude-sonnet-5, the drafting tier in model-tiers.ts, high effort); other turns use the general tier, Sonnet 4.6.

How we tune it

Prompt shape

  1. The matter: who the customer is, what they asked, what Clara already said.
  2. The staff text, verbatim.
  3. The outcomes, each with a one-line definition: two for the stuck judge (knowledge question, hand-off), six for the staff-reply judge. Pick one with reasonable defaults, never a keyword list.
5. What the data says

52 real cases where Clara asked for help: 26 written questions and 26 missed-call callbacks. Most are from Camellia in August; 3 are from Western Slope. Test runs are counted separately.

Why Clara asked (26 written)

ReasonCountShare
A fact she should have had (knowledge, listing, standard process)1454%
A person's judgment, an exception, or a wrong document831%
Customer asked for a human28%
Clara promised something she couldn't do14%
Vendor message14%

What staff did (same 26)

Staff responseCountHow Clara handled it
Client staff answered through Clara's reply loop0Never happened at a real customer
PropFlow operator answered, typing as Clara9Fine for the customer; answer never saved as knowledge
Client staff answered the customer directly3Clara never saw it; kept forwarding
Staff said "I've got it"1Read as a question; Clara replied to the manager as if they were the prospect
Live transfer connected1Fine
No visible reply ever12one reminder, then silence or a quiet close

Key numbers

MeasureValue
Avoidable (answerable from knowledge, listing or process)14 of 26 (54%)
Never answered by anyone, visibly12 of 26 (46%)
Customer left without an answer10 of 26 (38%)
Missed-call pages with a recorded callback0 of 26
Median time to first human reply, when one cameabout 6 h (11 cases; 9 by PropFlow operators)
Real staff replies that followed a reminder0

The paths

ReasonStaff responseWhat Clara didWhat a coworker should doVerdict
Fact she should have hadanyForwards, says "the team will follow up"Answers from knowledge; if truly missing, asks once and saves itWRONG
FactAnsweredRelays onceRelays and saves as a property factMISSING
Judgment or documentNever repliedone fixed reminder, then silent closeReminds against the customer's deadline, tries a second person, tells the customer honestlyWRONG
Judgment or documentReplied from own mailboxDoesn't see it, keeps forwardingTreats the mailbox reply as the answer and closesMISSING
anyCustomer writes again while waitingForwards every message, tells the customer nothingGives a status line, answers what she knows, recognises "done"WRONG
any"I've got it"Treats it as a question or answerMarks it human-owned, stops remindersWRONG
anyOut of office / "let me check"Would relay it as the answer (offline test)Keeps waiting, routes to backupWRONG (test only)
ExceptionDeclined with an alternativeRelays bothSameOK
anyStaff asks backAnswers from records, stays openSame, with a cap on roundsPARTLY
Complaint or policyAnswer relayed, customer pushesTook back the approved answerHolds to the approved answerWRONG
Asked for a human (phone)Transfer unansweredOne email per call, no callback trackingOne page per caller, callback window texted, tracked to doneMISSING
Vendor or billing voicemail–Pages the leasing inboxRoutes billing to billing, property calls to the ownerPARTLY
Staff's own question–Escalates it back to staffAnswers from records or says she can'tWRONG (test)
Plain tour request–Escalates itBooks itWRONG (test)

Top 5 wrong cells

  1. Facts she should have had get forwarded instead of answered (14 real).
  2. No reply from staff: one fixed reminder, then a silent close; the customer is never told.
  3. Customer writes again while waiting: every message forwarded, customer gets nothing.
  4. "I've got it" or out-of-office is read as an answer or a question.
  5. Missed calls: one page per call, no callback tracked (0 of 26).

The 10 most instructive real threads are saved, scrubbed, as harness fixtures.

6. Staff with two numbers

The case. Kat texted Clara from her personal cell and Clara did not recognise her. On 9/20 someone entered Kat's work number (the office landline) in the team page's single phone field. The code treated that field as "replace": saving the work phone replaced her mobile and retired it. The landline receives texts but cannot reply.

The model: two labeled slots

SlotWhat it isKat
Work phoneThe number on the team page; callers and the office line. May be a landline.…8394 (landline, cannot reply)
Mobile / personalA phone that can text back.…8120 (Clara texts here)

In storage terms: two live number records on the person, each labeled work or mobile; the existing "primary" flag means "text me here".

What exists today

PieceToday
StorageEach number is a record on the person with a primary flag (the number Clara texts) and a retired flag. Several live numbers are allowed; there is no work / mobile label.
RecognitionReads all live numbers, so a second live number is already recognised as the same person.
Team page / self-service saveroot cause one phone field; saving the work phone replaced her mobile and retired it.
Tour check-in askTexts the primary; its thread is keyed by that phone, so a reply from her other phone lands elsewhere.
Staff tour-alert textsGo only to the mobile typed on the opt-in row.

PRs

PRChangesShips
1Saving the team-page phone never retires the number already on file: the saved number becomes the one Clara texts, and the old one stays live as a backuplive (bug fix)
2Team page gets two fields, Work phone and Mobile, each saved on its own; Clara texts the mobile when there is onedark
3Optional: the check-in ask texts the number she booked from, and joins replies from either of her numbersdark

No landline detection. Nothing beyond the two slots.

No conflict with Gera's portfolio model: both numbers live on the one person record in the company. Caveat: recognising her by an old, already-retired number company-wide needs a company-wide staff role.

7. Phased plan

Every row is one PR, one concern, about 300 lines or fewer, with a harness fixture and a mutation control (plant the bug back, the check goes red). Each phase starts when its dependencies are merged and proven. Bug fixes ship live everywhere; behavior changes ship dark behind a property setting, default off, and Fede turns them on.

Phase 0 — stop the bleeding

For Kat: "I called them" ends the reminders. Her questions get answers addressed to her. Asks about a past tour close on their own. The conversation page shows she replied and who owns the matter now.

PRChangesDepends onProof (+ mutation control)Ships
0.1Wire the "human took over" transition; 9 AM reminder job skips human-owned matters—Kat replay: zero reminders after takeover (control: remove the skip → red)live
0.2Staff reply read by a model step into the six reply types; replaces the keyword list0.1Kat's reply → has it (control: put "find out" back as a rule → red)live
0.3Answer staff questions in a staff context, never through the customer's conversation—Zero writes to Steven's thread (control: route via customer thread → red)live
0.4Re-ask only after a real question back0.2No re-ask on "has it" (control: always re-ask → red)live
0.5Matter expiry on for all properties (drop the test-only list) and linked to the tour record—Matter on a finished tour → expired (control: restore date parsing → red)live
0.6Clara sends the company video link herself, including around a tour already in progress—10:39 question on a 10:00 tour gets the link, no escalation (control: drop the rule → red)live
0.7Conversation page labels by direction and intent ("Kat replied to Clara", "Kat asked Clara", "Clara answered Kat", "Clara asked the team"), drawn from the matter's own transitions; shows who owns the matter now0.2 (0.3 makes it correct at the source)Rendered label on the Kat thread (control: label by sender only → red)live
Gate: none; bug fixes, each ships live when its harness fixture and control pass.

Phase 1 — the two paths

For Kat: when a customer needs a person, the guest card lands on her name in AppFolio with one email, and Clara stops talking about it. She is never asked the same kind of question twice once she has answered it.

PRChangesDepends onProof (+ mutation control)Ships
1.1Escalation-time judgment: knowledge question / hand-off (an answer already in knowledge or settings is a bug in her answering, not a third outcome), from defaults (presence, signing, negotiation, upset → hand-off; policy, process, price → question)0.2Steven question → hand-off, never a knowledge question (control: force "question" → red)dark
1.2Staff person → AppFolio user map, pulled from AppFolio (none exists today)—Kat maps to her AppFolio user at Willows (control: blank map → red)dark
1.3Default hand-off person per property, a property setting on the property page1.2Setting read back on the pagedark [superseded 2026-09-29, see decisions]
1.4On hand-off, assign the guest card to that person (the assign write already exists); re-assign to whoever says "I've got it"1.2, 1.3Card owner changes at Willows (control: skip assign → red)dark
1.5Hand-off opens human-owned directly: one email, no nags, one customer line from Clara, no name0.1, 1.1One staff email, one customer line, zero nags (control: open as waiting → red)dark
1.6Centralize: one generic matter engine for all modules (module + subject record; leasing first, renewals/maintenance/collections add routing rows) — the refactor task1.1–1.5Leasing runs on the generic engine, no leasing-only code path left (control: hard-code leasing → red)dark
Gate: Phase 0 fixes merged and green on the harness; 1.2 and 1.3 before 1.4.

Phase 2 — prove it

The harness first pass (a results table, each case red/green on main) gates Fede's own QA as Kat; Fede does not test until that table is green.

For Kat: nothing changes until the replays and Fede's own run as Kat pass. Then she gets the Phase 1 behavior at Western Slope, with staff-driven relays reviewed until they are proven.

PRChangesDepends onProofShips
2.1Ten corpus threads as fixtures on the coworker harness (extension already in progress)corpus mining, 0.x, 1.xAll ten green; each with a planted-bug controltest only
2.2Fede-as-Kat QA at Willows (real email, real guest card)2.1QA checklist on the go-live tracker, with permalinkstest only
2.3Review gate on relays triggered by staff replies at Western Slope, until baked—Held relay appears in the review loopsetting
Gate: Phase 0 and 1 merged, corpus mining done; then bake on real Western Slope traffic.

Phase 3 — staff memory

For Kat: she can go back and forth with Clara over several messages, like a coworker who remembers yesterday's conversation.

PRChangesDepends onProofShips
3.1A Clara ↔ staff conversation per staff person, with its own memory; the matter is the shared object0.3Staff transcript never touches the customer's (control: shared store → red)dark
3.2Staff replies routed into that conversation; Clara uses its history3.1Multi-turn replay recalls an earlier answerdark
3.3Staff ask-back rounds: several questions both ways on one matter3.2Three-round fixture resolves correctlydark
3.4Multi-turn harness fixtures3.3All green with controlstest only
Gate: Phase 2 proven and baked, and real multi-turn staff traffic to test against.

Phases 0 and 1 overlap; Phase 2 is gated by the corpus pass and Fede's QA run; Phase 3 waits for real multi-turn staff traffic.

8. Who gets the hand-off: task type → role

A hand-off goes to a role, picked by the type of task, never to a hard-coded person. The company's Team page and its role dropdown are the only source of people and roles. There is no separate list of roles or people; Clara looks at the team and its roles and delegates from there. We ship opinionated defaults; a client can tweak them later.

We use only the roles the Team page has today: Property Manager, Leasing Agent, Company Admin. No new roles now. At Western Slope: Kat and Beverly are leasing agents (Kat does the showings, Beverly does computer work), Cheryl is the property manager, and Kat is the default person.

Clara hands off→ What type of task?→ Which role→ Who has that role on the Team page→ Guest card assigned + text/email to them
One lookup, two steps: task type picks the role, the Team page says who fills it.

Routing matrix (our recommended defaults)

Task typeDefault role nowLaterExample
Tour logisticsLeasing agent (Kat, the default person)sameProspect running late, wants to reschedule, no-show, lockbox trouble, something happened on site
Paperwork / application adminLeasing agentcould point at Beverly as the default for this task; still no new roleApplication stuck, missing document, wrong form sent
Knowledge or policy question Clara can't answer (answer saved to the knowledge base)Leasing agentsame as paperwork"Do you take cosigners?", "Is the yard fenced?"
Exception or approvalProperty managersameWaive a fee, hold a unit, special lease terms
Renewalsnot in chunk 1Property manager (negotiation, exceptions)Tenant pushes back on the renewal rent
Maintenancenot in chunk 1Emergency: on-call line or call center. Non-emergency: maintenance coordinator, else property managerBurst pipe at night; a slow drain
Collections (not offered yet)not in chunk 1Property manager, or accountingLate rent conversation
Anything elseThe property's default personsameAt Western Slope: Kat

Typical property-management team

The long-term role list the design scales to. Rows marked "later" are future only; nothing is added to the dropdown now.

RoleOn the Team page today?
Owner / principalLater (closest today: Company Admin)
Property managerYes
Assistant property managerLater
Leasing agentYes
Leasing assistantLater
Maintenance coordinator / technicianLater, with the maintenance chunk
Accounting / bookkeepingLater, with the collections chunk
Virtual assistant / adminLater

Chunks: the design is the whole matrix; we build it one module at a time. Chunk 1 is leasing only, which is what we are tuning now: with today's roles only: tour logistics, paperwork and knowledge → leasing agent; exceptions → property manager; anything else → the default person (Kat at Western Slope). Later chunks are renewals, maintenance and collections; each adds its rows to the same matrix and, if needed, its roles to the same dropdown.

How a client tweaks it: later, a section on the company settings page, working title "Human in the loop", with one small table: task type → role. People still come only from the Team page. Left alone, it uses our defaults. Defaults ship first; this section is not built now. It follows the building-then-company settings order in Gera's portfolio design: the company sets the matrix, and a building's own default person wins for that building. [superseded 2026-09-29, see decisions]

One naming note: these are job roles, separate from the access roles in Gera's design (org admin, property owner, PMS credential holder). The Team page dropdown mixes the two today (Company Admin sits next to Leasing Agent); they must stay distinct in the model.

9. Prior art: how others hand off to humans

Short answer: there is a simple, shared model, and ours already matches most of it. Two things differ: how often we remind, and how module-specific the matter is. (Research 2026-09-28.)

The common mental model

One hand-off shape for every module

The matter is the same record in every module: module · subject record · task type · owner (role → person) · what the human gets · what the customer hears · when it returns to Clara. Only the subject record and the AppFolio surface change.

ModuleSubject recordTypical hand-off → roleHuman acts in AppFolioBack to Clara when
LeasingGuest cardTour problem, exception → leasing agentGuest card assigned to them (Phase 1.4)Customer writes again
RenewalsLease renewal offerRent pushback, special terms → property managerThe renewal offer; AppFolio itself keeps staff on renewal offers (Realm-X)Offer sent or customer writes again
MaintenanceWork orderEmergency, access, vendor dispute → on-call line or coordinatorWork order assigned to a tech or vendor (AppFolio)Work order status changes
CollectionsTenant ledger balancePayment plan, dispute → property managerTenant ledger; Colleen escalates to the manager after its own follow-ups (Colleen)Payment posts or customer writes again

How often to remind

Repeating the same reminder backfires: acceptance "dropped by 30% for each additional reminder" (Ancker 2017). Incident tools notify once, then move to the next person after a timeout (PagerDuty); help desks remind before the deadline and escalate after it (Freshdesk). So: not three reminders. One ask, one reminder timed to the customer's deadline, then the next person, then an honest line to the customer.

What this means for this design

  1. Keep the two paths, one owner per matter, and "I've got it" as the acknowledgement that stops reminders. Everyone above works this way.
  2. Change "nag ≤3" to one reminder at the customer's deadline, then the next person in the role, then the customer's line. — adopted 2026-09-28.
  3. Change the matter to carry module and subject record now, and make the hand-off email a fixed packet (who, what they want, what Clara tried, the one action, link to the record). Renewals, maintenance and collections then reuse the engine by adding rows to the routing matrix. We keep saving staff answers straight to knowledge with who said it; vendors gate that with an approval step, which we reject by rule. — adopted 2026-09-28.
9b. What we tried before, and what moves into the engine

We built pieces of this loop several times: turnover texting for property managers, the promise ledger, the Camellia property-manager experiment, a reminder system for property-manager tasks, and a coworker test run. None became the product, but three of them solved the hard part, knowing which matter a staff message is about.

What we learned

Staff memory

Today Clara knows a staff member's name and role, nothing else. Their questions and answers are stored inside the customer's conversation (the cause of Kat's reply landing in Steven's thread). No setting says "text me, don't email", and nothing lists the matters open with one person. The engine gets a thread per staff person, a list of their open matters kept current by the matter workflow, and preferences that only the person or the Team page can change.

Seeing the back-and-forth

Today staff messages show as collapsed rows on the customer's conversation, labelled by who wrote them only. There is no matter page, and the workflow keeps counts, not events. Needed: an ordered event list in the workflow, one matter view with owner and timeline, and a "with Clara" list on each person's Team page entry.

PieceTodayVerdictWhy
Open-asks-per-person list (built for turnovers)live, turnovers and renewal letters onlymove inBecomes each staff person's open-matters list
"Which matter is this?" ladder (turnover texting)live, texts onlymove inLast message Clara sent → only open matter → one question
Email reply matching by headerslivekeepExact; the email rung of the same ladder
Turnover "Conversation with Clara" panellive, never used by a clientmove inThe idea becomes the matter view
Staff answer saved as knowledgelivemove inThe knowledge step
Property-manager task reminders, "forwarded question" kindlivemove, then deleteA second reminder system chasing the same forward
Daily 9 AM reminder joblivedeleteReplaced by the matter's own timer
Keyword list for staff replieslivedeleteReplaced by judgment
Four separate on/off switches for this looplive, offfold, then deleteOne company switch: Human in the loop [superseded 2026-09-29, see decisions]
Coworker test run (unmerged)deaddeleteProved the text loops; timeline idea moves to the matter view
Duplicate test harnesses (escalation, human-in-the-loop)tests onlyfold, then deleteOne harness for one engine
Staff texting tools (book, move, tour notes)liveleaveStaff tools; they read the engine's matter list
Promise ledgerlive, test property onlyleaveCustomer promises; already opens matters through the engine
Other property-manager reminders (applications, countersigns)liveleaveNot the staff loop
9c. Switch cleanup (2026-09-29)

Fede, 2026-09-29: "I think we should remove all the switches and just have it on" and "there shouldn't be lines where it's not on." Every on/off switch on the staff loop has been deleted (all merged 2026-09-29) so the behaviour is simply on everywhere; only the coworker-mode switch remains, pending Fede's yes/hold.

Switch (plain words)What it gatedBeforeAfterPRState
Staff ask-by-text (company)Whether Clara texts staff a question at allOff at every companyAlways on#13563Merged
Staff text leasing (company)Staff booking, moving or cancelling tours by textOffAlways on#13577Merged
Human in the loop (company)The whole staff loopSet at 0 of 10 companiesRemoved; loop always on#13613Merged
Escalated tour bookingClara books the tour herself after a hand-offOffAlways on#13565Merged
Team tour email after a call (property)Email to the team after a tour is booked on a callOn at Western Slope front door and the test propertyAlways on#13583Merged
Missed-transfer follow-up (property) + the old tour-day fallback senderThe follow-up when a transfer to staff failsOn at Western Slope front door, Camellia, test propertyAlways on; fallback sender deleted#13603Merged
Temporal enrollment env flagWhether escalation matters run on TemporalEnv flagDeleted; always Temporal#13559Merged
Ask-lane allowlistWhich companies could receive staff asksAllowlistRetired; guard-refused asks go to #alerts#13548Merged
Topic-scoped hold unmute——Merged#13578Merged
Memory-ack gateDead confirmation prompt after a staff answerDead codeDeleted; the in-thread remember path is the one lane#13611Merged
Coworker mode on tour confirmationCoworker wording in the tour confirmationOffAlways on#13622Merged
Coworker mode (the rest)A group of staff-facing behavioursOff everywhereKept for now; yes/hold ask posted to Fede 2026-09-29—Pending Fede

Also: the default hand-off person is now one person per company (an organization setting), merged in #13547.

Proof: after deploy, the Willows dry run on Fede's cell (staff text loop end to end), a Temporal count showing escalation matters running, and one real-property memory-ack message id with a clean Sentry window.

Willows staff email dry run (2026-09-29, 3:20 PM; completed 2026-09-30)

ClaimEvidenceResult
Tenant text sentTwilio SMefa55f26e072c4752b607bfe6a68f542, 3:20 PMPASS
Receivedmsg_3a57ee9c-b20d-4009-acd6-fbf923d4b779, 3:21 PMPASS
Staff question opened, waiting on staff, timer owned by Temporal, 0 remindersmatter_5de82075-fdd6-49dc-b84e-0213dca16e23PASS
Reminder workflow runningescalation-matter_5de82075-fdd6-49dc-b84e-0213dca16e23PASS
Staff question email delivered to our own Gmail test mailbox (morpheus@propflowai.co)Message-ID d7aa7140-4f57-4f46-8cf0-c71b0b602966@propflowai.co, 02:12:50Z, SPF/DKIM/DMARC pass (landed in Gmail spam)PASS
Staff reply by email from that mailboxMessage-ID 179073476631.3036.2874291882834973000@propflowai.co, 02:19:26ZPASS
Matter resolvedmatter_5de82075-fdd6-49dc-b84e-0213dca16e23, state resolved, resolvedAt and memoryAckSentAt 02:19:37Z, staffAnsweredBy morpheus@propflowai.coPASS
Knowledge saved at Willowsknow_c0cdee3b-d258-4c2a-9f55-fa2b93d37f8e, source staff_reply, title "Pet Deposit Refund Terms"PASS
Thank-you email to staffmsg_1114bd7a-abab-4c57-a7f7-e8b08382b518, writer escalation.memory-ack, delivered as 90436a26-c9d1-4dcc-9aef-f9d51e1609a4@propflowai.co (spam)PASS
Tenant follow-up textTwilio SMb5aefefe8bf001bb09a4e5d22f6d2c79, delivered 02:19:40Z to our own test numberPASS
Reminder workflow completedescalation-matter_5de82075-fdd6-49dc-b84e-0213dca16e23, run 01a0ef0b-023f-74d2-928d-cea7d44bce95, completed 02:19:40ZPASS

The loop is proven end to end at Willows as of 2026-09-30. The staff mailbox used is our own Gmail test inbox, admitted by #13936.

Found by the dry run:

PRChangesState
#13829Test properties may page our own sandbox mailboxesMerged
#13839Tour cancel on a held thread is confirmed to the prospectOpen
#13844Delete the last coworker-mode switchOpen
#13854Bench stops writing the deleted switchOpen
#13893flagged with the property teamOpen
#13936Willows dry run proven end to end via Gmail test mailbox and worker build cc20dd843Merged (2026-09-30)
10. Decisions

Fede (2026-09-28): only turning on at a customer needs his call; everything else is decided on the recommendation.

  1. Who gets the guest card on a hand-off? (a) the property's escalation owner · (b) whoever replies "I've got it" · (c) the default person at escalation time, re-assigned to whoever says they have it — Decided by Fede 2026-09-28: the hand-off goes to a role picked by task type, filled by the client's people; start with Kat as primary at Western Slope; whoever says "I've got it" takes the card. See Who gets the hand-off.
  2. What the customer hears once a person owns it. (a) nothing · (b) one line from Clara: "I've passed this to the team, they'll reach out" (no name) · (c) Clara checks back after a day — Decided by Fede 2026-09-28: one line from Clara, no name; repeat asks get "the team is still looking into it"
  3. When does a human-owned matter come back to Clara? (a) only when the customer writes again · (b) also after some quiet days, with one check-in · (c) never — Decided by Fede 2026-09-28: back to Clara when the owner says so or the subject closes; meanwhile new prospect messages are forwarded to the owner
  4. Scope now. (a) Phase 0 live today, Phase 1 dark right after, Phase 2 before any turn-on · (b) Phase 0 only, rest later · (c) go straight to Phase 3 — Decided 2026-09-28: (a) Phase 0 live, Phase 1 dark, Phase 2 before turn-on — decided on the recommendation
  5. Where the default hand-off person lives. (a) a property setting on the property page · (b) one person per company · (c) reuse the escalation email chain — Decided 2026-09-28: (a) property setting — decided on the recommendation [superseded 2026-09-29, see decisions]
  6. How staff map to AppFolio users. (a) matched automatically from the AppFolio user list by email · (b) typed per person on the property page — Decided 2026-09-28: (a) matched by email from the AppFolio user list — decided on the recommendation
  7. Turning Phase 1 on at Western Slope after Phase 2 passes: yes, with the staff-reply review gate on until baked · hold — Decided 2026-09-28: Fede's call, asked once the harness passes [superseded 2026-09-29, see decisions]
  8. Judge model: Decided: Sonnet 5.5, by benchmark. See The judge.
  9. Kat's numbers: work phone = the office landline, mobile = her cell, Clara texts the cell — recommend yes · hold — Decided by Fede 2026-09-28: landline = call routing only; mobile = notices, updates and texting Clara.
  10. Barry: wait for Kat's answer; if a real prospect, move his contact onto that card and take Kat's number off it — Decided by Fede 2026-09-28: move the tour to the 'Barry Unknown' card Kat made, send him the reminder, add the showing in AppFolio, give Kat her number back; in progress
  11. Reminders: one, not three — decided by Fede 2026-09-28; setting later if a client asks.
  12. Hand-off packet + one generic engine across modules — decided by Fede 2026-09-28.
  13. Engine runtime = one Temporal workflow per matter — decided by Fede 2026-09-28. It extends today's escalation-matter workflow; see Architecture.
  14. After a hand-off the human uses their own channel; Clara goes quiet on that matter and forwards repeat contacts — decided by Fede 2026-09-28.
  15. Escalation is about a matter, never the person. Clara keeps helping with everything else and never volunteers the pending matter unless the customer does. "Still looking into it" only when the customer re-asks about that same matter and it's truly still open — once staff answered, the tour moved, or the topic is over, she never mentions it again; no per-turn reminders. Real transcripts where Clara got stuck or over-repeated become harness fixtures — decided by Fede 2026-09-28.
  16. 2026-09-29 — No turn-on: the coworker loop is an improvement to a live behaviour. Fede, 2026-09-29: Clara already hands prospects to Western Slope staff today, so the staff loop improves a live path; there is no activation and no launch switch ('there shouldn't be lines where it's not on'). The Human in the loop company switch (#13211) is removed. The default hand-off person moves from the property page to the organization (#13232 placed it per property without approval; hand-off destinations are org-level). Proof is the Willows staff dry run on Fede's cell; then PR-D ships live everywhere. Decision 7 (turn Phase 1 on at WS) is withdrawn.
11. Out of scope / not doing
12. One reader for everything staff write to Clara (Proposed — pending review, 2026-10-27)

Why: Situs 2026-10-27: a staff note about an applicant was reworded and texted to the applicant; RCA: leak audit §Situs. Fede: 'we need to rewrite this'; checked with the Clara Refactor session (one shared reader, no rewrite layer, unsure never goes outward).

Checked against the vision (2026-10-27)

The Clara Refactor session and the Clara Coworker Vision session both reviewed this. Verdict: right shape, no conflict with the master page (/a/clara-coworker-loop-v3-2026-10: #turn-rebuilt, #gates, #inv-interfaces, #idea). Five changes, now part of the design:

  1. The reader never sends. It returns a reading only: outcome, facts with ids, what is still open, and why. The existing doors act on it: handled, question, note and unclear become 'stay silent, with the reason' plus a matter state; an answer becomes a normal Clara reply. Any word to staff goes through the one team-ask path.
  2. Staff facts enter Clara's reply as fact rows with ids, not a label. The writer declares which fact ids it used, and the facts check blocks any sentence to the person that traces to nothing. That is what stops 'I've already reviewed the packet' next time.
  3. Today's claim checks on the answer path stay until the facts check exists, and are deleted in that PR, not in PR 2.
  4. On handled or answer, Clara's own earlier held draft on the same matter is withdrawn. At Situs the held draft stayed approvable after the team had already answered.
  5. The note back to staff is also a claim: on handled and note it says 'closed, nothing sent to the applicant'; on answer it says 'reply held for approval'. Never 'I've let her know'.

The picture

BEFORE  staff writes ──► phrase list ── no match + 15 chars = "the answer" ──►
        rewrite step ("as if you looked it up yourself") ──► person   (on failure: staff words sent verbatim)

AFTER   staff writes ──► ONE READER (model judge) ──► what is this?
          answer for the person ──► Clara's normal reply writer, staff fact labeled ──► Supervised hold ──► person
          staff handled it      ──► close as staff-owned, thank staff ──────────► person gets nothing
          question for Clara    ──► Clara answers staff from the records ───────► person gets nothing
          note / policy         ──► record it (policy is remembered) ───────────► person gets nothing
          unclear, or any error ──► one short line to staff, team-ask hold ─────► person gets nothing

1. The reader already exists

On Sep 29 we built a model judge (Sonnet 5.5, thinking on). It scored 64 of 64 on its own test set: 18 real incidents, the rest synthetic. The phrase list scored 53. It never reached main. We finish it rather than write a second one.

Sep 29 judgeWhat the refactor needs
Outcomes3: decision, takeover, working5: answer, handled, question, note/policy, unclear
When unsure"Never drop an answer": relayUnsure never goes to the person
On errorFalls back to the phrase listUnclear: ask staff
ReadsClara's question + the replyAdds the person, recent thread, who wrote it, where
Gives backA bucket + a reasonAdds the facts for the person + "part still open"

Reused: the model call, the model choice, the 64-case test set and runner. Missing: five outcomes, one shared door, the one-line staff ask, and the hand-off to Clara's reply writer.

2. What each outcome does

OutcomeTo the personMatterRemembered as policy
AnswerClara's normal reply, held under SupervisedClosed (open if part is unanswered)If property-wide, from staff's own words
HandledNothingClosed, staff-owned; Clara's pending held draft withdrawnNo
QuestionNothingOpenNo
Note / policy ("I'll find out" = note + follow-up)NothingUnchangedPolicy only
UnclearNothingOpen, one ask to staff via the team-ask pathNo

Answers take the path team notes already use, minus its "news you looked into yourself" line. Clara credits "our team" for staff actions, never names them. Writer fails: nothing sent, engineering alerted. Model error: three retries, then unclear. A typed out-of-office reads as a note. Staff get at most one unclear ask per matter.

Deleted: the phrase list, the rewrite step, the verbatim backup, the numbers-only check, once the facts check exists (not in PR 2).

3. Proof

4. PR cut

  1. Lift the judge to main + eval, with five outcomes and fail-closed. Nothing calls it. Proves the score.
  2. Email replies and team notes go through it; old code deleted; withdraws the pending held draft; staff ack states what the record shows. Proves the Willows run.

Slack held-card replies keep today's grammar (Fede: no). The Clara Refactor session points in-thread teammate messages at the same door.

5. For Fede

Engineering notes

PropFlow Docs