Everything about the recent Clara-as-coworker fixes, in one place — what's decided, what's not, what's done.
The transfer works: Clara reliably dials Camellia's office line. The problem: nobody answers 6 of 14 transfers since Sept 8, and the email that follows often drops who called and why. Not caused by Western Slope or portfolio/org work — ruled out.
| Outcome | Count |
|---|---|
| Connected — a person picked up | 8 |
| Office voicemail | 3 |
| Rang out, no answer | 2 |
| Answered, then nobody spoke | 1 |
| Date | Caller wanted | Outcome | Verdict |
|---|---|---|---|
| Mon 9/8 | Application help | voicemail | OK-ish — name buried in quote |
| Wed 9/9 | Vendor, job extension | voicemail | OK |
| Fri 9/11 | Robocall | rang out | Broken — office paged about a robot |
| Mon 9/15, 3:05pm | Asked for leasing agent | rang out | Broken — real ask read as "no reason" |
| Mon 9/15, 3:06pm | Studio, Oct 1 move-in | answered, silent | Partly broken — name dropped, duplicate 97s later |
| Wed 9/16 | Jordan M. — key pickup, move-in day | voicemail | Broken — known name, reason stated twice; neither reached email |
Fede reviewed every change this session put live at Camellia beyond the autonomous switch itself. Outcome, Sept 7 evening (UTC):
Kept
Changed on Fede's word
Undone (reverted, not requested by Fede)
Standing rule: Nothing merges to Camellia's live paths without Fede's word on that specific change. QA passes report; they do not fix.
Evidence: merged #7296 43f5574bd9, #7298 a9ba8eadd8, #7303 c7410790e4, #7305 c4a295b89e, #7306 5416e27b92, #7307 1f5e50df07; closed #7279 #7292 #7293 #7262 #7276
Replay of past Camellia conversations through the code Camellia runs now (Sept 7 midday), five runs each side, today's behaviour versus autonomous. Since this morning the grader also reads the note the office receives.
| Metric | Today (coworker) | Autonomous |
|---|---|---|
| Answering instead of handing off | 73% | 0% |
| Giving everyone an answer or one deferral, never silence | 73% | 0% |
| Not promising a time or a callback | 60% | 0% |
| Leaving no record, hold, or alarm behind | 40% | 0% |
| Replying in her own words | 53% | 0% |
| The office note quotes the person's own words | 53% | 0% |
| The office note shows the number once | 0% | 0% |
| Saying the deferral only once | 73% | 0% |
| Sending the team a note only when she could not answer | 20% | 0% |
| The office note names the team that owns the ask | 33% | 0% |
Counts: promises with nothing behind them 6 to 0; holding lines 8 to 0; replies the person received 12 to 15; notes to the office 8 and 8. The three rows that looked worse at midday were a grading mistake: the grader counted a correct 'I'll let the leasing team know' as an answer. With that fixed, and the note now naming the desk that owns the ask in its subject and first line, every row is clean on three runs. One real wording defect remains in the decision deck (a pet-fee question answered fully and still followed by the deferral line) and is being fixed with the deck as the measurement. A wider run over all 439 replayable text and email turns is running overnight. Phone calls, 89% of the history, cannot be replayed this way; they are checked with real robot calls instead.
Live Camellia, last 7 days, today's build: 3 of 7 text or email hand-offs left the person hanging; 15 of 28 promises had nothing behind them; 5 stale re-pages to the team. That is the baseline the weekly scorecard will track after the flip.
| 62d640d2be | note names the desk; deferral is not an answer |
| 453adf209a | results |
Still open, low stakes, defaults applied unless Fede says otherwise: D9 drop the "on the way" and "arrived" tour pings (default: drop); D10 fold paperwork reminders into one daily digest (default: yes); D5 dedupe promise alarms (default: yes); D3 fair-housing timeout at coworker properties (default: leave blocking).
Quiet test at Camellia, Sept 7 night
| 59df569ad9 |
| 244885f572 |
| c11f85a6ee |
| 29e21c6c12 |
| d505ee0213 |
| f285c0dd15 |
| 2e6eddae0c |
| ce01252f74 |
| 2475870ea2 |
| 2dfac4e667 |
| a85c778e46 |
| 6a8b251f41 |
| ce08b5b742 |
Thirteen legs on the exact code Camellia runs. Labor Day made the office closed all day, so the transfer legs ran under a one-day override. Nine passed: answerable text answered from file with no hand-off; unanswerable text got the plain line and one note; the same question again got no repeat and no second note; a repair question from an unknown number named the maintenance team; three open-office calls got "let me connect you with someone on the team" and a real transfer attempt, with the missed-call note landing about six minutes later; three closed-office calls got the closed-office sentence word for word, no transfer, one note each with the question and a number. No tracked questions, reminders, promise alarms, holds, or threads left marked as a human's.
Two real failures: a prospect who hasn't toured got the right words but no note reached the team (second time found; being fixed at the cause), and an emailed question was dropped silently: the test mailbox filed it as junk, and the inbound sorter treated a resident's parking question as a system notification and skipped it. Whether that sorter drops real Camellia emails is being checked now.
Since then: when a vendor has more than one open job Clara asks which one instead of guessing (merged); the missed-call note after a failed transfer is sent as soon as the outcome is known (merged, with one regression caught and fixed within twenty minutes); the callback question sometimes still adds a reason, tracked.
| 824dbd864f | vendor greeting asks |
| c499918926 | missed-transfer note timing; fix-forward |
| d5c794f699 |
Sept 4: a root-cause read on why the hand-off loop keeps failing at Camellia, with four decisions for Fede, is the first section below. The Sept 4 hand-off build is merged and off everywhere. Earlier status follows. 6 of 11 fixes are already live or done and proven. 3 more are close and being reviewed. 1 is being handled in a separate session, and 1 is on hold for a redesign. Two more things need your okay below: a customer text's exact wording, and whether to release 16 stuck conversations. Turning any of this on for real Camellia residents only happens after you say go. Sep 3: the escalation harness is in (PR #6937); six rulings below decide the build. Later that night: the backlog of emails waiting on your review got dug into, the root causes got found, and the whole "did Clara keep her word" tracking system got graded — four more decisions below.
Split at Aug 4, the day the "escalated threads get no automatic reply" rule shipped. Inbound volume was flat to up, so this is not fewer messages making worse ratios.
| Camellia, text + email from real people | Jun 8 – Aug 3 | Aug 4 – Sep 4 |
|---|---|---|
| Got any reply within an hour | 97% | 89% |
| Got a reply that actually answered, within an hour | 93% | 78% |
| Never got a real answer at all | 5% | 14% |
| "Checking with the team" style holding lines sent | 6 in 8 weeks | 18 in 4 weeks |
The worst week was Aug 24, which was also the week with the most machinery running: 11 tracked questions, 8 hand-offs, 9 holding lines (6 of them repeats to the same two people), and still 17% of people never answered. One prospect got the holding line five times in 24 hours. Before Aug 4, every unanswered thread was a "thanks, got it." After, most were live asks: a lease-term correction, a move-in date, a post-tour "I loved the place!", a direct question.
The decline actually starts a week earlier, Jul 27, when we stopped Clara from claiming hand-offs she hadn't made. She stopped over-claiming and started under-delivering in the same move: the claim was removed, nothing replaced it.
RC1. The signal goes nowhere a human answers. Six delivery channels to humans, four kinds of tracked record, fifteen "doors" that page someone, and not one of them lands on a person at Camellia who replies. Slack is write-only in our code: there is no way to answer a Slack post. Replies to a hand-off email, a promise email or a missed-call note go to a dead end. Only one path can turn a human's answer into policy, and no real customer has ever used it. The loop was designed around a responsive PM and we pointed it at ourselves.
RC2. Every safety layer became the place the next real ask dies. Hold-for-review caught bad emails and also the one good one. The fair-housing check fails closed, so a slow model call blocks a pet-fee reply. The reminder ladder stops after three tries and nothing follows. "No canned acknowledgement on human-owned threads" removed the noise and installed the silence. Each layer was built for the previous incident and none owns the outcome "a person is waiting."
RC3. Point solutions instead of one owner. 26 mechanisms since March, 20 of them since Aug 4, 15 in the last four weeks. 96 code modules. The hand-off handler alone rewritten 45 times in four months. Four separate test rigs for the same loop built 11 days apart. 51 doc pages plus 187 auto-generated "parked on you" pages. Nobody, human or code, holds the whole picture, so every fix is local and every incident reads as new.
RC4. The rollout loop was too fast to learn from. Most changes shipped to Camellia from the same session that found the bug, often the same day, and were proven safe on a test bench that does not have Camellia's silent team. Four times a problem was declared fixed and reopened within days. Three mechanisms were built and turned off within a week. Docs and code disagree in both directions.
RC5. Wrong first customer for the full vision. The coworker loop only compounds when the human answers and the answer becomes policy. Camellia's team does not answer, and we have already learned most of their policies. At Camellia the loop has no fuel.
Fede's own bar, from Sept 3: no promised times, no "the team will reach out" unless a human is actually assigned; "not small enough, go back and look at the epic." Competitor research (Sept 4) found nobody in property management publishes how they handle "the AI is stuck," and the one documented complaint is a leading vendor failing to flag unanswered questions to a manager. Outside the industry the working pattern is one honest holding message, a named reason, one queue, a timer that moves the ask up, and the human's answer captured for next time. That is the missed-call email plus a timer, not what we built.
D1 — What does Camellia run while we rebuild?
Today Camellia runs a patchwork: escalated-thread silence on, tracked questions and reminders pointed at our inbox, the promise alarms partly off, the missed-call email off, hold-for-review off, the new coworker-mode switch off.
Recommended — Autonomous mode. Clara answers what she can from Camellia's notes, and for anything else says once "that's one for the leasing team, they'll go over it with you at your tour" (or "when they call you back"), and never promises a time or a follow-up. The only thing that leaves the building is one plain email per person per day to the real Camellia inbox, in the missed-call shape: who, what they asked, how to reach them. No tracked records, no reminders, no promise alarms, no holds, no holding-line template. Turn the missed-call email on.Keep the current patchwork and turn the Sept 4 coworker-mode switch onTurn Clara off at Camellia for hand-off cases entirely (silence, no email)
Decided by Fede (Sept 4 retro): Autonomous mode. Sequence: corpus and scorecard first, reproduce every failure on today's code, replay with the removable gates off, compare, then Fede's go to turn on. One config step is Fede's alone and needs no code: Camellia's escalation owner address is our own inbox copied to itself; clearing or repointing it turns the tracked-question layer off. Update, Sept 5: both already done — Camellia's hand-off owner is already the real Camellia inbox, and the missed-call email is already turned on there, both changed the evening of Sept 4 in another session on Fede's instruction. "Turn Camellia autonomous" is now a shorter step.
D2 — What happens to the machinery built since Aug 4?
Tracked questions, reminders, promise ledger and alarms, hold-for-review, holding-line template, the Sept 4 coworker-mode bundle.
Recommended — Keep the code, turn every switch off at real properties, and delete the old promise-alarm path that has no switch. Nothing is removed from the codebase until the gold-mine scorecard says what each piece is worth.Rip it all out of the codebase nowLeave everything as it is
Decided by Fede (Sept 4 retro): remove the half-baked layers. Done as one removal pull request per gate group, each proven by the before/after replay on real Camellia history. The registry counts 30 gates: 16 to remove, 7 to keep as alerts only, 6 to keep, 1 Situs-only. Eight have no off-switch today, which is why a replay-only profile switch ships first.
D3 — The fair-housing check
Always on, no switch, fails closed, reason not stored. Two blocks in 60 days at Camellia, both false.
Recommended — Keep it, but fail open on timeout, store the reason on the message, and when it blocks a reply the person gets the same "one for the team at your tour" line instead of silence. Add a per-property switch.Turn it off at CamelliaLeave as is
Recommendation: keep, fail open, never silent.
D4 — Where does the full coworker vision get built?
The loop needs a PM who answers and whose answers become policy.
Recommended — At the next client whose team actually replies, as a condition of onboarding (a named owner, a reply expectation). Camellia stays autonomous.Keep trying at Camellia
Decided by Fede (Sept 4 retro): the coworker loop is built with Situs Group and the next partner, whose teams will engage. Camellia stays autonomous.
Five pull requests merged, production untouched. (1) An extractor that pulls every Camellia record into a read-only corpus outside the repo: 912 conversations, 10,572 messages, every tour, work order, promise, hold, grade and trace since April. (2) A registry of all 30 hand-off gates, 16 marked removable, with a replay-only switch that refuses to run on any production runtime. (3) A scorecard that counts today's failures from the corpus with no model calls. (4) A reproduction lane that replays the real conversations through the real code. (5) A before/after report: today's gates versus autonomous, five runs each.
The scorecard today: 8 people left hanging after a hand-off; 4 people told "we'll get back to you" more than once (10 extra sends); 6 of 10 tracked questions closed with no staff answer; 19 of 39 promises with nothing behind them; 4 duplicate team emails; 3 pages about dates already gone. Four of those numbers match the hand audit exactly.
What the before/after shows, exactly counted: with the removable gates off, promises recorded with nothing behind them went from 4 to 0, sends stopped by a safety check from 1 to 0, team emails from 6 to 5, and the person received the same number of replies (14 and 14). Nothing got worse.
What it does not show, and why it matters more. The person-facing failures barely moved: Clara still hands off or promises a callback instead of answering or deferring to the tour in about 60% of turns, gates on or off. Two findings behind that. First, on the bench a live model answers with the bench's knowledge, so the same conversation reproduces a failure one run in five and then four runs in five; rates are samples, only the exact counts are evidence. Second, the gates were never the main cause of what the person experienced. The main cause is how Clara is told to behave: hand it to the team, promise a follow-up. Removing gates stops the noise to the team; changing what the person hears is a prompt change with its own evals, and it is the next lane after the removals.
Fair housing, measured: the judge withheld and then released the identical words on the same input. That is an alert's behavior, not a gate's. It is the only gate the replay switch cannot reach today, and the next pull request splits it.
Also caught overnight: a dated renewal test guard expired and turned main red for every pull request; the renewals session confirmed the old cohort had drained and retired the guards. It had warned for fourteen days with no reader.
What now exists, merged to production, off everywhere:
Fede's picks needed: Hand-off decision deck — fifteen real Camellia conversations, three options each for what Clara should say, one pick per card and each pick becomes an eval case.
In review, stacked and dark: the promise-alarm email gets an off switch under autonomous; tracked questions and the reminder ladder get a real off switch under autonomous (existing questions left alone); a property set to autonomous can never also be holding every email for approval.
The prompt change — Clara answers what is in the property's notes, defers the rest to the tour or callback once, never promises a follow-up, and the canned "I'll check with the team" line no longer overwrites her reply — is in its eighth review round. Every round's finding was real and none reached production.
The before/after, both halves together (Sept 5, evening)
Five runs of each arm on the real Camellia conversations, on production code with both the prompt change and the gate removals merged. Read as: how often the thing that should happen for the person writing in failed to happen.
| What should happen for the person | Fails today | Fails under autonomous |
|---|---|---|
| Every message gets an answer or one deferral, never silence, never a holding line | 47% | 0% (the only row with enough samples to call) |
| They receive Clara's own reply, not the canned line swapped in afterwards | 20% | 0% |
| No tracked record, no hold, no promise alarm behind the scenes | 27% | 0% |
| The turn answers rather than hands off | 47% | 13% |
| Nothing promises a time or a callback | 40% | 13% |
| A turn that can't answer says so exactly once | 47% | 40% |
| One team note when Clara couldn't answer | 27% | 20% |
| What happened, counted from records | Today | Autonomous |
|---|---|---|
| Promises with nothing behind them | 4 | 0 |
| Holding lines sent | 6 | 2 |
| Replies the person received | 14 | 15 |
| Tracked questions opened | 0 | 0 |
One row went the other way and is not a regression: the check that "no gate altered an outbound" went from 7% to 47% because under autonomous the promise check deliberately rewrites a promise into the deferral. Changing that sentence is the point. The expectation is being corrected to count only alert-only gates. The prompt half measured alone had improved these numbers; the gate half measured alone had made them worse; only the combined tree answers the question.
What has to be true before Camellia is switched
| Finding | What we learned |
|---|---|
| Reminder emails were never off | The coworker switch only gated the extras — the escalation at the cap, and the CC. The reminder email itself always went out; three full ladders ran to exhaustion at Camellia. |
| The gate inventory overstated what was off, five times | Every wrong row claimed something was dark that was live. Fix: each row now records the value read from the live property row and the date, with a build check that fails when a claim contradicts the code. |
| The duplicate "Clara made a promise" emails | Simpler cause than assumed: one pass over one call recorded three promises at once, and the alarm fires per promise. A once-per-conversation-per-day fix would change every coworker property, so it's parked as decision D5 below. |
| Fair housing, 30 days of Camellia replies (605 of them) | The check would block none, time out on none, and the only two blocks it ever made — the pet-fee reply and the application-link reply that followed — reproduce every time, and are both wrong. |
| Near miss | The promise-alarm switch sat on the shared delivery path for every email to the property team, including the missed-call note that is on at Camellia. Turning autonomous on would have silently deleted it. Caught in review before merge, fixed, pinned by a test. A second finding: every promise at an autonomous property would have been recorded as broken the moment it flipped. Also fixed. |
| Two plan facts were stale, not wrong | Camellia's hand-off owner is already the Camellia inbox, and the missed-call note is already on there — both changed on the evening of Sept 4 in another session on Fede's instruction. "Turn Camellia autonomous" is now a shorter step. |
| A fourth silencing flip, found by accident | At an autonomous property with no team mailbox, the hand-off handler still marked the thread as human-owned on its way out. Found while checking a stash entry, fixed and tested on both arms. |
| Running the deck against the recommended options found four misses: a deferral bolted onto a fully answered reply, pet fees not stated, an 'I'll have them…' promise, and one harness artifact. | The deck is doing its job before Fede picks. Fixed in the say-it-once and maintenance changes; harness artifact left failing on purpose. |
D5 — One promise alarm per conversation per day?
One pass over one call can record three promises at once, and the alarm fires per promise — that's the actual cause of the duplicate "Clara made a promise" emails.
Recommended — fix it, dark, behind the same hand-off setting, so it lands at autonomous properties firstFix it everywhere now (changes every coworker property)Leave it
Recommendation: a. Under autonomous the alarm is off anyway, so this only matters where it stays on; ship it dark and let Fede decide where.
Timeout behaviour: the check now lets a reply through on a timeout only at autonomous properties. Coworker properties keep blocking on a timeout. Fede's call whether the fail-open applies everywhere; it is a one-line change.
Evidence behind every number above: read-only pulls from production on Sept 4 (912 Camellia conversations, 10,572 messages, 125 tracked questions, 202 promise rows, 5,167 email delivery records with 30-day retention), the git history of the 16 gate files, 40 working sessions from Aug 7 to Sep 3, and a competitor scan. The raw pulls live outside the repo; the scrubbed corpus and scorecard land in the replay harness.
The rule, in five lines (Fede's words, Sept 6)
What we found today
| Finding | Why it matters | Status |
|---|---|---|
| A resident's safety complaint sat unanswered 28 days. Their call was transferred, went to voicemail, nobody called back, and the system marked the call "resolved." | "Resolved" at hang-up was a bookkeeping trick so the next call starts fresh; failed transfers with a recording counted as handled. Every property. | Fix in review — failed transfers stay open |
| Ten people at Camellia are waiting for a human answer right now, six of them live leasing opportunities. | The flip does not answer them; a person does. | List with Fede (private) |
| Phone calls ignore the autonomous setting entirely. | The phone prompt is one fleet-wide text with no per-property slot; "get me a person" always live-transfers. | In review — a per-property policy slot in the phone prompt, dark; connect in hours, take a message after hours |
| The missed-call note never says why Clara handed off, and the after-hours version is a different email to a different desk. | An inbox of "called, no message left" is unreadable. | Queued — one note for both, with the reason |
| The long confusing forward (person's raw messages pasted in) went out 10 times in 30 days; only the test property had the concise version. | Fede: "completely eliminate the old." | In review — deleted; every property gets the concise shape; also fixes Spanish messages reaching the team untranslated |
| "Clara made a promise" alarms went out under three different subjects from two files. | One event, three formats. | In review — one composer |
| Four emails went out twice, 30 to 45 seconds apart. | A shared retry path. | In review |
| 184 emails to the Camellia team in 30 days, in eight kinds; 44 were tour steps, 31 paperwork nudges. | Volume, not noise, mostly. | Two decisions below |
| The deferral sentence must depend on channel and hours: never "reach the office" to someone already calling the office; never "they'll call you back." | Fede's correction. | In review, all variants rendered in the PR |
| The replay's own regex and grader were written against the old sentence; one required the callback promise it was supposed to catch. | Would have zeroed two rows of the before/after. | Fixed |
D9 — Drop the "on the way" and "arrived" tour pings?
Recommended — drop them (10 of 44 tour emails)Keep allKeep only "arrived"
Recommendation: drop.
D10 — Fold the repeated paperwork reminders into one daily summary?
Recommended — yes, first touch stays individualNo, keep individual re-sendsStop the repeats entirely
Recommendation: yes.
D11 — Who answers the ten waiting people?
Recommended — Fede hands the list to Camellia's manager, todayFede answers the safety one and Camellia the restWe answer none until the flip
Recommendation: the first, today.
The decision deck
Fifteen real Camellia cases, each with what the person said, what Clara did, three options, and what the office would receive. Fede's picks become eval cases. Hand-off decision deck.
| What | Status |
|---|---|
| Weekly live scorecard (PR #7154) | Merged; first run next Monday |
| Deferral wording by channel and hours (PR #7155) | Merged a4529207a2 |
| Long-form card email deleted (PR #7156) | Merged f169f95eac |
| Failed transfers stay open (PR #7158) | In review |
| Say it once (PR #7161) | In review |
| Maintenance rule (PR #7162) | In review |
| One promise-alarm composer (PR #7163) | Merged bac5079d96 |
| Double-send fix (PR #7170) | Merged 43f02e8008 |
| Phone prompt policy slot (PR #7181) | In review — per-property hand-off policy slot in the phone prompt; dark; Camellia's phone prompt only updates through a hand-triggered workflow with a typed confirmation |
| Decision-deck evals (PR #7180) | Merged 0850834369; 13 cards graded in CI, two left red on purpose (Clara paraphrases the fixed sentence) |
| Merge rule change (PR #7184) | Merged 9927db7abb |
| Sept 6 replay results (PR #7186) | Merged b6ff217226 |
| Flip-readiness (PR #7126) | Merged |
| Staff reminder ladder stops under autonomous (PR #7193) | Merged bba66fab17 |
| Phone sentences (PR #7194) | Merged a4bfd7749c |
| Renewal prompt sync (PR #7195) | Merged 4c280356b6 |
| Tour deferral note (PR #7196) | Merged 67dcf5e6bc |
| One inbox (PR #7197) | Merged f40b2be10b |
| Human-owned mark released (PR #7198) | Merged a233a35ba4 |
| Fully answered turn no longer emails the team (PR #7199) | Merged 8cc77dd683 (a fully answered turn no longer emails the team; the note goes out whenever the reply told the person the team would hear) |
| Decision-deck test pack (PR #7201) | Landed — the decision-deck test pack crashed on its first CI run and failed an unrelated PR; fixed, and the pack is out of the blocking sweep until it has one measured run |
| Team note quotes the question (PR #7227) | Merged 1a7e35bc6c |
| Closed-today function (PR #7229) | Merged 860d4a486a |
| Deferral follows topic (PR #7232) | Merged fdb4e16060 |
| Six major holidays (PR #7238) | Merged 0c2da03a86 |
| Grader sees the note (PR #7241) | Merged 2042fdce7a |
| Pre-push sweep false positive (PR #7228) | Merged 07afb86332 |
| Phone deploy on merge restored (PR #7212) | Merged e0359ab3e6 |
| Hard block on manual uploads (PR #7219) | Merged d20aa00ea7 |
Decision — what to do with an application PropFlow can't contact yet
Today: skip it, with no record anywhere that it exists. The office often adds the phone or email a day or two later, once the applicant follows up, but by then PropFlow has already thrown the row away.
Decided by Fede (Sept 4, 2026) — import the applicant anyway, identified by their AppFolio application number, and automatically attach their phone and email once the office adds them in AppFolio later.Alternative considered — log it and report it, take no other actionAlternative considered — ask the office to always enter contact info up front
Both alternatives were rejected: reporting alone still leaves the applicant invisible to Clara, and asking the office to change how they enter applications puts the fix in the wrong place.
Activation log: Sep 5, 2026 — contact-less application import turned on at Camellia (merged 14:34 UTC, live in the sync job 14:46 UTC). Fede said go ("finish this work", Sep 5). First run after deploy imported the two missing applicants for unit 120; steady-state runs mint no duplicates.
Everything below is built, tested, and merged into the main codebase — but switched off for every property. Nothing changes for a real customer until Fede turns the switch on somewhere. There's a second, separate switch for the "book a tour while waiting on a question" piece specifically, described below.
All five are proven by an 18-scenario test lane built for exactly this ("the person is never muted, only the question waits") — each scenario traces back to something Fede said or a real incident (this prospect, plus three other stuck Camellia threads, two escalations that went right, and the Aug 3 case where Clara talked over a human). With the switch off, every scenario that was passing before still passes byte-for-byte identically — this build changes nothing for anyone until it's turned on.
Each was decided using the recommended option so the build could keep moving. All are reversible — nothing here is live for a customer yet. Flag any you want changed; otherwise these stand.
R1 — When the person asks the parked question again, what does Clara say?
Matches the Aug 21 rule: escalate the question, never the person. A repeat ask should never be met with silence, but it also shouldn't turn into a chatty back-and-forth about something Clara still can't answer.
Chosen — acknowledge once, name the exact question, then go quiet again on that topic until there's an answerStay silent (the old Aug 20 rule)Answer every single re-ask with a fresh acknowledgement
Confirm or override.
R2 — What happens after three reminders to the team go unanswered?
Today: nothing. The record just sits there. This is exactly what happened to the Camellia prospect: three reminders fired, then permanent silence.
Chosen — post it to the team's internal alert channel (#agent-trinity), and reset the reminder clock every time the person writes backKeep emailing the same contact indefinitelyLeave it as-is (silence after three)
Confirm or override.
R3 — If the person asks something new while an old question is still parked, what happens to the new question?
Today it gets folded into the old open item and is never tracked on its own — this is what happened to the applicant with the wrong lease dates.
Chosen — every distinct question opens its own tracked recordKeep folding new questions into the existing open one
Confirm or override.
R4 — What does it take for a question to count as "resolved"?
Today a routine cleanup sweep can mark something resolved even though nobody ever actually answered the person — that happened to a prospect who toured and loved the place, and their hottest signal got no reply.
Chosen — resolved requires either a delivered answer or a human explicitly closing it; a cleanup sweep alone can no longer do itKeep allowing sweeps to resolve
Confirm or override.
R5 — Should every promise or hand-off leave a record behind it?
Today a thread can sit marked "escalated" with literally no record and no way out — that happened to a robocall thread that sat that way for 17 days.
Chosen — yes, every promise or hand-off must create a tracked record; being marked "escalated" with no record is now treated as invalidAllow escalated status with no record
Confirm or override.
R6 — The "let Clara book a tour even while a question is parked" switch — fix it or drop it?
This switch already exists and is already on at Camellia, but testing found it wasn't actually working — a tour request still got stuck behind the open question even with the switch on.
Chosen — fix it so it actually works as intended (built and proven tonight)Drop the switch, treat this as unnecessary
Confirm or override.
| PR | What it shipped | Merge commit (short id) | Test-lane result at merge |
|---|---|---|---|
| #6937 | The 18-scenario test harness itself (no behavior change) | 7db5efb | 7 already passing, 10 known gaps to fix |
| #6978 | The "nothing went out" label now says "Edited, then sent" when that's what happened | 67c183f | full suite 152/152 green |
| #6979 | Every hand-off/promise creates a tracked record; fresh question = fresh record; resolved needs a real answer | e08c528 | 9 passing / 8 gaps closed by later PRs / 0 failing |
| #7022 | Reminders that reset when the person writes back; the "tracked with reminders" message only says that when it's true | 2b478fc | 12 passing / 5 gaps closed by later PRs / 0 failing |
| #7024 | The one honest status line on a repeat ask; a kept promise stays kept instead of getting quietly softened | b1044d2 | 17 passing / 1 gap closed by the next PR / 0 failing |
| #7037 | A tour request during a parked question gets booked and confirmed to the person | c298dbf | all 18 passing / 0 failing / 0 gaps left |
| Gold mine (#7091, #7102, #7105, #7115, #7117) | Corpus, gate registry + replay switch, scorecard, reproduction lane, before/after report | f5ab9ff99d, a731107807, 1184a452c0, da9b5e4966, cd8494709d | scorecard reproduces the audit; diff N=5 each arm: promises unbacked 4→0, blocked sends 1→0, replies 14→14 |
| Proof on merged main | Final confirmation run against the finished code, before any switch is turned on for a customer | — | sweep 1: 18 pass, 0 fail (06:33–06:51 UTC) · sweep 2: 18 pass, 0 fail (06:51–07:10 UTC) · switch-off sweep: identical to today, zero acknowledgements, zero records, zero pages (07:10 UTC). Code under test: c298dbf501. |
| #7118 | The per-property hand-off mode setting (coworker/autonomous), writable only by the dry-run-by-default script | 43dcebc239 | Merged |
| #7120 | Fair-housing check records verdict, reason and duration on every message | b10fa45421 | Merged |
| #7121 | Fair-housing check reports instead of blocks under autonomous mode | 22ebaacf39 | Merged |
| #7122 | Promise-alarm email off switch under autonomous | 41780874d6 | Merged |
| #7123 | Tracked questions and reminder ladder off switch under autonomous (existing questions left alone) | a2e0bb2f6e | Merged |
| #7124 | Autonomous properties can never also hold every email for approval | 35e1564fdb | Merged |
| #7125 | Tools-catalog drift fix that was blocking all merges | ebcee8b3ea | Merged |
| #7119 | Prompt change — answer from notes, defer once, never promise a follow-up, no canned overwrite line (eighth review round) | ac928e64e4 | Merged |
| #7128 | Combined before/after results — both halves together, on production code | d9c16e5bca | Merged |
| #7126 | Hand-off no longer marks a thread human-owned at an autonomous property; silence gate checks the property setting first | — | In review |
| #7127 | Drain script for open questions at flip time; setter script refuses to switch without it | — | In review |
A live example: a caller with an old, forgotten tour on the books tried to move it to a new time. Clara found the old tour, tried to reschedule it, got told there was nothing to reschedule, and fell back to "the team will handle it" — creating two separate held emails from one phone call.
A caller at The Willows reported a slow leak and asked for a plumber. Clara told him "I'll get a work order in for you" — but no work order was ever created. The cause: a rule meant to skip filing paperwork when a caller says something like "I already fixed it myself" misfired on ordinary call-ending small talk ("Nope, that's it, thank you — have a great one"), and treated that as "problem solved, no work order needed." The promise-tracking checker caught this one correctly 21 minutes later and tried to page the team — but this was a test call with nobody real on the other end to reach. Verified since: the bug was proven with a clean pair of live test calls back to back — say a polite goodbye and no work order gets created; hang up mid-sentence on one of Clara's questions instead, and the work order does get created. Same bug, caught both ways on purpose. The fix for it is written and waiting — held for Fede's review before it merges, not yet shipped.
A second, separate investigation graded the entire "did Clara keep her word" tracking system on its real-world track record — not just tonight's incidents. The verdict: it is not ready for production as built. It has been live 9 days, rebuilt from scratch 46 times, and had four separate features you personally ordered removed along the way. Nothing in the product — no screen, no report — reads its output; the only thing it currently produces is an email to the team.
| Property | Times it fired | Actually sent to a real person | What it got right | What it got wrong |
|---|---|---|---|---|
| Camellia (real customer) | 36 | 10 outbound actions | 2 genuine catches — a transfer that rang out and a voicemail that was silently picked up, both still waiting on staff | 8 of 10 (80%) were wrong — all false "broken promise" alarms on tours that actually went fine |
| Yale (sandbox) | 21 | 12 outbound actions | — | All 12 were noise ("the team will confirm your tour"), including two exact duplicates |
| The Willows (test bench) | 104 | — | — | Bench/test traffic, not real customer signal |
Of the emails that a real person actually received (not just logged internally), roughly 6 in 10 were false alarms.
| Setting | The Willows | Camellia | Yale |
|---|---|---|---|
| Texting the caller directly when a promise is graded | — | Off (turned off tonight) | Off (never turned on) |
| Emailing the team when a promise is graded | On | On | On |
| Review-before-send gate | Off (turned off tonight) | Off (turned off tonight) | Off |
There is no single master switch that stops the team emails — turning off the review gate does not stop the promise checker from emailing the team directly, and no property-level setting currently blocks that path either.
Stop the team emails from actually sending, but keep the checker running quietly in the background so you can see whether it's improving without it paging anyone. In order: (1) silence the outbound team emails now — record the verdict, don't deliver it; (2) fix the self-serve keyword bug that dropped tonight's work order, as its own higher-priority fix; (3) decide later, once it's proven itself quietly, whether to finish building it properly or tear it out — a full removal is roughly a week of work and there are three pieces of shared code (the "we missed your call" text, the caller-facts lookup, the missed-call note) that should be kept regardless of what happens to the rest.
Silence the promise-tracker's team emails right now?
Today it still emails the team every time it thinks a promise was broken — and 6 in 10 of those emails, once you filter to ones a person actually received, have been false alarms. Silencing it means it keeps checking and keeps a record, but stops paging anyone until it's proven itself.
Yes — silence sends, keep grading (Recommended)No — leave it emailing
Recommended: Yes. It's providing more noise than signal right now, and turning off the send doesn't lose any information — every grade still gets recorded.
Once it's proven itself, should the promise-tracking system be finished or torn out?
This has been rebuilt from scratch 46 times in 9 days, and you've pushed back on its complexity repeatedly ("over engineered," "way too complicated," "i never asked for that"). The investigation lays out a concrete removal plan if you want it gone, but recommends deciding this later, after a quiet period of just watching it grade calls with no emails going out.
Decide later — watch it quietly first (Recommended)Keep and finish building it properlyTear it out now
Recommended: decide later. Silencing the emails (above) removes the actual harm today; there's no rush to decide the system's future while it's quiet and no longer paging anyone.
Should Clara be allowed to commit a specific maintenance visit time on a call (e.g. "yes, Friday morning works")?
Today she structurally cannot — that ability was deliberately left out, so scheduling happens after a human coordinates with a vendor, not live on the call. Every "can someone come Friday?" question currently has to page a human, because the honest answer Clara can give is just "the team will confirm."
Yes — let her commit a timeNo — keep scheduling as a human/vendor step (current behavior)
No default recommendation — this is a product call about how much Clara should own on the maintenance side, not a bug fix.
Camellia's "let Clara handle a tour even on a frozen conversation" switch was found turned on — was that intended?
The code's own comments say this should only be on for the internal test property and off everywhere else, including Camellia. It was found on at Camellia tonight and nobody currently knows who turned it on or when — there's no record of the change. It's been switched off for now as a precaution.
Not intended — leave it off (Recommended, matches what the code's own documentation says should be true)Intended — someone meant to turn this on for Camellia, turn it back on
Recommended: leave it off until whoever flipped it (if anyone deliberately did) confirms it was on purpose.
Held items today: The Willows had 7 holds created, 5 pending at time of writing (eschold_5963858a, eschold_9e3ed8be — one caller's failed reschedule call producing two held emails 3 seconds apart; eschold_c3e16dd6 — the toilet-leak ask, approved but never delivered because its test sink address doesn't accept mail; three near-duplicate bench-test holds; one deliberate drill). Camellia had 2 holds: eschold_acbd90a4 (still pending 2+ days — the false alarm on a tour that went perfectly) and eschold_a5175aaa (rejected by a teammate as a stale false positive from a months-old call re-graded against today).
Booking guard with no date scope: agents/clara/lib/agent/tools-leasing.ts:3991-4020. Reschedule guard's past-date filter: agents/clara/lib/agent/tools-leasing.ts:4260-4263. False-promise "live tour" filter (today-or-later only): src/lib/domain/promises/ground-truth.ts:296-301, :590. Verdict logic: src/lib/domain/promises/decide.ts:329. Review-before-send gate, bump-only/no-auto-send: src/lib/domain/escalation/bake-gate.ts:392-407; cron sweep: src/app/api/cron/escalation-hold-sweep/route.ts:11-13. Self-serve keyword misfire that dropped tonight's work order: agents/clara/lib/agent/conversation-manager.ts:986-995, skip point src/app/api/voice/call-ended/route.ts:1163. Camellia tour-on-hold flag: src/lib/domain/escalation/escalated-tour-booking-flag.ts:26-30, field doc src/lib/data/types.ts ~2960, writer script scripts/set-escalated-tour-booking.ts. Promise-ledger trigger with no staleness guard: src/lib/temporal/promise-client.ts:57 from src/app/api/voice/call-ended/route.ts:1222. Track-record tally: 161 total graded rows (104 Willows bench, 36 Camellia, 21 Yale); 22 outbound actions at the two real properties.
Confirmed in the cloud logs: on both Aug 23 and Sep 3 the topic checker judged Will's new message the same matter as the open question, so the hold stayed. "Book me a tour of 524" being called the same question as "which units face west" contradicts the Aug 23 rule that Clara always helps with what she can answer. The tour-booking-while-held switch that would have handled it exists but is off at Camellia (sandbox only).
Full evidence trail (record ids, file references, log lines) is in the session status doc; ask Fede's session for it.
Those six screen fixes were cut back on Fede's call (scope): one small change shipped ("Sent" time on Clara's email replies), the rest were parked. The work that survived is the harness below.
Fede ruled "escalate the question, never the person" on Aug 13 and Aug 21; the harness encodes that as 18 testable claims, each traced to something he said or a real incident (Will, Avery, Casimir, Hayley twice, the Aug 3 chatter case, Daniel and Raul as the two "done right" references, and a robocall thread stuck for 17 days). It runs the real code path on the test property. PR #6937 (harness only, no behavior change). Full evidence file lives in the repo at scripts/coworker-harness/results/escalation-behavior-before-2026-09-03.md; the lane is registered on the Harness Atlas.
| Status | What it covers |
|---|---|
| Green today (7) | Clara does not talk over a human who took the thread; one clean team notice per held message; a staff answer closes the matter; a staff answer becomes property policy; a simple self-serve question on a held thread is answered; Clara's own good answer is not thrown away when she escalates; a human takeover stays with the human until released. |
| Red today (10 known gaps) | a tour request on a held thread stays held even with the tour switch on; the person gets silence instead of one "checking on that specific question" line; after three reminders nothing moves up; a 100-day hold looks like a 1-day hold; a new question on an escalated thread creates no record (Avery); "resolved" can be stamped with no delivered answer (Casimir); a thread can sit escalated with no record and no exit (robocall); a guard that edits one line and ships the reply is shown as "nothing went out"; when the person writes back after the reminders ran out nothing re-arms the chase (why Will's "I'll follow up tomorrow" was downgraded); the reminder emails to the team read like bot relays with template leftovers (advisory judge). |
When the person re-asks a parked question, should Clara acknowledge it?
Today she stays silent on a re-ask, per the Aug 20 rule that's still in the code.
A — Yes, once ("we're checking on that specific question") (Recommended, matches Aug 21 ruling)B — Stay silent (Aug 20 rule, still in code)
Recommended: A. Matches the Aug 21 ruling that Clara should escalate the question, never the person — silence reads as ignoring them.
Where should "stuck after three reminders" surface?
Right now nothing moves up once the reminder chase runs out.
A — Slack post to #agent-trinity, re-armed each time the person writes back (Recommended)B — Email only, keep going on business daysC — Nothing new
Recommended: A. Puts it where the team already watches for blocked-on-Fede items, and re-arming on a new message from the person fixes the Will pattern directly.
Should a new question on an escalated thread open a fresh record?
Today's code deliberately doesn't — a second, unrelated question from someone already escalated (like Avery) gets folded into the same open matter and never separately tracked.
A — Yes (Recommended; today's code deliberately doesn't)B — No
Recommended: A. Each question the person is actually waiting on deserves its own trackable record.
Should "resolved" require a delivered answer or a human's explicit closure?
Today a sweep can stamp a matter "resolved" with no answer ever having reached the person (the Casimir pattern).
A — Yes (Recommended)B — Keep sweeps
Recommended: A. "Resolved" should mean the person actually got an answer, or a human explicitly closed it — not that a cleanup job touched the row.
Should a thread ever be marked "escalated" with no record behind it?
Today it can — a robocall thread sat escalated for 17 days with no record and no way out.
A — Yes, a promise always creates a record (Recommended)B — Allow
Recommended: A. An escalation with no record has no owner and no exit, which is exactly what stranded the robocall thread.
What should happen to the tour-on-held-thread switch?
It was turned on at Camellia today, but the harness shows it not actually releasing the tour turn on a held thread — it stays held even with the switch on.
A — Fix it so it actually releases the tour turn (Recommended; it was turned on at Camellia today but the harness shows it not releasing)B — Drop it, the new model makes it unnecessary
Recommended: A. It's already on for real Camellia people, so leaving it broken means it's silently not doing the job it was turned on for.
Everything above is a night of individual fires. This is the step back: does the whole system still match what Fede actually asked for when he started this, and if not, what's the smallest change that gets it back on track — tonight, not a rebuild.
The founding rule, in Fede's own words from Aug 13: "escalate as little as possible; when we escalate, we create a policy and learn, and the next time we don't." Everything since has been read against that one sentence, plus five rulings he made along the way: never build a review queue for a person to sit and approve things (Aug 14) — engineering is the backstop, not a human clicking approve; escalate the question, not the person (Aug 20); no quiet off-switches for a real bug (Aug 23); keep this scoped to "Clara as a coworker, and keeping her word" (Aug 27); and if Clara says she'll do something, just have her do it herself, no separate tracking system needed (Aug 29). On Aug 31 he added: the goal is to reduce noise.
Roughly 18,000 lines of code, and 13 separate places in the system that can now page a human. Some of it is exactly what Fede asked for: the question-and-answer loop with a human, teaching Clara a new rule from the answer, the three-times reminder chase, holds that only cover the one topic in question, and a bake-in period Fede asked to add temporarily while trust builds. Some of it is more than he asked for, added along the way: a system that grades whether Clara kept every spoken promise (four separate pieces of which Fede has since ordered removed), a rule that a hold never expires, a hold that fires on any fair-housing-flagged staff answer, an experiment letting Clara auto-reply as a coworker (already reverted once), and text messages sent directly to callers. The fourth planned stage of this build — letting Clara actually carry out an instruction, not just answer or escalate it — was never started; Fede paused it himself on Aug 20.
Counting every bug found and fixed across the whole build, by the part of the system it lives in: the escalation-email-and-approval-gate system, 20; the keeping-your-word (promise) checker, 20; the missed-call follow-up lane, 20; the coworker-email feature, 9; the fair-housing staff-answer hold, 8; the tour-booking deadlock, 7; who a hold is even addressed to, 7; the reminder-nagging logic, 6; holds on a thread a human already took over, 5; creating a new tracked question, 4; the same person getting counted as two people, 4; and the "did they just say goodbye" detector, 3. On top of that, roughly 30 more fixes are recorded only by a one-line title, with no detail behind them to grade.
Three parts of the system — the keeping-your-word checker, the missed-call lane, and the escalation-email-and-approval-gate — each have as many or more bugs behind them as everything else put together. That is where a rebuild-versus-repair call matters most.
Not abstractions — real staff and real prospects who felt this go wrong: two staff members' own work email auto-replying to their teammates (Aug 20); a prospect left silent for 13 days on a real question; an accepted applicant left silent for 14 days with the wrong lease dates on file; a resident given the wrong door code (Aug 29); a prospect told a made-up rule that tours were closed until a date that isn't real (Aug 30); a text sent to a prospect that nobody approved (Aug 30); Fede himself getting five broken emails from Clara in one morning (Aug 31); a false "broken promise" alarm about a tour that actually went fine, still open days later; a resident's billing call mishandled (Sep 1); a hundred and six internal emails in a single week that a human was supposed to read; a tour request stuck in a dead end (Sep 3, now fixed); a promised work order that never got created (Sep 3, fix written and held); a fair-housing question mishandled and now being reviewed by hand; a safety switch found flipped on at a real property with no record of who did it or when; and a fix from earlier that morning that was never actually turned on.
Which is the right minimum change, starting tonight?
All three keep Clara working and none of them require a rebuild. They differ in how much of the newer, bug-heavy machinery keeps actively paging people versus just quietly logging in the background for now.
A — The one-question loop (Recommended)
B — Log everything quietly for a week, page nobody
C — Just fix Camellia's contact and release the stuck conversations
Clara answers everything she can on her own. For the one thing she genuinely can't, she sends one email to one named real person and keeps working on everything else. When that person replies, the answer goes back out and is saved as a standing rule so the same question never has to be asked again. Keep active: the question-and-answer loop itself, the release-on-reply step, teaching a rule from every answer, the three-reminder chase, holds scoped to the one topic asked about, and immediate paging for anything life-safety related. Downgrade to quiet logging only, no paging, until proven: the keeping-your-word checker, the review-before-send approval gate, the fair-housing staff-answer hold, and the missed-call follow-up lane — the four parts carrying the most bugs. Remove outright: the keeping-your-word checker's own outbound messages, the flag that freezes a tour request just because something else on the thread is on hold, and the experimental coworker auto-reply feature.
Turn off paging entirely across the board for one week. Everything still runs and still records what it would have done, but nothing reaches a real person. At the end of the week, look at the log and decide what actually deserved to page someone. Safer, but it means real staff and prospect questions get zero response from the system for a week — someone else has to be covering by hand.
Fix only Camellia's escalation contact (today it's still our own inbox, not a real person) and release the conversations that are currently frozen by the bug. Change nothing else about the system tonight. The smallest possible move, but it leaves every other bug in the census above exactly as it is.
Recommended: A, the one-question loop. It matches Fede's founding sentence directly, keeps the parts of the build he explicitly asked for, and quiets the newer machinery that's carrying almost all of the bug count without turning it off for good — nothing is thrown away, it just stops paging people until it's earned the right to again.
This reread covers the build's full history and every matter/incident record referenced above; it does not change any code or setting on its own.
Who should Camellia's escalation contact be?
Today it is a PropFlow address (hello@), so every Camellia hand-off, reminder and nag goes to us and stops after three tries. Whoever is set here is the person the system chases when Clara can't answer.
A — Erika's Camellia mailbox (Recommended)B — the shared camelliaapts inboxC — keep hello@ and have PropFlow work it as a queue
Recommended: A. The chase should land on the person who can actually answer. B works but reintroduces the "already in their inbox" suppression. C only works if someone owns hello@ daily, and 4 unanswered emails say nobody does.
When a held person writes again and nobody has replied, should the team alert fire even on a shared inbox?
Right now the alert is suppressed at Camellia because the email is "already in the team's inbox." The second unanswered message proves that assumption wrong.
A — Alert on the 2nd unanswered message, to the property's Slack channel (Recommended)B — Alert on every held messageC — Keep the suppression
Recommended: A. Keeps the no-noise rule for the first message, stops the black hole after that. Same channel the "prospect emailed" cards already land in.
Post an "escalated" card to the property's Slack channel when Clara hands a question to the team?
Today only the rarer "escalate to human" tool posts that card. The everyday hand-off posts nothing.
A — Yes, every hand-off (Recommended)B — Only when the reminder chase is exhaustedC — No
Recommended: A. One card per hand-off, in the channel the team already watches. Dark first, Willows first, Camellia on your go.
Turn on tour booking for held conversations at Camellia?
The switch exists and runs at the sandbox property: a person on a held thread who asks to tour gets the tour handled while the open question stays with the team. Would have handled Will's Sep 3 message on the spot.
A — Yes, after one day watching it at Willows (Recommended)B — Not yet
Recommended: A. Matches the Aug 23 rule: always help with what Clara can answer.
When the reminder chase runs out (three nags, no answer), what happens?
Today: one log line and silence, forever. The Aug 31 decision says "marked stuck and surfaced loudly" but that is gated on the Camellia switch-on and not live.
A — Post to the property's Slack channel and to #agent-trinity, and re-arm on the person's next message (Recommended)B — Post to #alerts onlyC — Leave as is until the switch-on
Recommended: A. Attention should go up the longer someone waits, not down.
The three other stuck Camellia people: who acts today?
Avery (accepted applicant, lease dates wrong, 14 days), Casimir (toured, loved it, 9 days), an unknown caller (17 days). All need a human at Camellia, not Clara. Fede can release their holds the same way as Will's, but the actual answers need Erika.
A — Fede pings Erika with the three names today (Recommended)B — Release the holds and let Clara re-engage first
Recommended: A. Two of the three are questions only the team can answer; a Clara reply would just be another "still checking."
Should the "we missed your call" text finally ship, now that its wording needs your okay?
When a phone transfer fails to reach a real person, this fix sends the caller exactly one text so they're not left in silence. It's built and tested — it's only waiting because it's a customer-facing message, and that always needs your sign-off before it goes out. Your okay here also covers a small related risk: in rare cases the call actually did connect, but this text still goes out as if it didn't — approving the wording means accepting that occasional false text along with it.
A prospect calls to move up his tour, gets transferred, and the line answers with nobody there. Today he gets nothing. With this fix, he'd get one text like "Sorry we missed you — the team will follow up shortly." (illustrative — the exact wording is what needs your okay)
Approve the wordingSend back with changes
No default recommendation — it's customer-facing copy, so it's waiting on your read, not a system default.
Release the 16 stuck conversations?
A bug froze 16 Camellia message threads so Clara stopped answering in them at all. 13 have been frozen over a month; 3 are more recent, including one resident whose question was already answered but whose thread never unfroze — he could message today and still be ignored. Releasing just unfreezes a thread so Clara resumes answering normally — nothing gets sent to anyone proactively, it only means a new message from them gets a reply again.
A resident whose repair question was already resolved texts "thanks, one more thing…" — today that text goes nowhere. After release, Clara answers it like any other message.
Release all 16Release only the 3 recent onesLeave frozen
Recommended: release all 16. The freeze itself is the bug, not a safeguard — there's no reason any of the 16 should stay stuck.
The email Clara sends when she's promising to follow up says the same thing twice — keep it or fold it into the plain ask email?
This "I'll get back to you" email currently states the same detail twice (once as a quote, once again as a restatement) and both times adds a line saying "this needs a person to follow up" — a sentence about the email itself, not information for the reader. It's a code-level bug in one shared rendering function plus every place in the codebase that asks a person for help, so fixing it touches a lot of files.
A — Recommended: keep it, rewritten to the plain slip formatB — remove it, fold into the everyday ask email
Recommended: A. The promise-tracking behavior underneath it is sound; only the wording is broken, and the plain-slip format proven in fix #11 already fixes this exact class of problem.
Settled tonight (2026-08-31):
live for real residents done, proven, shipped in review needs your decision (above) being worked in another session on hold
Eleven fixes to how Clara acts as a coworker on the Camellia bench — what people used to run into, what happens now, and the proof behind each one. Tested on a safe test property that behaves exactly like a real one, so a "live" test there is as real as it gets short of an actual resident. Where the proof is a test run rather than a real production event, that's called out.
When staff talked to each other inside a resident's message thread, that back-and-forth could show up looking like something the resident actually said or received.
Staff chatter now renders as a clearly-marked internal note, never mixed into what the resident sees.
Shipped and confirmed live in production. 39 previously affected threads were corrected retroactively.
When a call got missed or transferred and dropped, the caller automatically got a text, and a generic "Need your call on <person>" web page went out — on every property, whether or not that property had agreed to it.
Both are now opt-in, property by property. It's on at the test property and off everywhere real, including Camellia. If Clara can't tell which property a call belongs to, it stays off rather than guessing. The team alert for a missed tour-day call is unaffected — that one still fires.
Confirmed deployed to production Aug 30. Before-picture is real: one caller got an unapproved text, and the follow-up about his call went to a mailbox nobody was reading.
A conversation that didn't sort neatly into a topic was hidden from the conversations list by default — so a real caller (from fix #2) could be invisible to staff even though he'd called in.
Every conversation is visible by default now. Hiding one is something a person chooses to do, not something that happens automatically. Old saved/bookmarked filter links still work the same as before.
Merged and live in the same production deploy as fix #2.
There was a rule that told Clara to hold off giving gate or door codes and instead tell the prospect to "wait for the automatic text" — even for someone with an already-confirmed, in-person tour asking directly.
Clara now gives access instructions immediately for any confirmed in-person tour, including a tour that was cancelled and then rebooked. A prospect booked for a virtual tour correctly gets no physical code at all — there's nothing to give them.
Merged Aug 30. Scored 10/10 in a scripted test, then re-verified with a live end-to-end run on the test property using real calls: in-person tour got the code, rebooked tour got the code, virtual tour was correctly declined with no code leaked.
If Clara answered a question and, on that same turn, decided she needed a person's help, her actual answer could get thrown away — even a real, useful one like "Yes." A resident or prospect would see nothing.
Clara's answers are now checked for real content: a genuine answer — even one word — always gets sent. A bare "I've passed this along" acknowledgment (which says nothing new) still gets held back, and the team inbox still never gets both a reply and a duplicate note.
Merged, review round clear, backed by 345 targeted tests. A live run on the test property first captured the actual broken behavior, then confirmed the fix on the real bench line after merge.
When the fair-housing compliance check flagged a staff answer, the answer was held back entirely and never reached the resident — including cases where the checker itself had errored, or misread its own verdict.
The answer now goes out either way, with a warning posted to the team's alerts channel for a person to review. The stricter rule — block a risky answer before it reaches a prospect — is untouched; this change is about staff-facing answers only.
Live end-to-end proof run on the test property: a flagged answer was actually delivered, with real logs and real warning posts. A hole a reviewer caught is now closed, and the fix is merged with that proof behind it.
An email meant for the team ("we need a human to look at this") could be sent without anyone specifically deciding to send it.
Each property can require a Slack approval step first: the ask posts to Slack with Approve/Reject buttons and snooze options, and it never sends on its own. Genuine emergencies still go straight out, by design.
Full 7-step live proof run on the test property: the hold happens, the post appears, approve sends the exact original text, reject sends nothing, an emergency correctly bypasses the gate. Review is done; waiting on the final automated check before it can merge. Turning this on for Camellia is a separate step that needs your sign-off — merging this code does not turn anything on there.
The automated test suite that's supposed to catch coworker-behavior regressions had 9 tests that failed for reasons unrelated to real bugs, and no way to replay a real incident to check whether a fix actually worked.
98 test scenarios now run, including a full replay of an entire tour day. 82 pass cleanly, 14 have known tracked gaps, and 0 fail for unexplained reasons.
This is test-infrastructure work, so its own proof is the 82/98 pass count plus zero unexplained failures, not a live call. Fixes from the earlier review round are in; now awaiting a second look.
Some transferred Camellia calls land on a personal cell phone whose voicemail sometimes answers and drops the call after a few seconds, and sometimes rings a long time before silently picking up.
Not a code bug — a property fix: either clear out that mailbox, or point transfers at a staffed line instead of a personal cell.
Investigation complete and handed off. Being worked from a different session (the voicemail handoff) — not waiting on a decision here.
The pipeline that sends questions to a person had no quiet-hours awareness, could send the same text twice, could let two contradictory checks both reach a human without reconciling, and had no daily digest of unanswered questions.
All four gaps addressed in one bundle.
Built and reviewed, but parked — it needs to be redone to match the newer Slack-approval design (fix #7) before it ships.
The emails Clara sends when she needs a person's help could read stiff or robotic — awkward phrasing, stumbling over unit and phone numbers, odd capitalization, subject lines that buried the topic.
Six specific rough edges are fixed and proven live on the test property.
In active review. The 6 fixes above are proven live; the final review round is in progress.
Both are named here on purpose — they're why the process now requires proof before merge, not after.
Shipped 2026-08-31 (evening) — investigated, fixed, and deployed the same day. Traced against real production records (DynamoDB) and the email-delivery log (SendGrid). Matter IDs: matter_227a9847, matter_0ee6659b, matter_c3ea319d, pmesc_4292fbc2.
Fede got five broken emails from Clara in one morning, all at the Willows test property, where Fede's own address is the one Clara escalates to when she needs a person. In order:
9284fd7d-1284-4440-bc6a-4fd8093e3ca1.)Exhibit 4, in more detail — the faucet email. It came from a maintenance test fixture (gen-i3-pivot-ambiguity-sink-leak-pooling.golden.json) whose whole point is to prove Clara can file a work order on her own without bothering a person. It fails because of an already-known, already-documented bug that's sat open for two months: Clara declines to actually create the work order on roughly 80% of runs (written up in docs/planning/handyman-eval-bench-isolation.md, 2026-06-30 — the cause traced to handyman.ts:100-112, a single-property code branch that isn't winning when it should). The test's cleanup step deletes its own database records afterward, but it likely can't un-send an email that already went out — that part isn't fully confirmed.
How exposed was this. This lane is turned on at Camellia, a real customer — but there it's addressed to our own inbox (hello@propflowai.co), not to any JP-Co staff member's real mailbox. So no customer employee saw any of this today. Nothing Fede answered leaked out to a real person, and none of it got saved anywhere as policy.
Fix plan (designs still pending a talk-through with Fede, in order):
Also on the table as an interim step: mute Willows by clearing its escalation-owner address and turning off nagging on the 16 open matters, so the chase list stops growing while the real fix is designed. Proposed — awaiting Fede's go, not done.
All six fixes merged and deployed the same day, each behind its own per-property switch — turned ON only at The Willows and the Yale sandbox test properties, OFF at Camellia and every other real customer. Turning any of this on for customers is a separate decision, still Fede's to make.
Live proof. The original incident — Fede's natural-light preference getting deferred to "the team" — was replayed end-to-end through production at The Willows. Before the fix: the preference was deferred to a person on 4 of 5 checks. After the fix: Clara noted the preference herself and kept driving toward the tour, across 2 of 2 replayed scenarios, 10 of 10 checks passing.
Still open. Fede's own end-to-end walkthrough from his own inbox (kickoff message already sent to him); the maintenance master switch, still awaiting his go; and a recommended follow-up — a low-frequency mailbox reconciler — since the Microsoft Graph change-notification feed is the only path inbound email takes into the system today, and two test emails are known to have vanished before ever reaching our code.
A week-long look at every email Clara's coworker lane sent to the two staff inboxes she uses in testing (106 emails over 7 days), checked against a plain-English bar for what a good internal work email reads like.
Real internal coordination emails (318 sampled from the Enron email corpus, used only as a reference for how people actually write short work emails) run: subject is about 3 words and names the real topic; body is about 50 words (roughly 4 sentences); the ask is in the very first sentence; nothing gets said twice; and there's no line commenting on the email itself (zero of the 318 said anything like "this needs someone to follow up"). About half sign off with just a first name.
One change: rewrite the three template types (the "I'll follow up" email, the tour-day email, and the escalation email) to the same plain-slip format already proven at Willows; add a check that rewrites any machine-generated or non-English text before it's allowed into a staff email; and add a cap plus a duplicate-check on sends so the same email can't go out back-to-back. After that lands, turn on the Aug 31 nag-expiry fix at Willows and re-run this same check.
Through most of August, Clara would say things on a call like "I'll text you the numbers" or "the team will follow up" — and nothing checked afterward whether that actually happened. A late-August check of real Camellia calls found roughly half of these spoken promises were broken, and in several cases the same person called back later still waiting.
A rebuild in late August added one rule: every call ends with a check that reads back everything Clara promised and either does it, or reports honestly that it couldn't. Along the way the team found and fixed real bugs, including a record of how a phone transfer ended that had been silently failing to save since mid-April.
On Aug 29, Fede simplified the design further, in his own words: "if Clara says I'll do something — just have her do it, offline — that's it." A test replay of over 1,800 real calls came back clean on privacy and fair-housing grounds, so Camellia was turned on for this the evening of Aug 29, after Fede made a live test call himself. (It's since been dialed back to off-by-default at Camellia as part of the missed-call fix above.)
A wider look at the codebase found 13 separate places that could reach out to a human, built at different times, mostly unaware of each other — which is how the same problem could page someone two or three times over. Most of those 12 other doors have not yet been migrated to the new shared design.
A feature meant to let Clara always answer a recognized staff member's email instead auto-replied to the customer's own team, on their real work inbox, five times in one day. The feature was deleted entirely rather than just switched off. Clara now only emails a coworker on a thread she started or one addressed directly to her, and a nightly check watches the real mailbox so the same failure can't recur unnoticed.
The build is tracked in four stages: Answer (done), Speak — a solid phone channel (done), Act — staff can hand her an instruction and she carries it out (deliberately paused until the design is agreed), and Keep her word — the promise work above (largely shipped).
A worked example set the bar for "Act": a prospect was told in person "we don't take vouchers," which isn't correct under Colorado law. Clara correctly refused to guess and asked the team — but Fede then had to research the law himself and walk a manager through it by hand, work a real coworker should have carried further on her own.
A routine prospect email ("I'd like a bright unit, not on the ground floor") tripped ten separate bugs in one morning: the preference got escalated to staff as if it were a question, a guard threw away Clara's own good reply, a fair-housing checker misread an internal staff note and blocked it, and a second staff reply was silently dropped. Nothing crashed — every rule fired exactly as written, and the rules were wrong for this situation. Fede's locked rulings from that day are quoted in the decisions section above. One fix (the staff-chatter display fix) is already live; the rest is still being built.
A prospect with a same-day tour asked to come earlier, then asked for the door code — and got silence on both. A phone transfer rang a manager's personal cell that picked up but nobody spoke, and nothing noticed; a promised access-code text couldn't send because the feature was off for Camellia; and a "team is handling this" hold silenced Clara on text indefinitely while the same hold expired after 3 days on voice. Three fixes shipped with proof; the fourth — whether to change the transfer destination — is the voicemail decision above.
A mid-August round of decisions fixed how a staff member's email reply reaches a resident: instead of forwarding what a person wrote word-for-word, Clara now restates it in her own voice and strips anything that would reveal who decided it — after a real reply signed "– Fede" once reached a tenant's phone exactly as written.
A separate investigation into one resident's stuck key-pickup question found that a "muted" (staff-owned) thread only lets a new message through when it's clearly about something different — so a related question could get trapped behind it. Three more Camellia residents were caught the same way, with zero notification to staff. The fix already existed; turning it on for Camellia is what first set Camellia's alert address to our own inbox rather than a real person — the same setting the section-1 decision above is about.
Status key: LIVE current and actively used · DECISIONS OPEN waiting on your pick · HISTORY answered / superseded, kept for the record.
| Doc | What it is | Status |
|---|---|---|
| escalation-deprecation-and-bake-gate | The plan behind the first three decisions above. | DECISIONS OPEN |
| escalation-false-trigger-rca (the Fabiënne report) | Root-cause report on one prospect email that went wrong ten ways in one morning. | MERGED — stub |
| rca-camellia-tour-day | Root-cause report on the tour-day dead end. | MERGED — stub |
| promise-systematic-pattern | The deep-dive behind "Clara keeping her word." | MERGED — stub |
| promise-camellia-deep-dive | Evidence pass on turning on caller-facing texting for Camellia. | MERGED — stub |
| promise-ledger | Status doc for the promise-tracking build. | MERGED — stub |
| promise-ownership-and-due-time | Who owns a promise and when it's overdue. | MERGED — stub |
| clara-coworker-map | The four-stage phase tracker. | MERGED — stub |
| clara-coworker-capabilities | Inventory of what Clara can/can't do, mid-August. | MERGED — stub |
| coworker-actions-design | Design for the "Act" stage. | MERGED — stub |
| coworker-overnight | Morning report on the Aug 20 push. | MERGED — stub |
| harness-atlas | Catalog of every test/replay rig in the codebase. | LIVE reference |
| open-pr-board | Every open code change in the main repo, owner and status. | LIVE |
| fede-priorities | Standing portfolio view of every active initiative. | LIVE |
| escalation-email-deprecation-2026-08-29 | Earlier version of the deprecation question. | MERGED — stub |
| escalation-decisions-2026-08-16 | An earlier round of escalation-system decisions, all ruled. | MERGED — stub |
| escalation-architecture-2026-08-21 | Architecture writeup as it stood in mid-August. | MERGED — stub |
| escalation-architecture-decision-2026-08-04 | An earlier architecture decision. | MERGED — stub |
| escalation-outbound-bypass-harness-2026-08-28 | A test rig for whether sends can bypass safety gates. | LIVE reference |
| muted-thread-escalations-2026-08-18 | Investigation into muted threads swallowing messages. | MERGED — stub |
| takeover-atomic-2026-08-29 | Design for a clean human takeover of a Clara conversation. | LIVE reference |
| Missed-transfer report 9/2 → rca-camellia-voicemails | Deep inspection of the last 14 days of failed call hand-offs + turn-on readiness decisions D1–D7. | DECISIONS OPEN |
| Missed-call email audit 9/16 → missed-call-audit-2026-09-16 | Why office transfers still miss and what the missed-call emails get wrong, above. | FINDINGS ONLY |