Superseded   Direction: Clara, the whole system. This page is the data appendix; its autonomous branch, evening roll-up and decision 2 are rejected.

Staff notifications and the catch-all

Current state of every way Clara reaches the team from a prospect's turn, why there are so many, where it breaks, and the one structure underneath it: the catch-all property a phone call never leaves.

Proposed — pending review. Map and options only; nothing built.  Written 2026-10-08 after the first real self-guided tour (Thomas Rossi, Northridge, Western Slope). Fede: "I thought we had simplified into one." "Something fundamental here." "Don't jump to fixing."

TL;DR

MeasuredOct 7 tour, 5 hoursTarget
Emails to the PM113
Texts to the host103
Emails that came through the after-reply backstop8 of 110
Doors that can page staff from one prospect turn5 (A–E), plus 5 more from timers and tours1
Duplicate locks that share nothing41
PRs since Aug 1 touching escalation or team notices152—
Where the tour was filedcatch-all "front door", no unitNorthridge 565-102

Two structures, one root. The noise is five send doors added one incident at a time, each with its own idea of "already sent". The misfiled tour is the catch-all building a phone call is pinned to at ring time and never leaves; every downstream tool (guest card, application, escalation header, knowledge) then fails for that prospect. The Oct 4–5 "one door" work unified host texts only; escalation emails never went through it.

Overnight, Oct 8: one team-notification engine was built and measured, and it is held for your decision. The Oct 7 night goes from 11 emails to 4 plus one evening roll-up, and silent stalls from 45 to 0. Five yes/hold decisions are in section 0.

Contents

  1. One engine: overnight stab (Oct 8)
  2. Figure 1: the doors to the team
  3. Why so many: one incident, one door
  4. Where it breaks
  5. Figure 2: the catch-all a phone call never leaves
  6. What Gera's architecture already says
  7. Options for the team meeting
  8. Test harness: every case from this night
  9. Replay numbers (year to date)
  10. Repairing Thomas
  11. Decisions for Fede
0. One engine: overnight stab (Oct 8)

Built and measured overnight, held for Fede. Nothing is live. Fede, Oct 8 02:53Z: "a single way that's not too noisy but also doesn't drop things… I'll make the decisions in the morning."

Before → after

Replay of every real conversation, Mar 30 to Oct 8TodayEngine, roll-up at day's endEngine, first note now recommended
Oct 7 tour prospect: emails to the PM110 now + 1 roll-up4 now + 1 roll-up
"I'll check with the team" and nobody was told4500
  of those, at Camellia3600
Same-day, on-site asks held until evening—60
Prod's 69 escalation emails69 sent9 now, 60 to roll-up49 now, 20 to roll-up; 0 dropped
Team emails per active prospect-day: Western Slope0.2470.2000.259
  Camellia0.0360.0680.078
  All customers0.0730.0930.112
Staff answers released to the prospect correctly18 of 1818 of 1818 of 18
Test cases from this night the engine owns0 of 63 of 6 as chosen (per topic); 6 of 6 with per-person grouping. See the test section

Prior art. How other systems hand off to humans was researched on Sep 28: Clara as a Coworker, section 9 (frameworks pause-and-ask vs. support vendors hand off whole conversations). A narrower pass on dedupe, digests and how a human reply resumes the agent is section 0a, just below.

What this means in one line. The engine ends repeats and silent drops: the 11-email night becomes 4 plus one roll-up, and the 45 dropped promises reach the team. This chain routes 9 of the 13 doors marked "fold" through the one entry point (forward tool, team note, after-reply backstop, tour status, tour alert email, two call-end checks, the call-end message); the rest are named below. Total team email does not go down, because the drops now arrive. The big volume lever sits upstream: 43 of the 69 emails had no real question or were answerable from the knowledge base (decision 5).

All numbers come from the engine's real decision code (commit e1d2cb7) and the chosen policy: one question per person per topic, at most one update a day, and a 30-minute window after a staff answer. Each property's handoff mode is as set in production today. In the first-now column, the Oct 7 row assumes the front door is autonomous, as today; with decision 3 it is 4 + 1 either way. Emails per active prospect-day counts both the emails sent right away and the roll-ups.

The rule. One entry point, involveTeam, and one lock: one open question per person per topic. A promise to check always opens or joins exactly one question, so a silent stall cannot happen. A repeat of a question still waiting for an answer never sends again; it becomes a line in that person's one evening roll-up. A staff answer closes the question and releases Clara's reply. Tour status notices (on my way, running late, arrived) are a separate kind of record with their own one-hour window, so they never swallow a question. The roll-up is part of the engine, not a separate sender.

Today: 33 ways to reach the team, 29 locks

DURING CLARA'S TURN Forward tool own check: one text per conversation "Already told a human?" check own check: property + conversation, 24 h Direct PM page + matter own check: one per call Matter + decision email own check: one open matter per conversation Escalate-to-human tool own check: one open matter Daily team note own check: person + day + wording Team-inbox notice own check: same as the 24 h check AFTER THE REPLY After-reply backstop own check: person + day + prospect's raw words Backstop staff text own check: conversation + words, 20 min VOICE: CALL END Missed transfer notice own check: one per call, 24 h Missed-call note own check: one per call Unknown-caller note own check: per tool Callback backstop own check: per matter Maintenance backstop own check: per matter Callback dial own check: per matter, 1 h Live ring / text-on-ring own check: per line, 15 min TOURS AND TIMERS Tour update tool own check: recipient + tour, 20 min Tour alert fan-out own check: tour + event (texts only) After-tour check-in own check: per tour Self-guided lockbox asks own check: per tour + day Lost slot / blocked notices own check: per slot, 120 days Team-notify engine own check: per event, forever Module send-or-hold door own check: per notice Manager inbox · host phone29 separate duplicate checks; none asks "was the team already told this turn?"
Today: 23 live ways Clara can reach the team, in four groups, each with its own idea of "already told them". 29 separate duplicate checks in all.

Proposed: one entry point, one lock

CALLERS (TODAY'S DOORS, NOW THIN ADAPTERS) Forward toolwas door A Team note toolwas door C After-reply checkwas backstop D, no own key Voice call endcallback owed, notes Host textwas door E/F Tour eventsarrival, lockbox, debrief involveTeam(intent) — the one entry point intent = person, property, the PERSON's words, reason, turn one decision: open · join · duplicate · skip one lock row: one open question per person (per topic) a promise to check always opens or joins exactly one Open — coworker propertyone question (the existing matter)email via owner chain, or text via theteam-notices Hold/Supervised/Live door Join — same question openask folded into the open questionno new email; at most one update a dayrelay turns never page Open — autonomous propertyone plain email per person per day(Constitution I.1: who, what, how to reach)digest is the engine's, not a separate job Staff reply → classifyStaffReply → matter state machine answer: question closes, lock released, Clara's reply released to the person "working on it": human owns it · no answer: the existing one-nag ladder a re-ask after the answer is a new question; KB-answerable never reaches here
Proposed: every door becomes a thin caller of one entry point. The engine decides open, join or nothing, against one lock. It delivers now, or in the evening roll-up.

The Oct 7 night under the new engine

ONE PROSPECT, OCT 7 EVENING (LOCAL TIME) → upstairs unit? 5:51p upstairs (again) 5:51p address? 5:54p address fix 1 5:55p address fix 2 5:57p PM: "sounds perfect" 6:19p ↩ ↩ ↩ host text: lock up 6:30p tour feedback 6:30p painter has key 6:31p painter key (again) 6:31p PM: "all set" 6:35p ↩ ↩ ↩ "rent it to me" 6:53p application? 6:54p PM replies 6:57p ↩ ↩ ↩ application (again) 6:58p TODAY (prod, Oct 7) 11 now · 1 text ENGINE · talk moves to the building 4 now + 1 roll-up (7 lines) · 1 text ENGINE · front door as today, all at day end 0 now + 1 roll-up (11 lines) · 1 text email sent right away folded into the one evening roll-up (nothing sent now) text to the tour host ↩property manager replies Replay of the real conversation through the engine decision (policy topic/1440/1/30, core e1d2cb7). The tour booking confirmation (one more email, a tour notice) is left out on all three rows.
The real Oct 7 conversation replayed through the engine. Each column is one moment Clara contacted the team.

What exists today, and what goes

JUN JUL AUG SEP OCT forward_to_property_manager notify_leasing_team missed-call note pm-action reminder chase retired 10-03 transfer outcome watchdog replaced 08-27 escalate_to_human capture-unknown-caller note matter + decision email reply release nag cron sends retired 10-03 notifyHumanOnce promise ledger staff outbound retired 09-29 gated-inbound notice bake gate Temporal nag sends retired 10-04 voice callback dial hangup-message backstop stale-mute sweep pm-page team-note fallthrough autonomous team note after-reply backstop escalation owner chain v1 replaced 10-07 hunt chain text-on-ring CALLNOTICE claim tour alert fan-out tour check-in ask held-first notice backstop staff text staff-loop judge self-guided lockbox ask lost-slot notice booking-blocked notice unmatched-maintenance backstop unchecked-voice-tour callback-confirmed backstop team-notify engine leasing desk team SMS retired 10-04 team notices module door self-guided notes on engine keep (the engine is built on it) stays, but routes through the one engine dead, retired or duplicate: delete already replaced
How we got here: every door and lock since June, colored by what happens to it (keep, fold into the engine, already dead, superseded).

33 doors: 13 keep (the escalation record, staff-reply release, the hold queue, live call transfer), 13 fold into the engine, 7 delete (no longer send anything, or duplicate another door). Deleting and folding removes an estimated 11,000 to 13,500 lines. The Oct 4 "one engine" covered host texts and team notices only; escalation emails never went through it, and no old path was deleted. That is why the doors kept multiplying.

All 33 ways Clara reaches the team today, with a verdict each
DoorWhat it isSize (lines)SinceVerdict
AnotifyHumanOnce ("already told a human?")1,166Aug 26fold into the engine
A2PM page + matter, "REGARDLESS"1,299Aug 26fold into the engine 2 emails/ask, inference
BMatter + decision email (openMatterAndAsk), owner chain, outbox6,399Aug 14keep
CTeam note, one per person per day1,036Sep 6keep
DAfter-reply backstop (mint + flush)535Sep 6fold into the engine
E1Team-notify engine (notifyTeam/routeTeamNotice)4,894Oct 4keep core
E2Team notices module door (sendOrHoldTeamNotice)222Oct 5keep
Fnotify_leasing_team (tour updates)1,000Jun 7fold into the engine
GReply release / relay / teaching5,659Aug 14keep
HPromise ledger staff outbound1,844Aug 26delete (no longer sends) retired #13801/#13912
IBackstop staff text94Sep 28delete (duplicate)
JTour alert fan-out (email + texts)1,324Sep 24fold into the engine
Kforward_to_property_manager tool2,319Junfold into the engine 3 doors from one tool
Lescalate_to_human tool514Augkeep
MGated-inbound team notice767Aug 27fold into the engine
NHeld-first-email notice (internal)578Sep 25keep internal
OVoice missed transfer + CALLNOTICE5,364 (slice)Sep 23fold into the engine
PHunt chain + text-on-ring3,426Sep 19-20keep live transfer
QVoice callback dial363Sepkeep Willows only
RCapture-unknown-caller note1,537Augfold into the engine
SHangup-message backstop688Sepdelete (no longer sends) yale-sandbox only
TCallback-confirmed backstop263Oct 3fold into the engine
UUnmatched-maintenance backstop181Oct 1fold into the engine
VTour check-in ask1,129Sep 25keep switch ON at Western Slope, prod read
WSelf-guided lockbox ask, alerts, host notes1,497Sep 29keep Fede 10-07
XLost-slot, booking-blocked, unchecked-voice-tour397Oct 1fold into the engine 2 of 3 default off; prod unverified
YPM action reminder chase1,520Jul 21delete (no longer sends) chase retired #16102
ZNag pass + stuck surface1,814Aug 14delete (no longer sends) sends (bookkeeping stays
AAStale-mute sweep662Sepkeep internal Slack
ABBake gate / held text queue4,804Aug 30keep
ACStaff-loop judge / owner routing244Sep 28delete (no longer sends) no prod caller
ADpm-page team-note fallthrough263Sepdelete (no longer sends) yale-sandbox only
AEMissed-call note2,164Jun 16fold into the engine
0a. Prior art, the narrow pass: does anyone dedupe asks, batch them, and close them on a reply? (Oct 8)

Extends the Sep 28 research on Clara as a Coworker, section 9. Only the three questions that research did not answer. Property-management competitors publish no escalation mechanics; "not documented" means exactly that.

Three Specifics — Lock, Digest, Resume

Scope: Answers the prior-art doc does not address: (1) one open question per person per topic + dedupe; (2) digest/roll-up batching; (3) how human reply closes and resumes.

---

1. One Open Question Per Person Per Topic + Dedupe

SystemMechanismURL
TemporalSignal handler validates `pending_request_id`; duplicates ignored.Human-in-Loop
PagerDutyDedup key: repeats update existing incident, not create new. Ack stops repeats.Incident Dedup
LangGraphNo dedupe; each interrupt is discrete. Second interrupt lacks event.Double Texting
FreshdeskNo lock; reminders time-based, escalate after SLA.SLA Reminders
Others (OpenAI, CrewAI, Sierra, Ada, Zendesk, Decagon, Intercom, Funnel, EliseAI, Realm-X)Not documented.—

Finding: Only Temporal and PagerDuty document dedupe. Neither enforces "one per person per topic" with fold-in. Your design is novel.

---

2. Digest/Roll-Up Batching

SystemBatching?Urgency RuleURL
FreshdeskYes (optional); consolidated digest.Time-based (after SLA breach).Escalation
PagerDutyNo; immediate.Real-time by problem type.Policies
All othersNo digest; point-in-time.——

Finding: Only Freshdesk (time-triggered). Evening roll-up batching not documented.

---

3. Human Reply Closes & Resumes

SystemClose MechanismIdempotentLate ReplyURL
TemporalSignal transitions state; timer expires. Duplicates rejected.YesTimer fires; late signal rejected.Signals
FreshdeskStatus "Pending" → "Open" on reply (automation).Not statedEscalation fires first; reply closes.Auto-Reopen
PagerDutyAck stops repeats; resolve closes. Second updates same.YesAfter timeout, escalates; reply still resolves.Escalation
LangGraphResume re-runs node. Second interrupt not clear.NoNot documented.Interrupts
OthersNot documented.———

Finding: Temporal, Freshdesk, PagerDuty document idempotent loops. None document roll-up + fold-in + one-evening-answer.

---

Five Takeaways

  1. Dedup patterns exist (Temporal validation, PagerDuty keys) but assume one per incident/service, not one per person/topic with fold-in.
  2. Digest batching is rare: only Freshdesk (time-triggered). No evening roll-up documented.
  3. Idempotent close loops exist but no system documents your fold-in + one-evening model.
  4. Your three-part design (one lock per person/topic, fold repeats into evening digest, human reply closes & resumes) is novel.
  5. Property-management competitors do not publish mechanism details; EliseAI's daily queue review is the closest precedent to batching.

Tuning: what counts as "the same question"

Tested with every property run as coworker, where the settings matter most. "One per person per topic" is the only setting that never left a genuinely new topic waiting until evening at a coworker property. One update a day and a 24-hour window cost nothing extra. Total team email barely moves across rows; what changes is how much is sent at once and how much waits for the roll-up.

What counts as "the same question"Updates a day on an open questionTeam emails per active prospect-day (sent now + roll-up)Prod's 69: sent now / to roll-upNew topics that only reached the team at day's endStalls
one question per person00.106 (0.081 + 0.025)40 / 2990
one question per person10.102 (0.084 + 0.018)43 / 2670
one question per person20.102 (0.084 + 0.018)43 / 2670
one per person per topic00.112 (0.09 + 0.022)49 / 2000
one per person per topic chosen10.108 (0.092 + 0.016)51 / 1800
one per person per topic20.108 (0.092 + 0.016)51 / 1800

Test cases before → after

Case (from this night)ExpectedTodayEngine, per-topic (chosen)Engine, per-person
Staff answered half a two-part ask; Clara's relay says "I'll check with the team" about the restno new email on the relay2 emails11
After-reply backstop and forward fire on one ask, 22 seconds apartone email21 same turn; 2 across two turns1
Three address corrections in 3 minutesone email at most321
Kat's 28: no re-page on the relay turn (trc-01)0 on relayfailpasspass
Kat's 28: one ask, one email (trc-03)1failpasspass
Kat's 28: a refined address is one escalation (sec-07)1fail (prod opened 4)fail (2)pass

What the two failures mean. Per-topic grouping guesses the topic from keywords. A follow-up worded differently ("unit", then "rent") lands in a different topic and opens a second email. Per-person grouping passes all six, but in the replay it left 7 genuinely new topics waiting until evening at coworker properties. Per-topic left none. The fix is to make a follow-up within minutes stick to the person's open question whatever its keywords. That is a small core change to make before merge (decision 1).

The per-topic column was re-scored at 05:00Z on the redesigned core (lock 151cad3750), by the real engine code with an in-memory store, not a live agent loop. The per-person column is the 03:30Z score, before the redesign. Mutation control: an engine that sends on every join turns the scored rows red. Of the other cases, 2 wait on adapters (a guest-card ask asked twice; a page with no question in it) and 33 belong to other lanes (wording, the catch-all filing, the "thank you" read as an answer, lockbox codes). They are listed with owners in #17723; that re-score is pushed at ef7f0ed8f7 with the failing per-topic cases marked as known defects pending decision 1.

PR chain (all held for Fede)

Bottom up: the decision, the lock, then the evening roll-up, and only then the adapters. An adapter must never merge before the roll-up, or the asks it hands over go nowhere. Every PR is labeled held for Fede, nothing is armed to merge, and nothing has a switch.

#PRWhat it doesReviewStatus
1#17715The decision: open a new question, join the open one, or nothing for a repeatbot approvedheld for Fede
2#17719The one lock and the entry point; a staff answer releases it; a store failure alerts engineering and still tells the team oncebot approvedheld for Fede
3#17736Evening roll-up 1/4: the store and the one-email composerbot approvedheld for Fede
4#17740Evening roll-up 2/4: the roll-up email kind in the team senderin reviewheld for Fede
5#17747Evening roll-up 3/4: the 6 PM property-local timerin reviewheld for Fede
6#17757Evening roll-up 4/4: a joined ask starts the timer; an ask after 6 PM goes to tomorrowbot approvedheld for Fede
7#17726Live wiring: questions are the existing escalation recordsbot approvedheld for Fede
8#17780Live wiring for the roll-up: a queued ask starts that property's 6 PM timerin reviewheld for Fede
9#17743Doors A, C, K: the forward tool and the team note go through the enginebot asked changesheld for Fede
10#17762Door D: the after-reply backstop goes through the enginebot approvedheld for Fede
11#17725Door F: tour status texts and emails to the host go through the enginebot approvedheld for Fede
12#17737Voice: the call-end message goes through the enginebot approvedheld for Fede
13#17756Door J: the tour alert email keys on the tour, so it never repeats the host noticebot approvedheld for Fede
14#17760Doors T and U: the call-end backstops ask the engine before opening a questionin reviewheld for Fede
15#17745[Decision 4] Delete the engine switch: turns it on at Situs and ConAmbot approvedheld for Fede
16#17723Test cases from this night, scored before and after (tests only)in reviewheld for Fede
17#17734Replay variant, tuning sweep, model-tier sample (scripts only)in reviewheld for Fede

The review caught real drops. Tonight the code review flagged 9 blocking defects across 6 PRs. Six of them would have silently dropped or delayed a team message: a tour status swallowing a question, a second tour status muted for a day, a forward absorbed by a stale lock, a second reschedule never told to the host, an ask after 6 PM never sent, and a staff text lost. 8 are fixed; 1 is held (#17743, below). Not in the chain yet, each with an issue or owner: delete the duplicate backstop text (door I, #17766); the PM page and missed-call note (A2, AE) and the gated-inbound notice (M); tour status rows still use a small private ledger, not the engine lock (named in #17725). Honest follow-ups after the chain: missed transfer, capture-unknown-caller, lost-slot alerts, the tour check-in ask, voice callback, self-guided host notes.

Morning decisions

  1. Merge the engine chain as the one way Clara involves the team? At coworker properties, a new ask reaches the team right away. An ask that repeats a question still waiting for an answer never sends again; it rides the evening roll-up. It is an improvement to live behavior, so on your yes it merges bottom-up with no switch. Recommend: yes. Before merge, one small core change: a follow-up within minutes joins the person's open question whatever its keywords. Today the keyword topic guess splits one ask into two emails in 2 of 6 test cases. Merge order: the roll-up PRs first, the adapters after them, never before.
  2. Camellia and other autonomous properties: first note now, or one email at day's end? "First now": the first ask of the day goes out right away and later asks join that day's roll-up. In the replay this sends all 6 same-day, on-site asks that the end-of-day option held until evening, and costs 0.010 more emails per active day at Camellia (0.068 → 0.078, and Western Slope goes from 0.200 to 0.259 against 0.247 today). Both options keep "one plain email per person per day" in spirit, with zero stalls. Recommend: first now.
  3. Western Slope front door: when a caller talks about a specific building or a tour, does the conversation move to that building and run coworker? This is your Oct 8 ruling, built as its own PR. Today the front door runs autonomous, so on Oct 7 the engine would have sent 0 emails right away (with end-of-day) instead of the 4 real questions. Recommend: yes, as the leasing-record rule in section 4b.
  4. Delete the teamNotifyEngine switch? That turns the engine's delivery on at Situs and ConAm, where it is off today. It is a customer turn-on, so it is yours. Recommend: yes, after items 1 and 2 merge and the replay stays green. Not proven there: the replay ran on Western Slope and Camellia data only, because Situs and ConAm have no team notices yet.
  5. Start a separate lane: Clara contacts the team only when the knowledge base cannot answer? 43 of prod's 69 escalation emails had no real question or were answerable from the knowledge base. The engine moves them into the roll-up; it does not remove them. Recommend: yes, a prompt-and-gate lane, not engine work.

Held with an open blocking finding, not patched again: #17743 (the forward tool and the team note). It was blocked twice for the same reason: a caller tells Clara "the team has it" when the ask was only queued for the evening roll-up. The fix is one typed answer from the engine (sent now / queued for the roll-up / already told), mapped once to both the tool result and Clara's wording. It is written up in #17773 and is the first thing to build after your yes on item 1.

How this was measured, and what is not proven

Replay. 1,353 real conversations (944 active prospect-days) go through the engine's real decision function, not a copy. The control reproduces prod's sends. A planted mutation (send on every join, disable stall marking) turns 6 replay tests red. 180 policy runs were made: 90 settings, each at production handoff modes and at "coworker everywhere". The redacted corpus stays off the repo (PII).

Model tier. The pilot's recorded model replies (two samples of 45 turns, plus the 28 mirrored cases) are routed through the engine; the model was not re-run. Through the engine, the model's own sends on sample A go from 20 to 4 now plus 17 roll-up lines. Every promise opens or joins a question (5 of 5 across samples).

Where the earlier "11 → 4, 61 of 69 kept" came from. The earlier one-sender replay (section 8) had no roll-up and no autonomous mode, so a moved email counted as "not sent". Here it is delivered in the roll-up. This is lane C's reading; the earlier run was not repeated.

Not proven yet.

  • No live agent loop ran with the engine wired in. Every test is structural, in memory.
  • The topic sorter is keywords. 46% of asks land in "other" (mostly voice fragments). A hand-check of 20 joins found 3 wrong merges out of 12 that could be judged: an address question bundled into a unit-viewing ask, and two like it. A wrong merge bundles a roll-up line; it never drops one.
  • The same keyword split shows in the Oct 7 replay. One of the "4 now" is the first address correction, opened as a new question because its words read as a different topic. With the follow-up-sticks fix it would likely be 3. That is not measured yet.
  • Unanswered questions go stale after 7 days. That is a replay assumption, not a measured value.
  • Only 1 tour-host text exists in the recorded history, so texts per tour are not measured.
  • 36 of the 45 stalls are Camellia replies promising "the team will reach out". Under Camellia's rules Clara should not say that at all. The engine catches them; the prompt should stop making them (decision 5's lane).

Review history of the core (#17715).

  • Round 1: two blocking findings. A tour status record swallowed a real question, and the "just answered" window was measured from contact time instead of answer time.
  • Round 2: the same two were still open; that push changed roll-up delivery instead.
  • Round 3: both fixed, and a new blocking finding. The tuned 24-hour setting also silenced a second tour status for a day.
  • The common cause: status notices and team questions shared one record type and one setting. One redesign split them into two kinds of record with separate windows, and required the answer time. Round 4 approved it with no findings. The one nit is issue #17732.
1. The doors to the team
Prospect turn (text, email, voice)Clara reasons, calls tools, writes a reply Clara's reply TOOL CALLS DURING THE TURN AFTER THE REPLY re-reads the words of the reply A  Plain forwardemail to the PMlock: exact question(model's wording), fails openAug 27 B  Matterdecision email, 1 nag maxlock: reuse an open matteron this conversationAug 14 → Oct 7 C  Team noteemail to the PM, sent directlylock: person + day +hash of the model's questionsSep 6 E  Host textnotify_leasing_team → Katlock: team-notices engine(the Oct 4–5 "one door")Jun 8 → Oct 5 D  Backstopif the reply says "I'll check withthe team" and no C note is queuedlock: same as C, but hashes theprospect's raw words → never matches A or CSep 6 · 8 of 11 emails on Oct 7 PM inbox · host phoneevery email opens its own tracked question G  Staff reply → classifierquestion mark anywhere → "clarify" email back to the PManswer → relay to prospect, save to knowledge"That sounds perfect, thank you!" → read as the answer (bug #17641) the relay turn re-runs the prospect's question→ backstop pages the PM with his own open question
Figure 1. Five doors from one prospect turn, four unrelated locks. Orange: the backstop, which decides from Clara's wording, not from what the prospect asked. Not drawn: timers and tour events (promise ledger, tour alerts, backstop staff text, debrief), which add five more senders.
2. Why so many: one incident, one door
DoorAddedThe incident it fixedIts own lock
F  notify_leasing_team (host texts)Jun 8, #2018Prospects updated a tour (late, arriving) and nobody told the host.none, then the engine below
G  Matter + reply releaseAug 14, #5738Ask a human and keep working; match the answer back to the question.reuse an open matter
A  notifyHumanOnceAug 27, #6373Same-call retries paged the PM twice.exact question tuple, fails open
C + D  Team note and backstopSep 6, #7196Clara said "I'll ask the team" about a balcony question and called no tool. No email went out.person + day + hash; "two doors, one key"
J  Tour alert fan-outSep 24, #11901Tour senders reached the property inbox, not the subscribed staff.tour + time
I  Backstop staff textSep 28, #13366Text-lane deflections reached the team by email only.conversation + hash of words
H  Promise ledgerOct 1, #13912Promises Clara made were paged to the PM, never to the caller.human_notify + team-note lock
E  Team-notices engineOct 4–5, #16356 + #16651"The one door": Hold, Supervised, Live gating for team notices. Wired into host texts and tour updates.its own claims
B  Owner chainOct 7, #17389A forward with nobody on file went nowhere; now it walks owner → company email → engineering.same as G

"I thought we had simplified into one." We did, for one class. The Oct 4–5 engine became the single door for team notices: the texts to a host about a tour. The escalation emails to the PM (A, B, C, D) were never routed through it, and the comment in the team-note sender still says a backstop email followed by a forward about the same ask is an "accepted, documented duplicate". 152 PRs since Aug 1 touched this area; none removed a door.

3. Where it breaks
  • Different fingerprints for the same ask. A hashes the model's question list, D hashes the prospect's raw words, B matches an open matter, E has its own claims. The same question through two doors never collides.
  • The backstop decides from Clara's words, not the prospect's. "You can rent it to me" paged the PM. Three address corrections in three minutes paged him three times. Every rewording is a new fingerprint.
  • The relay turn re-pages. When the PM answers, Clara's relay turn re-runs the prospect's original question as input. Anything the PM did not cover becomes "I'll check with the team", and the backstop sends the PM his own open question back. Every other door skips relay turns; D does not.
  • Every email opens its own tracked question. One ask, two emails, two matters, two "Staff answered" cards.
  • Everything fails open. Each lock is written with "a silently suppressed page is worse than an extra one". With five doors that philosophy compounds.
  • The classifier reads gratitude as an answer (#17641), and reads a question mark anywhere as "the PM needs clarification", so a complete answer with a trailing "would you ask him...?" relayed nothing.
4. The catch-all a phone call never leaves

Architecture map for tomorrow: /a/front-door-architecture-2026-10

Western Slope's public line rings a stand-in building called the "front door" (approved Sep 12 as a stopgap, because the rent-roll import was incomplete). It is a nameplate with no units. What happens next depends on the channel.

970 shared line ringsconversation born on "front door" TEXT VOICE Home re-decided every turnaddress in the text → listing → building Home fixed at ring timenever updated during or after the call schedule_tourre-files to the building only if thelisting is joined and it is one home joined not joined Tour on Northridgeunit 565-102, all tools work Tour on "front door"unit empty, address in unit field WHAT BREAKS FOR THAT PROSPECT guest card cannot be mirrored to AppFolio · application send falls back to "no link" and never retries successfully · escalation emails say "Property: not identified yet" knowledge is read by property id, so Northridge facts are invisible · self-guided eligibility is a property flag the front door lacks · team tour email widens to the whole company
Figure 2. Thomas Rossi called. The front door stuck for the whole call, and his tour was filed there with no unit. Jay had to tell Clara the building by email at 6:57 PM. No rule anywhere says "a tour belongs to a real building and a unit".

Footprint at Western Slope (prod, read-only, since Sep 1)

RecordOn the front doorOn real buildings
Conversations123 (115 calls, 4 texts, 4 emails)91
Leads20about 190
Tours1 (Thomas)24 (3 with an empty unit)
Escalation matters15 (11 are Thomas's)17
Escalation emails saying "Property: not identified yet" since Sep 2411 of 23; 10 are Thomas's
Front-door conversations where a real home was named and still not re-filedabout 11 of 123 (9%); the rest never named a home: maintenance, vendors, police, spam
Conversations re-filed by hand6, all by Fede on Oct 2, note "voice conversation pinned to front-door by bindHome design"

The sharpest fact. Thomas never named the address; Clara did, at 19:23:56, from the listing. The voice booking tool ran during the call with listing e4a0f0d3, which belongs to Northridge unit 565-102, and still wrote the lead and the tour on the front door with the address in the unit-number field. The right building was in hand and not used. Both confirmations (his text, the team email) said "565 Redcliff Cir" and the company name, never "Northridge". No code re-files a tour off the front door; the only re-filing in the history is Fede's six by hand.

The three other failed application sends since Oct 3 are not on the front door (buildings 392 and 163). Their failure reads "AppFolio could not be asked" and the last successful AppFolio application send for Western Slope was Oct 2; that is being checked separately.

4a. Deep inspection, Oct 8 (read-only, prod)

Short answer. Only Western Slope has a front door. Three causes, one a live bug: (1) a phone call is pinned to the dialled line when it rings and the conversation is never allowed to move, about 90% of what sits there, by design; (2) a first-time caller who books by phone had the tour filed on the placeholder because the booking tool was handed the line's own row and had no step to file under the unit's building (fixed for new calls by #17573, four hours after Thomas; unproven on a real call); (3) nothing moves anything afterward: Gera's daily tripwire was never built and the one-time move (step 5a) is still a dry run.

WRITE PATH                         PROPERTY COMES FROM                     GUARD
Conversation, phone (call ends)    the dialled line, at ring               ✗  call-ended/route.ts:831-854
Conversation, text (stored row)    thread's line; bindHome refuses moves   ✗  conversation.ts:475-524
Conversation, text (per turn)      re-resolved every turn, in memory       ✓  inbound-dispatcher.ts:2626-2656
Inquiry, save_prospect             turn home > person's home > line        ✓~ tools-leasing.ts:4229
Inquiry + tour, phone booking      listing's building (since Oct 7 23:36)  ✓~ tools-leasing.ts:9118
Inquiry, email lead                re-files if exactly one home matches    ✓~ front-door-unit-home.ts:129-175
Tour, applyTourIntent (6 callers)  whatever the caller passes              ✗  apply-tour-intent.ts:926
Tour, after-call request           placeholder has no units, refuses       ✓  postcall-tour-request.ts:215-270
PMS write (card, showing)          intent property, else listing building  ✓~ drain.ts:989
Application send                   caller's property                       ✗  guest-card-send-application-intent.ts:104
Matter (escalation, team note)     inherits the conversation's property    ✗  escalation-matter.ts:142
Later re-file / reconciler         none scheduled; hand scripts only       ✗
✓~ = guarded only when one home is already known

How much, and is it rising. Western Slope, front door / real home, per week since Sep 12 (Oct 5 = Mon-Wed).

Week ofConversationsInquiriesToursMattersAppFolio writes
Sep 1410 / 67 / 380 / 10 / 00 / 5
Sep 2153 / 246 / 260 / 80 / 10 / 59
Sep 2835 / 465 / 240 / 112 / 140 / 117
Oct 528 / 355 / 231 / 313 / 32 / 48
Front door total126231152
  • Flat, not falling: 6 to 9 front-door conversations a day; its share of Western Slope's conversations fell from two-thirds to 45% and stayed there. 115 of 126 are phone calls.
  • Nothing leaves: 6 conversations were moved by hand, no inquiry ever moved. 18 of 23 inquiries still open, 7 from the week of Sep 14. 6 people have a second card on the real home (duplicates).
  • The Oct 5 matters spike is Thomas: all 13 trace to his one tour.
  • 20 front-door transcripts read by hand: 3 named one of our homes and were missed; 0 where Clara named it and the record was not updated; 17 were vendors, residents, police, hang-ups or homes that are not ours. The switchboard mostly works as intended. The damage is split records: 14 of 126 conversations belong to someone whose card or tour is already on a real home.

Gera's design vs code today. D9 "accept the placeholder with a tripwire, a daily count of rows born under it" (Sep 10, "this week"): not built, no cron references the placeholder. Re-key script "once, after step 5a": enumerator, revert, census and dry-run plan exist (#7622, #7754, #14218, #17376), no apply. `home_unknown` / refusal states: none in code.

Options. (A) recommended, a hard rule at write time: no tour, AppFolio write or application may be created on a placeholder; it is created on the listing's building, as #17573 now does for phone bookings, extended to the other five tour callers and to application send; when no home is known, refuse and ask "which home?" instead of filing on the line; build Gera's daily tripwire as the alarm. Fix, no switch, about 1 to 2 days as 2 small PRs, plus a one-time cleanup of 23 cards, 1 tour and 2 failed intents with the existing preview/apply scripts (Fede's go on prod data). (B) nightly re-filer: contradicts #9579 (moving rows broke the tour-to-card join) and D9; only 3 of 20 sampled were resolvable anyway. (C) delete the placeholder, conversations belong to the company: that is step 5a, Gera's lane; doing it early breaks conversation keys and call-ended creation and orphans the line's knowledge, settings and voice cache, which live on the placeholder row.

Method: read-only prod scans by property id and by org id (both gave 123 live front-door conversations, 23 cards); tours and matters scanned across the 30 Western Slope property ids; transcript sample seed 20261007. Full report in the session scratchpad.

4b. Where should the rule live? Architecture and options

Today. The line a call rings on becomes the conversation's property. Every tool then reads "the property" off the conversation and passes it down. Leasing records inherit it. There is no separate idea of "the home this prospect is talking about" that a record must carry.

TODAY (phone)                                         TARGET (any channel)
office line rings                                     office line rings
  └─ conversation.property = line (never moves)         └─ conversation.property = line (fine, can stay)
       └─ tool gets conversation.property                    └─ HOME resolved from what the prospect says
            ├─ inquiry.property  = line  ✗                        (unit, listing, address), per turn, every channel
            ├─ tour.property     = line  ✗                        ├─ inquiry.home  = real home   (required)
            ├─ PMS write         = line  ✗ fails                  ├─ tour.home     = real home   (required)
            └─ application       = line  ✗ fails                  ├─ PMS write     = real home
                                                                   └─ application   = real home
Text today already does the "HOME resolved per turn" half in memory; voice does not; nothing requires it on the record.
OptionWhere the rule livesWhat it catchesCost / risk
L1 Guard at each creatorA check inside the 4 places that write inquiries, tours, PMS writes, applicationsEvery known creator todaySmall (2 PRs). Distributed: the 5th creator someone adds next month has no guard. Patches the symptom at each door, the pattern this retro is about.
L2 Fix the input: resolve the home per turn on every channelThe turn resolver. Voice tools receive the resolved home like text does; call end re-resolves once moreThe voice gap that produced ThomasMedium. Fixes the cause for phone, but still trusts callers; a tool that passes the line through is still allowed to write it.
L3 Data layer refuses: leasing records require a real homeThe save functions for inquiry, tour, PMS intent, application intent reject a placeholder, hard fail, like the isolation floorEvery creator, present and future, every channel, including scriptsMedium. One rule, one place, impossible to bypass. Needs L2's resolution so voice has a home to give; otherwise phone bookings fail loudly until it lands. This is Gera's "tours are born on the home" made enforceable.
L4 Reconciler after the factA nightly job re-files placeholder records whose transcript resolvesSome of today's 23Rejected by the inspection: moving rows broke the tour-to-card join before (#9579); only 3 of 20 were resolvable.

Recommendation: L3 with L2 as its enabler, in that order of design and the reverse order of shipping. Decide that a leasing record requires a real home at the data layer (L3). Ship L2 first so voice can supply one, then L3 so nothing can ever write the line again, then the daily zero-count as the alarm. L1 alone is one more patch at one more door. This touches Gera's portfolio model (home vs line), so the decision is shared with him; building is the leasing lane's.

Gera's lane (Smith, bridge, Oct 8 02:58Z): no conflict with the portfolio design; three conditions on any build. (1) Detect the placeholder with the existing company-line umbrella check, not a placeholder stamp: the live front-door row carries none on purpose, so a stamp-based guard would be dead on the one line it exists for. (2) The daily count leaves conversations out and says so in the PR body; they legitimately live on the line. (3) The refusal surfaces as a named "home unknown" result that makes Clara ask first, never a silent skip. His design's interim ("tours land on the umbrella calendar") is superseded by the ruling and gets one line updated in the same PR.

Decision asks: (1) L3+L2 as the rule, or L1 now? (2) cleanup of the 23 existing cards and Thomas's tour: with the preview/apply scripts, or leave until step 5a?

5. What Gera's architecture already says

The portfolio design (portfolio-architecture-how, Oct 2) already rules on both halves:

  • "Tours and work orders are born on the home." "Only bindHome ever writes that home."
  • Before the home is known: "application_link → refused: home_unknown". "There is no company-level 'home not yet known' bucket a work order can be filed into."
  • The umbrella is accepted "with the tripwire", to be re-keyed once after step 5a: "every tour it books lands under the umbrella where the tripwire counts it." Its umbrella is the proto building; the provisioning script notes the re-key will not catch the real front door unless told.
  • One resolver walks address → customer → function → person → home, on every channel.

So the catch-all is not a surprise to the architecture; it is a known interim that has now paged a customer. The fix direction is already decided there. What is not decided is when, and whether voice gets the same resolver as text before step 5a.

6. Options for the team meeting

Notifications

OptionWhat changesOct 7 would have beenRisk
N1. One sender, one lock (recommended)Every staff contact from a prospect turn goes through one sender keyed on person + open matter + the prospect's ask. The backstop shrinks to a yes/no "was a human contacted this turn"; if yes it is silent, if no it sends once. Corrections to an open ask edit the matter instead of emailing. Doors C and D delete; A and B become callers of the one sender.3 emails: upstairs 2-bed, lockbox key, application + co-signer.Largest diff; needs the year-to-date replay as proof. Four PRs: sender, callers, delete C/D, delete the old locks.
N2. Shared turn-level claimKeep the doors; add one claim per turn that every door checks before sending.About 6 emails: kills the A+D duplicates, keeps the wording-triggered ones.Fifth lock. Fede: "we keep making this mistake."
N3. Delete the backstop onlyRemove D. Accept that a reply saying "I'll check with the team" with no tool call stalls silently; add a harness check that fails the reply instead.3 emails, but the Sep 6 balcony case regresses unless the reply check ships with it.Cheapest. Silent stalls are the other failure mode Fede named.

Catch-all and voice

OptionWhat changesThomas would haveRisk
P1. Tours are born on the home, every channel (recommended)One invariant where every booking lands (apply-tour-intent): a tour needs a real building and a unit, or booking asks for the address. Voice gets the same per-turn home resolver text already has, so the home is known before the booking tool runs. Matches Gera's "born on the home" and "home_unknown refused".Tour on Northridge 565-102; application sent after the tour; escalations named the property.Voice resolver is new code in the call path. Gera's lane; needs his yes on sequencing with step 5a.
P2. Reconcile at call endKeep the ring-time home; after the call, re-file the conversation, lead and tour to the home named during the call.Same outcome, 10 minutes later.Two states to keep in sync; mid-call tools still see the front door.
P3. Keep the umbrella until 5aStatus quo plus the tripwire count on the go-live page.Repaired by hand each time.Every Western Slope caller is Thomas until 5a.
7. Test harness: every case from this night

Fede: "include all of this in the test harness." Each case is a named fixture with the expected behavior; cases main still fails are marked known-gap so the check turns red the day they pass by accident.

#Case (from the Oct 7 trace, UTC)ExpectedWhere
1PM answers 00:57:50; relay turn says "I'll check with the team" about the unanswered half; backstop re-pages 00:58:04zero staff emails on a relay turncoworker harness, PR pending
2"You can rent it to me" (no question) pages the PMno staff contactcoworker harness
3backstop 23:51:20 + forward 23:51:42 on one askone emailcoworker harness
4three address corrections in 3 minutes, three emailsone or nonecoworker harness; #17636 pins the count
5tour booked on the catch-all with empty unit and address in the unit field (voice)tour lands on the real building + unit; application runs in AppFolio mode; header names the propertytour harness, new
6"That sounds perfect, thank you!" + signature read as the answernot a decision#17642 (it.fails), issue #17641
7PM writes "you can identify the property internally as Northridge"conversation re-filed to that propertycoworker harness
8self-guided tour gets a host debriefnone for self-guided#17648
9"call me tomorrow" after the tour → three "I'll check with the team"host texted once, one promise sentence#17648
10lockbox code asked for before arrivalsent at once, host told once#17618, #17647
11self-guided email offers "between 12:00 AM and 11:30 PM"no time range; book what they askPR pending
12staff reply with a cell number saved to the public knowledge basefact saved, number dropped#17645
13PM's full answer ends with a question for the prospect; Clara emails the PM "here is what I'll pass along" and relays nothing; "That sounds perfect, thank you" then relayed as the answerdraft-then-go: Clara drafts, asks the PM "want me to send that?", sends the stored draft word for word on his yes#17671 (held for Fede, design option D); replay of the real exchange 5/5
14Clara offers Thomas a tour of #204 while he is standing in #102 on a tournever offer a tour to someone touring now or today#17670 (fix, armed)
8. Replay numbers (year to date)

Structural tier, final (no model; 1,311 real conversations, 666 people, Mar 30 to Oct 8). The control reproduces 66 of the 69 escalation emails prod actually sent and adds none; staff-reply release and matter state agree 18 of 18. So the test bed is trustworthy for "what would each rule have done to the emails we really sent".

VariantOf prod's 69 emails, still sentFolded or attached insteadMatters avoidedOct 7 prospect (prod: 11)
Control (today's rules)66009 (the 2 missing are the backstop repeats, which share a key with nothing)
One thread per person per day4424111 sent, 10 folded
Attach to the open matter60874 sent, 7 attached
Smarter staff-reply classifier66009; every recorded staff answer already read as an answer, the "thank you" case is new

Two replay runs, read them apart. The table above is the merged engine (#17667) with prod's backstop NOT modeled, so it reproduces 66 of 69. The overnight lead's run models the backstop and reproduces 69 of 69; it is the one that scores N1 (Oct 7: 11 → 4 emails; 61 of 69 kept, nothing new sent) and "N1 + one thread" (11 → 1). Its full per-rule table, dataset counts (1,353 conversations, 389 escalation points, 45 silent stalls) and the model-tier pilot live in leasing-engine-designs §54; this page stays the decision page.

Corrected Oct 8 02:40Z: the first run dropped staff answers on folded asks (review finding, fixed in #17667 before merge). "Attach to the open matter" moved from 57 to 60 kept, and the Oct 7 row from 1 to 4 sent; the one-thread row did not move. The 3 control misses are all prod sending the same forward twice within minutes. None of the variants sends anything prod suppressed. What this tier cannot see: emails a new rule would ADD, and the words Clara would say. That is the model tier, running now on a sample, scored for agreement with prod and with itself. Year-to-date pattern by customer: Camellia's failure is 36 silent stalls ("I'll check with the team", nothing opened); Western Slope's is noise (202 decision points, 274 staff replies in 229 conversations). Only 15 staff-answer relays exist in the whole history. Replay tooling: PRs #17665, #17666, #17667 (test and tooling only). The redacted dataset stays out of the repo until it passes a strict independent PII read.

9. Repairing Thomas

Done (Oct 8, 03:45-04:01Z, on Fede's "repair, make sure the application is sent"). Nothing was sent to Thomas, Jay or Kat; the conversation was not split or moved.

RecordBefore (Oct 7 evening)After (Oct 8, 04:01Z)Proof
Inquiry + tourFiled on the front-door placeholderFiled on Northridge, unit 565-102tour row propertyId appfolio-403
AppFolio guest cardFailed 10 times ("account could not be resolved for western-slope-front-door")Card 2997 on Northridge, source Phone Call, created 03:45Zoutbox row sent, attempt 11; mirror shows the card under his name
Call noteParked behind the failed card, would never have sentBooking-call summary posted to card 2997 at 04:00:49Zoutbox row sent
Application linkMarked "no link configured", never attemptedMark cleared; walker reached the send step and held it for quiet hours (Colorado night). Goes out on its own after 8 AM MT; a watcher confirms.walker log: send_application_deferred_quiet_hours
Past showingFailedLeft failed on purpose (would create a past appointment)-

Two outbox bugs this exposed, fixed in PR #17753 (bug fix, no switch; issues #17748, #17749; remaining raw-id paths tracked in #17755): (1) the card sender swaps a front-door booking to the real building for the property check but still sends the front-door id when it creates and looks up the card, so every front-door booking's card fails; (2) a call note linked to a card request never sends after the card later succeeds. Both needed hand scripts tonight.

Not in AppFolio: the "painter has the key / very interested" note from his text thread was never queued by the system, so there is nothing to release; it is a product gap, not a stuck row. Scripts live in the thomas-refile worktree; every write was ledgered.

9a. Incident: the Western Slope AppFolio robot went down and nobody was told
WhatFact
StartOct 7, 3:38 PM MT (robot heartbeat; Sentry issue 7779768172, 129 events by 7:54 PM)
ScopeWestern Slope only. Camellia/JP&Co: no failed probe in 14 days, application link sent 11:30 AM MT. Situs: nothing in flight.
Error"session probe was ambiguous": after login the robot loads one property page to prove the session; AppFolio now answers with a redirect back to that same page. The robot does not recognize that answer and stops rather than act while possibly signed out. A human browser follows the redirect and sees nothing wrong.
CauseMost likely an AppFolio-side change. Probe code unchanged since Sep 9-10; nothing deployed near the start time; not linked to the Oct 6 PMS engine split.
Cost9 Western Slope guest-card writes failed for good, 3 still retrying. No showings and no application sends sat in that queue. Thomas's repair steps 2-4 blocked.

Why no alert reached anyone.

  • The heartbeat reported the failed probe every few minutes at info level. No Sentry rule pages on a repeated info note.
  • The session health check decides by loading the AppFolio dashboard, which still loads. It also waits for a status word the robot never sends ("failed" vs "refresh_failed").
  • The queue's final give-up alert landed on an older Sentry issue from 2:30 PM (same fingerprint as the "front door has no AppFolio property" error), so it read as more of the same.

Fixes. Ours, shipping as a bug fix with no switch: failed queue rows retry on their own once the session is healthy, up to 72 h, instead of waiting for a person to run the redrive script. Asked of the robot's lane (Smith, bridge thread): accept the self-redirect or fall back to a real re-login; page on repeated failed probes per account; health check reads the probe result, not the dashboard; the outage gets its own Sentry fingerprint.

10. Decisions for Fede
  1. Notifications: superseded by section 0, decision 1. Earlier options: N1 one sender, one lock (recommended) / N2 shared claim / N3 delete the backstop. Yes to N1, or pick?
  2. Catch-all, the leasing-record rule. Fede, Oct 8 02:50Z: "if they are talking about a specific property, especially with a tour, we should never allow it to be on the front door." Conversations on the line are fine; a leasing record on the line is the defect. Where the rule should live is the open decision: options L1-L4 in section 4b, with a recommendation. Nothing is built.
  3. Thomas: done on your yes (section 9). Card 2997 and note are in AppFolio; the application link sends after 8 AM MT.
  4. Staff-answer relay, option D (draft-then-go): PR #17671 is built and held for you. Merge it as the new relay behavior, or hold? (#17671 changes how Clara handles a PM's answer; it is an improvement to live behavior, so on your yes it ships with no switch.)
  5. Application links at Western Slope: none has gone out since Oct 2. Five prospects since Oct 3 got none (fresh prod read Oct 8 02:30Z): one has no phone or email on file, one is unexplained (reason not stored, #17692), two were refused by AppFolio because the unit is not on the client's vacancies list, one is Thomas on the front door. The two vacancies-list cases are the client's data: tell Jay which two homes are missing from the list? Yes / hold?

Nothing on this page is built. The harness cases ship regardless as test-only PRs.

PropFlow Docs