PARTLY UNVERIFIED — some statuses on this page were HELD, not measured The last refresher tick could not read some of the pull requests these rows point at, so it HELD their statuses rather than downgrade them. A held status is not a measurement that nothing changed. Unverified since · the “last refreshed” stamp on this page is the last time a status MOVED, not a claim that anybody checked since.
AUTHOR’S WORD — 8 rows here show a completed status that nothing derived The pill on these rows was typed, not measured: ws-microsoft-verified-publisher, lp-scraper-live, tb-portfolio-bench, k9-api-key-secure-link, modules-western-slope-leasing-only, ws-twilio-sms-url, ws-tour-length-30-2026-09-17, ws-renewals-preview-flip-2026-11-03. Every other status on this page comes from that row’s own PR, commit or decision links; these name nothing a machine can read, so nothing can contradict them when the work changes. To make the same claim checkable, write one of these on the row and it derives on the next tick: prs (a PR ref — read from GitHub), completion_evidence (owner/repo@<full 40-char sha> — checked against the default branch), shipped_without_pr (why no PR can exist), or decision (the id that settled it). A row that is not owed a build says so with unbuilt; one a decision retired says so with canceled.
Western Slope go-live

Western Slope go-live

Western Slope live on the portfolio model: one number, one mailbox, 14 properties, guest cards working

Status is DERIVED from each row’s own PR, decision and prod-evidence links by bin/refresh-tracker western-slope-go-live — never typed. Last refreshed 2026-11-05 12:32Z.

Western Slope's issue list, Sept 21: our version — our internal read of Jason's Sept 21 email, item by item.

On this page

Renewals at Western Slope: supervised, communications only

Proposed — pending Fede's review. Written 2026-10-08 from the 10/7 Western Slope call, the 10/7 team call, the 9/30 and 10/5 calls, and the code on main. Investigation only; nothing built, nothing sent. The 10/3 plan below it is kept for the record.

Superseded on 2026-10-12 by Renewals, end to end: levels of autonomy: the week-by-week plan and the six decisions live there, and the step order below changed (paperwork is no longer tied to Live; the office sends it at Western Slope until Jay’s AppFolio templates are set). This section is kept for the record.

TL;DR. Jay and Fede agreed on the call: Clara handles the renewal conversation, their team sends the paperwork, and their team gets a heads-up they can stop. Gera’s Off / Supervised / Live gate exists and already holds every message Clara writes. Three things do not exist yet: running the conversation without the AppFolio offer, their team approving (today only we can), and the heads-up list. Because Supervised still creates the AppFolio offer and AppFolio emails the tenant while Clara’s text waits, “turn it on with everything held” is not safe at Western Slope yet. A practice run that sends nothing can happen tomorrow with a script we already have.

The ladder

flowchart LR
  A["Off\n(today)"] --> B["0. Practice run\nnothing sent\nlist emailed to Fede, then Jay/Kat\nthis week, no code"]
  B --> C["1. Supervised, team sends paperwork\nClara texts/emails, their team approves,\nKat sends the AppFolio document\n(the missing step)"]
  C --> D["2. Supervised, Clara sends paperwork\nwhen Jay's templates are set\nper building in AppFolio"]
  D --> E["3. Live\nCamellia today"]
  style C fill:#fff3cd,stroke:#b45309

What Supervised does today

flowchart LR
  S["8:00 daily check\nopens a renewal\n90 days out"] --> P["AppFolio robot\ncreates and sends the offer"]
  P --> AFE["AppFolio emails the tenant\n'ready to sign'  ⚠ not held"]
  P --> T["Clara's offer text,\nletter, reminders, replies"]
  T --> H["Held: eschold row\nSlack card + /review page\nexpires after 24h"]
  H -- approve --> SEND["sent as written"]
  H -- reject / any other word --> DEAD["dropped, reminders stop"]
  style AFE fill:#fde2e2,stroke:#b3261e

Every renewal message Clara writes is held when the building (or company) is Supervised: offer text, letter, reminders, lease-ending warning, term-change text, the no-phone email, and her replies. A backstop at the send door refuses anything unapproved. But the offer itself is only refused when Renewals is Off; nothing between the daily check and the robot reads Supervised. There is no path that runs the conversation without the AppFolio offer: every send waits for the offer, the letter is pulled from AppFolio, and the copy says “review and sign in your portal.”

The design: a renewal is a conversation plus a paperwork step

Fede, 2026-10-08: “love this.” Who does the paperwork is a per-company answer, Clara or their team. The conversation is the same either way.

flowchart LR
  D["Daily check
opens the renewal"] --> C["Conversation
offer text · reminders · replies
(held when Supervised)"]
  D --> W{"Who sends
the paperwork?"}
  W -- Clara --> R["AppFolio robot
creates and sends the offer
(Camellia today)"]
  W -- their team --> T["Marked 'paperwork with the team'
Kat sends it in AppFolio
sync closes the renewal when she does"]
  R --> C
  T --> C
  style W fill:#fff3cd,stroke:#b45309

Today the paperwork is welded into the conversation in five places: the workflow waits for the offer before it says anything; the daily check always queues the robot; the letter text pulls the PDF from the AppFolio offer; the copy says “sign in your portal”; and Clara’s term-change tool writes to AppFolio directly. The seam:

This is the lane 10 shape: the AppFolio write is a side effect behind an interface, and “their team does it” is the no-op adapter. It builds on Gera’s gate, not beside it, so Gera sees this before the first PR. Size: about three small PRs on the workflow plus one for copy, all dark behind the default-off setting, proven at Willows.

What we already have for the customer to approve

MechanismHoldsWho can approveFits the ask?
Held messages on /review (and the staff page under /admin)Every renewal text and email under SupervisedA company admin at their own buildings, or us. Property managers see the buttons and get a 403.Closest. Missing: the “open” links go to our staff-only page; no batch approve; “hold” means reject; unapproved items die after 24h, which breaks a weekly review; held items don't show on the renewals board.
Slack card in #western-slopeSame itemsSomeone whose Slack email matches a PropFlow admin loginNo. Mention is hard-coded to Fede; the reply route received zero events 9/19–10/7; any word that isn't “approve” rejects a renewal text.
Renewals board /leasing/renewals + lease pageRenewals held by the eligibility checkAny workspace member, scoped to their buildingsPartly. Approve starts a renewal (and the offer); there is no view of held messages and no per-message hold.
Decision queue on /review (five feeds)Tenant claims, vendor outreach, past-due reminders, renewal corrections, new leasesAny workspace memberPattern only. Finished DataTable + drawer; renewals holds are not a feed here.
Gera's Customer Approvals Plan (published 10/8; part 1 merged 10/9)Every held messageTheir company admins, by email link + pageThe right home. One switch per company, an email per held message, a customer-facing held-message page. Renewals ride it; we don't build a second queue.
Leases-ending digest emailNothing; information only—Pattern for the weekly list. Off by default, no link back, sent to the renewal contact.
Read-only replay of their real leases (scripts/renewal-harness/replay/real-book.ts, merged 10/2)Nothing; simulates 10/5–1/31 under a policy file—The practice run. Writes are blocked by construction; output is the per-lease list.

Gaps, in order

#GapSizeOwner
1Conversation without the offer. One company setting, “Who sends the renewal paperwork: Clara in AppFolio / your team” (a new capability a customer can want off, so it may have a switch; Camellia stays as is). When “your team”: the daily check opens the renewal and Clara's texts go out without the robot; the copy says Kat will send the paperwork instead of “sign in your portal”; the letter leg is skipped; Clara's term-change tool stops writing to AppFolio. Folds the unused held_review entry mode and the no-template dead end.One small PR chain on the renewal workflowLane 11, on top of Gera's gate
2Their team approves. Part 1 of Gera's Customer Approvals Plan: the company switch, the email to their admins, a held-message page they can open. Plus three renewals-specific fixes: a parked state instead of the 24h expiry, approve-all, and held texts shown on the renewals board. Update 10/9: part 1 merged overnight (reviewers per module #17999, email to reviewers with reply tag #18014, emailed approve/reject through the one staff-reply door #18059, reviewer opens and decides with their own login #18046, the door asks back when a reply is unclear #18080). Not yet done for renewals: the parked state instead of the 24h expiry (#16593 makes a held renewal offer expire unapproved after 24h), approve-all, held texts on the renewals board. Naming Kat and Jay as Renewals reviewers at Western Slope is the turn-on step and is Fede's call. Decided 10/9 (Fede): one batch email on the 1st of each month, see approval cadence.Gera's part 1 + small follow-upsGera; lane 11 for the renewals bits
3The weekly heads-up list (shape open; Fede 10/8: “needs a bit more thinking”). Three things to settle first: (1) silence must not become a send in month one, so it starts as approve-all-or-strike, opt-out only after a month of clean batches; (2) it is the decision gate (who, what terms) and Gera's door is the wording gate, so Kat never approves the same renewal twice, and the list is what survives into Live; (3) it lands as the agenda for their weekly renewals meeting, sent the day before. Original idea: “Here are the leases Clara starts next week and the terms your policy gives them; reply or open the page to stop one.” Reuse the leases-ending digest shape with a link into the page from gap 2. This is Jay's “heads-up we can stop,” which is the opposite of today's hold-until-approved.One PR once gap 2 existsLane 11
4Basic edits before send (rent, term). Not built. The “offer renewal” click takes only the tenant; rent and term come from the policy. Once gap 1 exists an edit only changes the text, not an AppFolio document, so a rent and term override on the held row is small. Gera’s plan already lists “Ask for changes” as a later part.Small, after gap 2Lane 11
5Policy answers wired. The Renewals › Offers answers save straight to live settings; the Renewals › Follow-up answers (hold rules, escalation owner, notice routing) are stored and read by nothing. Sean filled the form on the call; we copy the answers in by hand this week.Hand step now; reader laterLane 11

Approval cadence: one batch email on the 1st of each month (Decided 10/9, Fede: (a))

Fede 10/9: “I don't know if I like the one email per approval… it makes more sense to batch it… all the ones that are coming into the 90-day eligible window, which ones are held and which ones are going to go out and the terms.”

What the real lease dates say (read-only pull of Western Slope today, 180 active tenants; Lincoln and Courtyard left out). Every lease ends on the last day of a month, so the 90-day window opens on about one day a month. Per-message email would mean nothing for weeks, then a burst. Weekly batches would be empty 12 weeks out of 13.

WhenLeases entering the 90-day windowEmails to Kat under per-message (offer + 2 nudges in week one, plus one per tenant reply)Under one monthly batch
Day one (already in window)1414 the first morning, ~40 over the first ten days1
Oct 1722, then ~6(in the Nov 1 list)
Nov 288, then ~241
Nov 3077, then ~211
Dec 3199, then ~271
Every other day in the 90 days00 new (replies and late nudges only)0

Lease ends per month, so the batches ahead are visible: Oct 1 · Nov 6 · Dec 7 · Jan 10 · Feb 7 · Mar 9 · Apr 10 · May 21 · Jun 16. Also 40 leases already past their end date (decision E6, pending) and 13 with no end date (month-to-month, never scanned).

Recommendation: one batch email on the 1st of each month. It lists every lease whose window opens that month: unit, current rent, offered rent and term from their policy, and whether it will go out or stays held (balance, Section 8, no end date). Approving the list pre-authorizes the offer and its scheduled nudges; only a tenant reply that needs a decision (a counter, a move-out, a complaint) still comes through Gera's door as a single email. Weekly is the same email with mostly empty weeks; per-message is the burst pattern above.

Decided 10/9 (Fede): (a) monthly on the 1st. What it changes: the held-offer 24-hour expiry (#16593) becomes a parked state until the month's batch is approved; approving the batch covers the offer and its scheduled nudges; a tenant reply that needs a decision still goes through Gera's door one at a time. Handed to Smith on the bridge 10/9. Fede 10/9, second ruling: no setting. The monthly list is the only way Supervised renewals are approved, for every company, live on merge (no customer is on Supervised today, so nothing changes until Fede flips Western Slope). The first list goes out the day a company's Renewals gate is switched to Supervised, covering everything already in the window; then the 1st of each month. A one-line re-send command exists for a lost email. Build: lane 11, a chain of small PRs.

The monthly email: three layouts to pick from (10/9, after Fede saw the first sample)

Fede 10/9: the table version was "very crowded, doesn't tell you who the tenant is." Below, the same 7 Fairhaven leases in three layouts. Names are mock. All three keep the same door: one reply or one click approves the list. Recommendation: A. It reads on a phone, names the tenant first, and groups by building the way Kat thinks about the portfolio. B is the same for small months. C hides the terms Fede wants Kat to see before she replies.

A. Cards by building (recommended)
Subject: 7 renewals to approve at Fairhaven for October

Hi Kat,

7 renewals go out this month. Nothing needs a decision; reply approve or review the list.

Review the list

Building 23
Jordan P. · U028
Lease ends Nov 1 · $1,293 now, offered $1,293 for 12 months
Building 27
Maya R. · U071
Lease ends Dec 1 · $2,395 now, offered $2,395 for 12 months
Luis A. · U075
Lease ends Jan 1 · $2,595 now, offered $2,595 for 12 months
… 4 more in Buildings 16, 22, 24, 25
Not going out
Sam K. · Building 20, U021
Held: balance on the account

Reply approve to send them all, or reject to hold them all. Whoever answers first decides.

B. One line per tenant
Subject: 7 renewals to approve at Fairhaven for October

Hi Kat,

7 renewals go out this month, all at current rent for 12 months.

Review the list

Jordan P., Bldg 23 U028 · ends Nov 1 · $1,293
Maya R., Bldg 27 U071 · ends Dec 1 · $2,395
Luis A., Bldg 27 U075 · ends Jan 1 · $2,595
Priya N., Bldg 16 U017 · ends Jan 16 · $1,600
Chris D., Bldg 22 U023 · ends Jan 1 · $914
Ana M., Bldg 24 U048 · ends Jan 1 · $1,600
Omar T., Bldg 25 U057 · ends Jan 1 · $1,293

Not going out: Sam K., Bldg 20 U021 (balance on the account)

Reply approve to send them all, or reject to hold them all. Whoever answers first decides.

C. Summary only, details on the page
Subject: 7 renewals to approve at Fairhaven for October

Hi Kat,

7 renewals go out this month at current rent for 12 months, in Buildings 16, 22, 23, 24, 25 and 27. 1 is held for a balance.

Review and approve

Or reply approve to send them all. Whoever answers first decides.

Common to all three: the greeting, button and sign-off come from the email shell our other emails use; the per-message reviewer email is the voice. Month-to-month tenants are not listed. No explanation of what Clara does after approval. Sent to the named reviewers (Kat, Jay) at their work addresses.

Reply words. Today's door accepts approve / approved / send / send it and reject / do not send, and asks back on anything else. The batch adds one shape: approve, hold <unit> (and hold <unit> alone). Anything else, Clara asks back, as today.

Open for Fede: (1) the page link opens one list with a tick per row, not one page per lease (today's reviewer page shows one message; the list view is new); (2) held rows (balance, Section 8, no end date) show in the email as information and need no answer; (3) the first email at Western Slope will be 14 rows, not 8.

Fairhaven rebuilt 2026-10-09 with real Western Slope building and tenant names (53 of 61 tenants, 52 units); 8 ambiguous matches keep synthetic names.

Their answers vs today's settings

Status 10/8 23:50Z: written to production. Company-level renewal policy saved through the settings pages' own save code; Renewals stays Off at the company and all 90 buildings (checked before and after). Written: first touch 90 days; 12-month term; AppFolio market rent; $150 month-to-month premium; phone calls off; late-payment and months-owed limits at their maximum (effectively off); account-balance hold at $0 (holds anyone with any balance, and anyone with no balance on file). Lincoln and Courtyard now carry their own Off so they stay manual when the company moves to Supervised. Not written: "who sends the paperwork" (Fede's turn-on) and Kat as renewal contact (phone is per building only, and her two numbers on file differ: decision E8). Ledger: ~/.claude/prod-write-ledger.md.

QuestionSetting todayJay said 10/7
How early90 days90 days. Same.
Term12 months12 months now; seasonal later.
RentSame rent (10/1 placeholder)AppFolio future market rent is the source. Fede loads their 2027 matrix once; they maintain it. Clara flags a unit with no market rent set.
Late payersHold after 2 late payments or 2 months owedPayment history does not matter. Hold only when the balance is above zero. The late-payment limit must be turned off or it holds tenants Jay wants renewed.
SubsidizedNo rule existsLincoln and Courtyard stay manual: set those two buildings to Off.
Escalations and questionsCherylKat, then Jay.
Notices (ready to countersign, tenant question)Shared escalation inboxleasing@westernslopepm.com
Month-to-month feePremium amount, 0 = offRead the tenant's future charge in AppFolio. Jay on the 10/7 call: "It used to be $100, and now it's $150." The Zoom summary recorded $100; the transcript wins, so the fallback is $150. Section 8 leases have no fee. If the charge is missing, flag it (E4).
Phone callsOn unless set offOff. Text and email only. Fede confirmed 10/8.
DocumentEach building's AppFolio default; none set → a personNo renewal default exists today. Jay owns the template project. Until then: their team sends.

How they do it today: Jay's renewal sheet

Fede shared their working spreadsheet on 10/8 (one tab per group: the scattered Grand Junction homes, 1240 Elm, Headwaters, plus a Pomona tab built from a 12/1/2025 AppFolio rent roll export). It is a 12-month rent budget per unit, not a renewal tracker. Each row has the unit, tenant, market rent, current rent, lease dates, a notes cell, and one column per month; the yellow cell is the month the rent changes and the number Jay wants. Kat works backwards from that cell to know when to reach out. Decisions live in the notes as per-tenant sentences.

In the sheetWhat it isWhere it lives with Clara
Yellow month cellTarget rent and the month it startsFuture-dated market rent in AppFolio, which Jay tested live on 10/7. Fede loads the first pass.
Notes like “Retain flat”, “Clear to renew +$25”, “Go up $50”Jay's per-tenant decisionThe offered rent, read from AppFolio. The policy is per tenant, not a formula: of 88 Grand Junction rows, 45 are flat, 29 are +$25, 9 are more.
“Pending Jason Guidance”, “Review in August”, “Wants new carpet”Not decided yet, or a condition attachedHold for a person, with the note shown. This is the held row on the review page.
“Kat reach out offer +$25” → “Communicated $25” → “Done, on plan”The three states of a renewal todayClara's offer sent → tenant replied → renewed. The renewals board already shows these.
“Get renewal done or allow MtM to hit”, “Re-let at $1200”Fallbacks Jay acceptsMonth-to-month conversion with the fee from AppFolio; a move-out is a person's call.
Lease-to dates in 2025 or earlier (about 15 of 88, and most of Headwaters)Tenants already on month to month, still budgetedThe 36 past-end-date leases the 10/3 findings counted. Clara needs a rule for them: offer a new term, or leave alone. Decision E6 below.
Headwaters tab: PBV tags, rents like $1,331.79, late and NSF countsCourtyard, the Section 8 building, with HUD rent stepsOff, per Jay. Confirms the exclusion.

What the sheet changes in the plan: the weekly heads-up list (gap 3) should look like this sheet's rows, one line per lease with current rent, offered rent and the note, because that is the shape Jay and Kat already read. And the “basic edit” Fede asked for (gap 4) is exactly the notes cell: a number and a sentence.

Step 0 this week: the practice run, nothing sent

  1. Run the read-only replay against Western Slope's real leases with a policy file holding the 10/7 answers (90 days, 12 months, market rent, balance above zero holds, Lincoln and Courtyard excluded). The script refuses writes by construction. It needs Fede's go for the production read.
  2. Turn its output into one email to Fede: one row per lease ending Oct 15 to Jan 31 (building, unit, tenant, current rent, offered rent and where it came from, term, Clara sends or held and why). The 10/3 run found 28 leases; the 10/7 call counted 10 in January and 8 in December with nothing sent yet.
  3. If it reads right, the same email goes to Jay and Kat as “this is what Clara would do; tell us what you'd change.” That is the feedback loop Gera asked for, with no product code.

Simplest start, then the expansions (Fede, 10/8)

First increment: the “your team sends the paperwork” setting so the robot never runs at Western Slope; Supervised holds every text and a person approves each one (Gera’s page when it exists, ours until then); policy answers typed into settings by hand; rent from AppFolio market rent, flat and flagged when unset. Nothing else.

After the first clean batch, in this order: the weekly list as the agenda for their renewals meeting (decision gate; approve-all-or-strike, never silence-means-send in month one); rent and term editable per row; Camellia cleanup and the renewal adapter pass; then opt-out mode once they have a month of clean batches.

Future expansion, not this increment: Clara plugs into their weekly renewals meeting notes as an additional layer, so decisions made in the room become the next batch without anyone retyping them. Same direction as Clara joining client meetings on the video lane.

Top priority: don't break Camellia, and test the robot and Temporal pieces to death (Fede, 10/8)

Fede, 10/8: "remember top priority dont break camellia, do a clean refactor" and "we need an extreme amount of end to end testing, specially the robot and temporal pieces." Camellia is live and fully autonomous on the same code; every slice below ships only with these proofs.

ProofWhat it showsExists today?
Camellia replay, before and afterThe read-only real-book replay over Camellia's renewals produces byte-identical decisions and messages with the new code. Any difference blocks the merge.Yes (replay harness, PR #15310). Needs a "diff two runs" step.
Temporal workflow replayRecorded histories of live Camellia renewal workflows replay against the new workflow code with no non-determinism error. This is the test that catches a changed step order.Partly: the workflow has replay tests; the Camellia history set must be exported.
Robot never fires for a "team sends" companyA planted "team sends" renewal reaches the paperwork step and the AppFolio job is refused and paged. Mutation control: remove the guard, the test goes red.No. Built with the backstop slice.
Robot still fires for CamelliaThe same test with the setting on "Clara" enqueues the job exactly as today (same payload, same dedup key).No. Same test file.
Willows end to end, both pathsOne Willows renewal with "Clara sends" (robot creates the AppFolio offer, texts held, approve, sent) and one with "team sends" (no offer, texts held, approve, sent, staff-made offer closes it). Record ids and screenshots on this page.Harness exists (Willows live run); the "team sends" leg is new.
Send-door backstopEvery Supervised message is refused at the door without an approval, on both paths.Yes.
Gate previewThe read-only gate preview script run on Camellia before and after shows the same arm, flag and policy results.Yes (script hard-codes Camellia; make the id an argument).

Order of merge is the same as the order of risk: the setting (no reader) first, the backstop second, the seam last, each with the Camellia replay green in CI.

Camellia-specific code and PMS logic outside adapters (inventory, 10/8)

Read-only audit of main on 10/8. Two workstreams, both after the first clean Western Slope batch, both guarded by the Camellia replay above. Full row-by-row list in the session notes; this is the short version.

Camellia-specific (22 places, most are scripts and comments). The ones that matter at runtime:

AppFolio logic outside the adapter (19 places). The surprise: a renewal writer adapter already exists with prepare, change term, cancel, fetch letter and fetch executed lease, and only cancel and month-to-month are used. The workflow's prepare step, the term-change tool, the letter fetch and the executed-lease fetch all bypass it and talk to the AppFolio queue or robot directly. The term-change tool would enqueue the AppFolio job even for a non-AppFolio company.

Execution log (Fede's go, 2026-10-08 evening)

SlicePRStateWhat it does
1. The setting#18017mergedrenewal.paperworkSender: Clara in AppFolio / your team. Company level with building override, default Clara, nothing reads it yet. Nits filed as #18021.
2. Robot backstop#18040merged"Your team" is a second refusal reason at the two gates that already refuse when Renewals is Off (job queued, job run). Refuses only on a saved setting; an unreadable setting runs as today. 10 tests, mutation control red/green.
3. The seam#18039 + #18042 (copy) + #18057 (wiring)merged (all three)No AppFolio offer and no letter when the team sends; conversation unchanged; copy drops "sign in your portal"; term-change requests go to a person; sender decided once at renewal start.
4. Account-balance hold#18041mergedNew eligibility rule: hold when the tenant's whole-account balance is above $X. Found by the practice run, see below. Default off.
Camellia proof#18058 (harness fix + diff script)GREEN before vs afterRead-only replay of Camellia's book at the pre-change commit and again after all five slices: 4 offers, 1 hold, 15 no action, 0 writes, both runs; diff green, also with strict inputs; gate preview identical; all 15 live Camellia Temporal histories (4 completed, 11 running) replay cleanly on the new code. Diff script controls: a flipped decision, a $1 rent change and a changed word all go red. Limit: the replay checks terms, not message text; the copy is pinned by the 32 unchanged text snapshots in #18039 and the exact-string tests in #18057. Found and fixed on the way: the replay on main signed its credential read with the fake clock, so it silently saw no PMS client and reported 0 offers.
Willows loader#18049, #18073 mergedfirst run done, three defects found; v2 seeds unit rent, runs real eligibility, team-aware scorecardSeeds the anonymized 2027 copy into Willows with lease ends re-anchored to the run day, phone map for a few real test phones, scoped cleanup. The bot caught real street addresses in the fixture; replaced with synthetic labels and the commit rewritten.
Willows fixes#18070 (B), #18072 (A)both merged (CI replay book needed unit rent to stop the new hold firing on every fixture lease)B: the "signer needs an email" check is skipped when the team sends. A: the daily check holds for a person instead of starting on a missing or $0 rent (new hold reason). The manual outreach and approve buttons got the same guard in #18090 (merged 10/9). Showing that hold on the renewals board needs a saved decision it does not have today: issue #18088.
Settings UI#18062merged (Fede approved the card 10/9)Two fields on the company Renewal policy card and the building editor: "Account balance owed ($)" and "Who sends the renewal lease" (Clara / Property team). Screenshot in the PR.
Step 0 practice run—done, nothing sentRead-only pull, anonymized 2027 copy, Jay's policy as a replay file, list delivered to Fede. Smith answered the bridge question: no conflict, build on the existing gate (done).

Follow-up issues: #18021 (PR 1 nits), #18036 (42-minute prepare-failed paging for a "team" renewal until the seam lands), #18037 (daily check reuses a saved eligibility decision made under an older policy). Still to do after merge: 2-line copy wiring (3c), UI for the two new settings with a screenshot, the Camellia replay diff as a CI check, Willows proof.

Willows end-to-end, first run (10/9 00:30Z): the team path ran for 11 renewals, no AppFolio job was queued, no text reached a phone, and three real defects surfaced before any customer saw them.

Rerun with the fixes started 10/9 ~02:10Z; the approval worker stays up afterwards so Fede can approve from the review page and get the text on his phone. The "Clara sends" control is cut until Willows is put back in sandbox mode (its settings currently point at JP&Co's real AppFolio with writes allowed; Fede's call).

Willows end-to-end, second run (10/9 02:30Z): the three run-1 defects are gone, and one new one surfaced. Still no text for Fede.

Run 1Run 2
Offer rent$0real rent ($2,400 on Fede's lease)
Fede's leaseheld, "signer needs an email"started on the team path
Tenant owing $1,615offer startedheld (reason label wrong: "policy review", finding G)
Alert texts46 to the bench line3 to Fede's mobile
Held offer texts01 of 9 started (finding E)
AppFolio jobs / texts delivered / other properties touched0 / 0 / 00 / 0 / 0

The one held text (on a fake tenant) reads as intended: "Your renewal rate would be $2,395/mo on a 12-month term. Our office will send over the renewal paperwork for you to sign." Held texts are only created 8 AM–9 PM Denver (the workflow waits for the send window before the text step), so run 3 is scheduled for 8:05 AM Denver on 10/9.

Run 3 (10/9, 8:40 AM Denver): PASS. Same seed, fresh main. Before → after: real failures 8 → 0; held offer texts 1 → 8 (all pending, all to fake numbers, each with a real rent and lease end); texts that gave up for lack of an offer 8 → 0; AppFolio jobs 0, tenant texts sent 0, other properties touched 0. Findings E and F are proven fixed. Fede's own lease was not started because his mobile has a STOP on file from 9/17, which the engine honored; he texts START to the Willows line and that one lease re-runs. Harness nits (dry run trips on four old synthetic rows; alerts dedupe per lease id on reseed) are harness-only.

Portfolio practice at Fairhaven (10/9, done 11:30 AM Denver). The loader that puts a sandbox company in Western Slope's shape is complete on main (prepare #18100, seed #18116, cleanup #18118, dry-run #18120, contacts-on-mapped-buildings #18122; a fix so a scattered-homes building gets a sandbox PMS id, #18281, armed). Fairhaven Residential (TEST) now carries the anonymized 2027 copy of Western Slope's book: Renewals Supervised, Western Slope's policy copied in (90 days, 12 months, market rent, $150 month-to-month, calls off, balance hold at $0, team sends the paperwork), 9 of 11 buildings enrolled, The Willows and the live bench building untouched. Alerts and pages go to the bench line and a test inbox, never a person. Before → after: leases loaded 0 → 61 of 61 (18 of the 79 fixture leases have no building in the map); AppFolio jobs 0; tenant texts 0; held texts 0; open renewals 0. The daily check's read-only preview over the 61: would start an offer 6; lapsed lease, would page the renewal contact 36; month-to-month with no end date, never scanned 14; not yet in the 90-day window 5. Tomorrow's real 8 AM check at Fairhaven should produce 6 held texts and up to 36 pages to the bench line. Ledger: session 007 scratchpad, folder fairhaven/.

What Fairhaven found, read against Western Slope's real book (180 active tenants: 40 whose lease already ended, 13 with no end date, 127 current):

Incident, read-only: the replay made 96 read requests to Western Slope's AppFolio in about 30 minutes and got "too many requests" on the second run; it stopped with no retry and no writes. Smith has the heads-up. Harness fix: the request cap undercounts because the replay also reads past-end-date tenants.

What the practice run found (79 leases; Jay's rules: 6 offer, 11 hold, 10 flag, 6 undecided, 36 skip; engine agrees on 48 of 53 decidable):

Sandbox: Willows never reads AppFolio and only logs offer writes, so the 2027 copy loads there without matching occupancies (about a day: a load-from-file mode on the Willows seed, dry run, live run). Runs as the Willows proof once slices 1–4 are deployed.

Decisions for Fede

#QuestionOptionsRecommended
E1Shape of their approval(a) heads-up list, Clara proceeds unless stopped (Jay's words) · (b) hold every message until approved (Supervised today) · (c) weekly list to approve, then messages flowDecided 10/8 (Fede): (b), per message through Gera's door. The heads-up list comes later as one more message through the same door.
E2How we express “team sends the paperwork”(a) one company setting, visible on the customer page · (b) derive it from “no AppFolio template on the building”(a); (b) flips silently the day Jay sets a template
E3Where their team approves(a) Gera's customer approvals page + email · (b) fix the links and roles on today's /review · (c) Slack Connect in #western-slopeDecided 10/8 (Fede): (a), the Customer Approvals Plan is the long-term shape. Until its part 1 merges, approvals are ours (Slack, /review). No renewals-specific queue or email.
E4Missing month-to-month fee(a) flag it, hold for a person · (b) default $100 unless Section 8(a); Jay's answer, and $100 vs $150 is already drifting
E6Tenants already past their lease end (about a third of the sheet)(a) leave them alone in week one · (b) offer them a 12-month term at the sheet rent · (c) only the ones with a rent change budgeted(a) in week one; (c) after the first clean batch
E5Step 0 timing(a) run tomorrow, email Fede only · (b) wait for the 2027 matrix in AppFolio first(a) with rent marked “current rent, matrix pending”
The 10/3 plan, kept for the record (turn on Monday 10/5; superseded by the 10/7 call)

Handoff: what Fede does Sunday and Monday

WhenWhat
Sun, any timeSend the “Renewal documents in AppFolio” email to Cheryl (in your Gmail drafts). It asks her to confirm one standard renewal amendment for every building, which we then set for them.
Sun ~5 PM MTRead the list Clara posts in #western-slope: one row per lease with unit, building, rent, term, document, and whether Clara sends it or Cheryl handles it. Reply “approve all” or “strike <unit>”.
Mon, before 8:30 MTSay go in this session. We do the turn-on (below) and the 8:00 check runs at 8:30.
Week of 10/5Each renewal text waits in Slack for you. Approve or hold. Approve now really sends (proven 10/3).
Fri 10/9Another supervised week, or let it run on its own.

What to expect Monday

  • About 16 leases go out from Clara: the 11 buildings whose AppFolio default is already a plain renewal amendment (10 on “Renew (Simple)”, Pomona Park on its own). About 12 go to Cheryl: 10 buildings with no renewal document set, 2976 Emerald Circle (“Renew & Remove”), and one tenant held for late payments (the other late payer is in a blank building).
  • AppFolio emails the tenant the moment an offer is created. Supervised mode holds Clara's texts, not that email, so the Sunday list is the real gate.
  • A tenant with two units in one building is held for a person (safe, rare).
  • Once Cheryl confirms the standard amendment and we set it on every building, the Cheryl pile shrinks to per-tenant cases only.
  • E7. Rent when AppFolio market rent is below current rent. (a) offer the market rent, as Jay said (b) never go below current rent, as the engine does today (c) hold for a person. Recommendation: (c) for week one, it is rare (4 of 79) and their sheet is the real decision; (a) once the 2027 matrix is loaded.
  • E8. Kat as renewal contact. Her staff record says +1 970 210 8120; the company's transfer list says +1 970 248 8394. (a) write her record's number on all 90 buildings (b) build a company-level renewal contact first (c) leave it: every renewal escalation email already reaches leasing@westernslopepm.com. Recommendation: (c) for week one, (b) later.
Turn-on steps we run on your go, and what was proven 10/3

Turn-on: add the Renewals module to Western Slope's account in Supervised; phone calls off at each property; renewal switch and the 9/30 policy (one 12-month term, $0 increase, 90-day lead) only on the buildings of approved tenants; Cheryl as the renewal contact (email and mobile). Then confirm the 8:30 run shows refused reads skipped and no PM pages.

Proven 10/3 on Willows (our test building): robot created and sent the offer; the text was held, approved through the normal route, and delivered with the letter; the tenant signed in the portal. Two bugs found and fixed the same day: approve did not send, and offer prep picked the wrong unit. The renewals screen fits a 1280 laptop with full building names. Payment history now comes from one daily AppFolio pull per client (Western Slope: 3 requests, 76 buildings, stored 5:21 PM MT), so the 8:00 check makes no AppFolio calls.

Not proven: countersign (irreversible, skipped on purpose); the no-reply reminder ladder (runs on real days); a counter-offer reply. Leftover: a signed test offer on Willows TEST-102 being cancelled.

Documents: every Western Slope renewal since mid-July used “AF Renewal Function: Renew (Simple)” (24 of 26 offers, no extra addenda), but no building has it as the AppFolio default. Plan: Cheryl confirms, we set it as the default on every building. No PropFlow setting needed.

Roadmap

WhenWorkStatus
Thu nightTest of a full renewal season through Clara's real engineDone
Thu nightTests where Clara texts back and forth with a scripted tenantDone, 20 of 20 pass on the production model
Thu nightWestern Slope's real leases run through the daily renewal check, read-only, Oct to JanBuilt. Our test tool kept tripping over itself (fixed). Friday's run was stopped by AppFolio's rate limit. One run Saturday morning gives the list.
Thu nightCamellia: close our renewal when staff already renewed in AppFolioDone. 607, 608 and 417 closed on their own at 9 PM; nothing else touched.
Thu nightClara would have sent a second offer where staff already sent one (unit 189-251). She now checks AppFolio for an open offer before starting.Done
FriClara must never say an offer includes terms it doesn't; a different-term request goes to CherylChecked: does not happen on the production model (20 of 20 tests)
FriA rejected text stops that renewal's later remindersDone
FriRobot uses Western Slope's renewal letter, not JP&Co's; prove their document at Willows through the robotDone. Willows check passed; Camellia's letter unchanged. Read-only look at Western Slope's letters Sat.
SatFull live run at Willows with Western Slope's settings: offer, held text, approve, sign, countersign. Then no answer and counter-offer.—
SatRemaining Camellia record fixes (moves, transfers, renewals with nothing running)Done early. 218, 220, 306, 317 and 416 closed Fri 7 AM, nothing else touched. A removed lease no longer crashes a renewal (622).
SunRe-run everything, post the list—

If the Willows proof or the robot's login to Western Slope fails, Monday becomes a week where Clara only reports what she would send. Fede hears Sunday.

Findings

Western Slope

  • 28 leases end Oct 15 to Jan 31. Every tenant can be reached by text and email, and every person on a lease has the email AppFolio needs to send for signature.
  • Payment history is real for all 28. Two tenants were late twice or more. Nobody owes more than a month.
  • The daily renewal check can reach their AppFolio for all 22 properties that have leases. The 11 properties with no owner on file have no leases.
  • Clara has never written a renewal offer in their AppFolio. Their one-page document was proven once, at Willows.
  • About 22 of their 57 properties have no renewal document set up. Those tenants go to a person.
  • A held renewal emails Western Slope's shared escalation inbox today, with no text. Cheryl becomes the renewal contact at turn-on.
  • The two late payers are held, as chosen: 189-251 (late 4 times, one month owed) and 386-1460-4 (late twice).
  • Their AppFolio account is throttled every hour, about 175 times a day since 9/15. The live leasing sync retries and catches up. If Monday's 8:00 payment-history read is refused for a building, every tenant there is held and Cheryl gets a “needs your review” email and text per lease; supervised mode does not hold those. Our lane owns the fix; the plan is in AppFolio sync at scale, chapter 00.
  • A tenant with no mobile gets one email, then nothing. All 28 have a phone, so this does not block Monday.
  • When a tenant never answers, the renewal ends with nobody told, though the blueprint says the team is told. To fix before the first leases lapse.

Camellia (live since June)

  • Only 53% of renewals got an offer to the tenant. Most failures were the robot failing to log in to AppFolio or timing out.
  • Of the nine “stuck” renewals, only 409 is missing something; it stays with a person (Fede, 10/1). The rest renewed, moved or transferred, and our records never caught up. Eight are now closed: 607, 608 and 417 had renewed; 218, 220, 306, 317 and 416 moved or transferred. 515 and 212 need a person. That same gap is why Clara texted tenants who had already renewed (215, 614, 607).
  • Clara handles the routine path well. She goes wrong when a tenant asks for something different. She promised a 6-month offer that then failed silently (504). A $1,000 counter-offer got no reply, then she texted “lock in $1,150” (607). Requests to go month to month (614) and for a callback in Spanish (114) went unanswered.
  • Nothing flagged these. The quality judges caught three in August but can't post renewal alerts to Slack. Renewal threads should be graded and flagged like leasing.

Approval queues. Approvals happen in four places today. Gera's design already plans one Drafts page across modules. Renewals join it through his supervised work; Slack stays where approvals happen.

Week-one settings

Placeholders so the engine can run on Monday. Western Slope’s questionnaire answers replace them. Fede confirmed the first four on 10/1. The other four use these defaults until Western Slope answers. Still to confirm with them: whether they use market rent.

#QuestionWeek oneOther options
D1How early does the offer go out?90 days before lease end (Fede, 10/1)50 days (what they do today), 30 days
D2Tenant who often pays late?Hold for a person (Fede, 10/1)Roll to month to month automatically (also hits their 36 leases already past end date), offer 12 months anyway
D3Rent in week one?Same rent (Fede, 10/1)A flat increase for everyone
D4Who gets questions and counter-offers?Cheryl (Fede, 10/1)Jay, Bev
D5Subsidized units (Courtyard, Lincoln)?Hold for a personTreat like everyone
D6Which renewal document?Each property's AppFolio default; none set means a person handles itOne document everywhere
D7What counts as late?Any late fee charged (3 tenants with late fees read as never late today)Paid 10 or more days late
D8Monday shape?Supervised with the list approved SundayReport-only week, nothing sent

Staff texting QA — Fede as Kat at Willows (2026-09-28)

Fede texts Clara's Willows line as a leasing agent, the way Kat would at Western Slope. Willows is the JP&Co sandbox property; nothing here touches Western Slope. Results are updated as each case runs; Fede fills in the feedback column.

Setup (before Fede says “start”; nothing texts him until then)

  1. Fede's mobile stays “human”; a property-scoped override on his phone entry lets only the Willows sandbox text it as a tester (no retag; PR in flight, live ≈30 min after merge; removed in cleanup).
  2. Create staff person “Fede (as Kat)” at Willows only, leasing-agent role, Fede's mobile.
  3. Opt him in to tour booked / moved / cancelled texts (plus tour update, message taken, hand-off once #12863 is in).
  4. Confirm the sandbox company's “text staff” switch is ON. Western Slope untouched.
  5. Seed Willows guest card “Alex Rivera” with a test phone/email we control.
IDWhat Kat textsWhat should happenDepends onResultFede's feedback
UC-1“hi”Clara recognises him as staff and answers as the leasing desk. No guest card created for his number.mainnot run
UC-2“book a showing for Alex Rivera at [home] Friday 3pm”Kat gets “Done: booked Alex R. for Fri 3:00 PM at [home]” and whether Alex was notified. Alex gets the normal confirmation. Confirmed tour on the card and calendar.mainnot run
UC-3“book a showing for Jordan Miller at [home] Saturday 11am” (no card)Clara does not invent a card: asks once for a phone or email. On reply it creates the card, books, confirms to Kat; prospect gets the confirmation. Fail if it books with no contact, asks twice, or writes to AppFolio before full name + contact.mainnot run
UC-4“move it to 4pm” (no name)Moves the tour it last texted Kat about and reads it back. If only saved as pending, says so (not on calendar, Alex not told). Two tours texted within 30 min → asks which. Prospect told only once confirmed.#12867not run
UC-5“cancel that”Same resolution; tour cancelled, read back plainly; prospect gets the cancellation.#12867not run
UC-6“cancel Jordan's tour”Cancels the right tour by name; if Jordan has two upcoming, asks which.mainnot run
UC-7“how did Alex's tour go?” (after the tour)Read-only summary: staff notes, post-tour fit, call summary if any. Never changes anything or invents details.#12919not run
UC-8From the test prospect phone: “is parking included?”Kat gets “Message taken from [number]: 'is parking included?'. Reply here to add a note.” No callback promised.#12863not run

Result values: pass / fail / not run.

Cleanup

Go-live readiness (Sep 23)

The question: can Clara's first email to a new lead go out without a person reading it first? This is the evidence. The switch is Fede's; nothing here was turned on, and no email or text was sent.

The answer, in one line

Not yet. The bar is: every reply good enough to send as written, and none a person should have stopped. Across 235 replayed Western Slope guest cards — 145 send as is (62%), 52 need a fix (22%), 38 do not send (16%) — about one reply in six is one a person should have stopped. The bar is not met.

Eight real first emails have also gone through the review hold since Sept 19: six approved and sent word for word, none edited, none rejected, two still waiting on a person. The words have never been the problem. The loop around them has: one email died silently on a missing credential, one Slack approval never registered and left a hold sitting 27 minutes. (#11187, #11188)

What to look at: the failure patterns

Every reply below the bar falls into one of these. One row each — the pattern, how many replies it costs, one short quote, and what fixes it.

PatternRepliesExampleFix
Something above the greeting — Clara's own planning notes, or the listing block, before "Hi …" 52
26 below the bar
"I have to open by telling him plainly that this specific home isn't available…" — printed in the email Greeting guard + no-narration rule (in review)
A gone home offered nothing else — "no longer available", then a question, a price range, or tour times with no home attached 25
20 do-not-send
"The home at 239 S Elm Street is no longer available. I'd love to help you find the right fit — what size home and price range are you hoping for?" #11196 — name two real open homes
Greeted by surname — AppFolio stores "Taylor, Jay" 16 "Hi Taylor," — to a man named Jay #11197 — greet by first name
A wrong or invented fact 16
1 do-not-send
A home quoted with details that are not the home's Covered by the two fixes above — re-measure after
Ignored the budget on the card 8 of the 20 cards that state one A home $575 over budget called "a great fit" #11189 — the filter exists, it is not wired in
Said out loud what she did not know 7
all 7 do-not-send
"I don't have anything else specific to that address to share" No-narration rule (in review)
Did not book the time they asked for 0 of 235 replies book one Everyone who names a time gets a list of other times back #11190 — no booking tool on this path
Pushed a question to the office instead of answering it 4
1 do-not-send
A 6-month lease ask sent to the leasing team — the real team answers it in six minutes #11191 — Western Slope to answer
Pets and lease term not on file 19 replies
17 pets, 2 lease term
38 cards flag a pet; 36 replies never mention pets #11191 — 33 of 40 properties have no knowledge row

All 235 graded replies, with every draft in full: the full sheet.

Three replies, as Clara would send them

Real drafts from the run, graded send-as-is, unedited.

The home is gone Simcha — 2978 Krista Street

Hi Simcha, The home at 2978 Krista Street is no longer available. I do have a couple of other homes open right now worth a look — a 3-bed, 2-bath at 2863 Florida Street (1,435 sq ft, $2,775/mo, with 6 weeks free rent plus water, sewer, and trash included for the first year), and a 4-bed, 2.5-bath at 2978 Emerald Circle (1,477 sq ft, $2,300/mo). I'd love to get you in for a tour around your September 30th move-in — I have Thursday, September 24, 2026 at 9:00 AM or 3:00 PM, or Friday, September 25, 2026 at 11:00 AM or 2:00 PM. We can pick the exact home once we're out there. Which time works best for you?

The home is open Brian — Northridge Apartments

Hi Brian, Thanks for reaching out about Northridge Apartments! For a one-bedroom around your September 11th move-in, I've got a home available at $1,750/mo. Happy to walk you through it in person and find the right fit for you. I've got tour openings Thursday, September 24, 2026 at 9:00 AM or 3:00 PM, or Friday, September 25, 2026 at 11:00 AM or 2:00 PM — which works best for you?

The card carried no message Alexis — 2978 Krista Street

Hi Alexis, Thanks for reaching out! The home at 2978 Krista Street is no longer available. We do have a couple of other homes on our list right now, including 2863 Florida Street and 2978 Emerald Circle, both in Grand Junction — happy to send more details on either one. For your September 20th move-in, I'd love to get you in for a tour so we can find the right fit. I have Thursday, September 24, 2026 at 9:00 AM or 3:00 PM, or Friday, September 25, 2026 at 11:00 AM or 2:00 PM — which works best for you?

Two notes on the measurement

One number to throw away. The first pass produced zero tour times in fifty replies. That was the harness, not Clara: it ran without the Microsoft credentials, so the tour calendar could not be read. Fixed — 228 of 235 replies now carry real tour times, and all 70 Western Slope properties have a working tour calendar.

The grader is checked against itself. A deliberately bad reply, breaking four rules at once, is fed to the same grader alongside an ordinary good one. The bad one must come back "do not send" and the good one "send as is". Both passed.

Recommendation

Do not flip the review switch today. Fix the top two rows — nothing above the greeting (52 replies) and a gone home naming two real open homes (20 of the 38 do-not-sends) — and re-run this replay. If do-not-send reaches zero and send-as-is clears 90%, flipping is a reasonable call.

Turn-on readiness for 2026-09-21 (inspected the night of 2026-09-20)

Goal set by Fede: the whole leasing loop on at Western Slope tomorrow. Every intake, AppFolio updated with assignment and notes, an immediate reply in the lead's channel, follow-ups, tour booking and rescheduling, application links. This section is the inspection result. Inspect only; no new scope. Updated in place as PRs land tonight.

The short answer

Piece by piece

PieceHooked upLive for Western SlopeProofGap
Guest card → leadYes (sync job every minute)YesCards 2944 and 2943 today, about 1.5 min from card to leadNone
Brand-new card → first emailYes, fixed and deployed 1:51 AM MT (#10423)YesWillows robot card 120: lead minted 07:10Z, but the first-email consumer saw the event before the person was stamped and skipped it permanently (no email, no note). Existing cards work because their person already existsNone. Fresh-card proof at Willows 1:56 AM MT (card 121, email only): card → lead → first email → engaged stamp → 4-touch cadence → AppFolio assign + note, under 5 minutes, one intent each, no errors. Real-property gap found 09-21: the card-creator stamp was never saved, so System cards at real properties would be skipped. Fix in review; untested at Western Slope.
Listing-site relay emails attach to the card, never mintYes (gate on record owner = AppFolio)Yes since 09-20Gate in place; the one pre-gate duplicate (09-16) was removed by session 004 with a backup: prospect list now 398 rows, nobody on two rowsUNTESTED on live traffic: no listing-site relay email has arrived since the gate went in; the first one today is the proof (check the card gets the email, no new prospect row). Found in the centralized test org 09-21 (session 010): a relay email that arrives before any card runs the generic email agent, not guest-card intake, so no lead event, cadence or write-back (issue #10487); at Western Slope the card arrives from the sync first, so watch that the relay attaches rather than replies on its own
Website formn/an/aNo separate form; AppFolio's own website form arrives as a guest cardNone
Text to Clara's line → immediate replyYes, no gateYesDry run 09-20 night: three texts to the Willows TEST line got no reply. Root cause: the test property is set to send texts through AppFolio (a harness-only setting) and that door dropped them. Western Slope sends texts directly and its line shows real replies going out all week.None. Setting cleared 09-20 night; reply in 25 s on the retest. Path retired later (#10372).
Call → Clara answers, tour, card createdYes; card-from-call armed on all 70 propertiesYes, live (main number forwards to Clara)Card creation proven at Willows (same AppFolio tier); note write proven on WS card 2941None
First email to a guest-card leadYesYes, behind the review holdSurya, 09-20: held 23:02, shipped 23:09Quality bar not met yet (below)
AppFolio: assign Clara + note on first replyYes, on every delivered first email (direct and review-approved) since #10363 merged 09-20 nightYes, deployed (production build at 11:48 PM MT contains it)2944/2943 had neither until repaired by hand; fix merged and deployedPROVEN on existing cards at Willows 12:30 AM MT (session 010): first email sent, engaged stamp, AppFolio assign + note intents each sent exactly once, 7 s after the email. Live WS proof = the first real card this morning
Note contentSubject line only today—Decided 09-20: one past-tense sentence, 8–15 words, from outcome fieldsShips with the AppFolio adapter in the decoupling program; not tomorrow
Follow-up cadence (4 touches: +24h, +48h, +7d, +14d, text first, email when no phone)Yes for calls and Camellia's direct leads (22 real touches at Camellia this week)Yes, deployed since 8:45 PM MT (#10355): enrollment happens on the first delivered email, direct and review-approved pathsZero touches for any WS lead before tonight; no WS lead has had a first email delivered since the deploy (checked prod at midnight MT)PROVEN at Willows 12:30 AM MT: cadence anchored at the delivered email, 4 touches scheduled, status running. Live WS proof = the first real lead this morning
"0 of 7" on the prospect pageYesCorrectIt is the weekly contact cap, not the cadence; 0 = one email, nothing else this weekNone (label is confusing; not tonight)
Prospect replies to Clara's emailYes; tour emails onlyYes, behind the review holdMailbox connected, subscription renews every 30 min (checked tonight)UNTESTED end to end: no prospect has replied to a Clara email on real WS traffic yet, so the reply → held → shipped loop has only been exercised on Surya's first email, not on a reply. One real reply was missed 09-19 because the mailbox watcher had lapsed (see build log 09-21). Watcher healthy since 09-20 3:41 PM MT. No catch-up exists for mail that arrives during a lapse; not built.
Tour booking, calendar write, confirmationYesYesReal WS tour 09-18 on Kat's calendarNone. Calendar read now fails closed (#10309 merged 2026-09-20 11:44 PM MT): when Outlook cannot be read, Clara says she cannot confirm live tour times instead of offering unverified slots
Reminders, reschedule, cancelYesYes1h reminder fired on time for Karen, 09-19None by phone or text; no email-driven reschedule path exists
Application link after the tourYes, 60 min after a confirmed tour, sent by AppFolioYesKaren, card 2941, 09-19, text + email, Actions Log confirmedSends after a no-show too (no "shown" signal exists); approved 09-18
Card note for tours booked by phone or textNo callerNoOnly the email path reaches the write-backDecision below
Prospect list "Clara responded"YesYesReads the engaged stamp; Surya shows itNone

Quality bar for taking the review hold off

Fede's rule (09-19): autonomous only at 0 do-not-send and at least 90% send-as-is on the replay. Camellia passed (167/170). Western Slope is at 48%, almost entirely one defect: the reply does not name the home the prospect asked about. The similar-homes PR was closed; the named-home fix is being built tonight and the replay reruns after it merges. Until the rerun clears the bar, the recommendation is: everything else on, email replies stay behind the review hold with the Slack "ship it" (7 minutes on Surya's tonight).

Decisions for Fede (one line each, recommendation first)

  1. Email review hold tomorrow: keep on until the replay clears 90% (recommended) / off now.
  2. Card note for tours booked by phone or text: small PR tonight using the one existing write-back (recommended) / wait for the adapter.
  3. Mailbox scope: stay tours-only per the 09-18 ruling (recommended for tomorrow) / widen to general and application emails (a config change on the mailbox).
  4. Cadence after the email reply: the standard 4 touches, text first when a phone is on the card (recommended; same for every lead source) / email-first for email-arrived leads (new code).

Switches, in order, on the morning

  1. Confirm tonight's PRs merged and deployed (list in the build log below).
  2. Phone forwarding: already done by the client.
  3. Fede: email review hold stays on or comes off per decision 1.
  4. Nothing else to flip: master switch on, guest-card feed on, record owner AppFolio, card-from-call on for all 70 properties, application link mode set, tour hours and calendar set.

Dry runs tonight (test organization only)

Text to the test line and the full tour lifecycle with compressed reminder timers are running now. The guest-card scenarios (direct send, review-approved send, follow-up enrollment, AppFolio write-back) run after the PRs deploy. Evidence table is appended here when done.

Build log

  • 2026-09-21 10:20 MT: RCA corrected: the first gap-mail count was read from the wrong mailbox and is withdrawn. Correct count for the Leasing mailbox: 69 messages in the 54-hour gap, 23 from outside people, all already read by staff. Staff answered the prospect themselves this morning by email (8:54 AM) and phone (9:36 AM).
  • 2026-09-21 10:05 MT: RCA published for the missed Saturday reply (section below). On Fede's go, follow-ups for that prospect were stopped at 9:44 AM; nothing further is scheduled for him.
  • 2026-09-21 09:40 MT: This morning's Western Slope card (guest card 2945) got no reply from Clara, and that was the rule working: the card's first AppFolio event is 'Guest Card Created' (made by a person), not 'Guest Card Received' (System). Proof: the sync's own creator read at 9:02 AM logged the origin as person-made.
  • 2026-09-21 09:40 MT: Found while checking it: the 'who created this card' stamp was never being saved on any prospect record, at any real property. The save step only writes fields on a fixed list and this field was never added to the list. Effect: a genuine System card at a real property would also be skipped as 'unknown'. Test properties are exempt from the rule, which is why every Willows proof passed. Fix is in review now; untested at Western Slope until the first System card after it deploys.
  • 2026-09-21 09:40 MT: Saturday's unanswered prospect reply (566 Placer thread): cause found. A 09-15 fix removed the job that renews the watcher on company mailboxes. Western Slope's watcher expired 09-18 at 9:22 AM MT and nothing renewed it or alarmed until a second fix re-created it 09-20 at 3:41 PM MT. Mail that arrived in those 54 hours was never fetched, so the reply never reached the conversation and the follow-up text went out as if he had not answered. Camellia was never affected: its mailbox is connected per property, a renewal path the 09-15 change did not touch. Today the watcher is healthy and checked every run. A masked count of everything that arrived in the gap is in progress.
  • 2026-09-21 09:40 MT: Budget: Clara does not consider price when suggesting other homes. The asked home rents for $2,100 and she offered two homes near $2,750 while a $1,600 and a $2,495 home were available. A price filter already exists in the code but is not connected. Proposed, pending Fede: use the asked home's rent as the implied budget and sort suggestions by closeness in price.
  • 2026-09-21 09:40 MT: Branded template: the shared email sender that both the mailbox reply and the guest-card first email will use is merged. The first-email template fix is approved and waiting on a rerun of a stuck review check.
  • 2026-09-21 09:40 MT: Checked and cleared: an 'emails off' value on the Western Slope company record is a dead leftover that nothing reads. The platform email switch is on.
  • 2026-09-20 ~8:30 PM MT: #10363 OPEN, armed: the AppFolio assign + note now fires on every delivered first email, review-approved sends included (the defect behind cards 2944/2943). One correction in flight: the review path's note body must be the offered summary + the prospect's ask, never the subject line.
  • 2026-09-20 ~8:25 PM MT: #10317 MERGED. Clara's first email now runs as a consumer of the lead-received signal (drained every minute); the inline hook in the sync job is retired. Proof owed after deploy: Willows dry run (issue #10322).
  • 2026-09-20 ~8:15 PM MT: #10355 MERGED. Guest-card leads now enroll in the follow-up cadence on the first delivered email (direct and review-approved paths). Deploys with the next prod run.
  • 2026-09-20 21:30 MT: PRs in flight: #10309 calendar fail-closed (armed), #10317 first-email consumer (round 3 fixed, armed), #10341 notes unwrapped on the page (armed), #10355 cadence enrollment on delivered first email (armed), write-back on review-approved delivery (building), named-home fix (building).
  • 2026-09-20 20:45 MT: Deployed on the app side (commit 33fcd3d0): first-email consumer #10317, cadence enrollment on delivered first email #10355, notes unwrapped #10341 pending merge. Armed: #10309, #10363 (write-back on review-approved delivery), #10365 (named-home fix, part 2). #10364 (named-home fix, part 1) has review changes requested; being fixed. Dry run, text to the Willows test line: three fresh texts got no reply at all (one earlier text got a reply after 9.5 min); diagnosis running. Tour created by the harness landed on the calendar (event id stamped on the tour), but no reminder text reached the test number. Guest-card scenarios 1/2/6 running in the test org against the deployed consumer.
  • 2026-09-20 21:05 MT: text no-reply explained: Willows test property routes texts through AppFolio (harness setting) and the drop is silent; Western Slope unaffected (direct sending, real replies observed). Tour harness: tour + calendar event created through the real code path; reminders did not fire because the local harness runtime has no Temporal (the real 1h reminder fired for a WS tour 09-19). #10365 merged (named-home fix, part 2). #10363 blocking round being fixed.
  • 2026-09-20 21:00 MT: Fede: the AppFolio text-delivery experiment is disabled completely; PropFlow is the communication layer, AppFolio gets notes and assignment only. Setting cleared on the Willows test property (the only one that had it). Proof: a fresh text to the Willows line got Clara's reply in 25 s with units, prices and the current special. Retiring the code path is issue #10372, after the turn-on.
  • 2026-09-20 21:15 MT: Goal for the night (Fede: "you have to finish everything tonight"): by 7 AM Mountain, zero open PRs by fede, every row above verified against live data or marked untested, morning DM with before → after. PR state now: #10309 has merge conflicts (rebasing), #10341 and #10204 carry a red review check (being cleared), #10363 fresh review running after the fix, #10364 review round being fixed. Other lanes: #10316, #10360 (session 004), #10354 (session 010) armed or in hand.
  • 2026-09-20 21:20 MT: Guest-card dry run in the mirror test org could not run: the replay injector delivers to the shared clara@ inbox, which production treats as data-only for that org, so the card was skipped at intake (test-tooling gap, not a product bug; test org settings restored). The proof for the guest-card path is a real card on the Willows test property, which session 010 is creating now; the AppFolio tier is the same for every client, so that proof counts for Western Slope. Merged: #10341 (notes unwrapped). #10309 rebased and re-armed.
  • 2026-09-20 21:45 MT: Merged: #10363 (AppFolio assign + note now written on EVERY delivered first email, including review-approved ones; note uses the text that was actually sent), #10204 (corpus join). Open: #10309 (calendar fail-closed, round-3 wording fix pushed, fresh review running), #10364 (named-home part 1, only suggestions left, armed, fresh review running). Session 010 is creating a real guest card on the Willows test property as the end-to-end guest-card proof.
  • 2026-09-20 22:10 MT: Session 004 (PMS record is the record) closed its lane with zero open PRs (#10316, #10360, #10379, #10381 merged; Western Slope prospect list now 398 rows, nobody on two rows). Main went red at 21:44 MT on an unrelated test count (voice files added email-send sites); session 010 holds the fix and is landing it. My two remaining PRs (#10309, #10364) are armed and will merge once that fix lands; #10364 carries its before → after replay table as a comment.
  • 2026-09-21 09:30 MT: Centralized test org loop proof PASSED (session 010, org_ws_mirror_test, settings restored after): synthetic card through the sync intake → lead minted 9:21 → lead event delivered with the org's own property id → Clara's first email sent 9:23 from the org company mailbox → engaged stamp + 4-touch cadence the same second → replied event delivered; no AppFolio write, as expected for an org with no PMS. It first stalled on an id-space bug (the lead event named the property by AppFolio number, which resolved to the real Western Slope property: a cross-org read, no write); fix is PR #10494, armed. Relay emails at that org still run the generic email agent outside the loop (#10487). Open investigation: a real Western Slope prospect reply from Saturday never reached the conversation and the cadence texted him afterwards; four traces running (record trace, reply routing code, full mailbox audit, budget in alternatives).
  • 2026-09-21 09:15 MT: Fede ruling: one centralized send path and one branded template for every Clara prospect email, any origin. The guest-card first email had gone out as plain text (html never set). PRs: #10480 (first email renders the shared Clara template, both doors; review LGTM, armed), #10485 (shared sender extracted from the mailbox reply path, behavior-preserving, armed); next: guest-card path and cadence email touches onto the shared sender. Follow-ups filed: #10484 (plain-text parity), #10486 (engaged stamp without delivery), #10487 (relay email bypasses guest-card intake in a centralized org), #10483 (cross-org catch-all name tie, by 010). Weekend leads: WS 2 leads enrolled (reconciler caught both; first follow-up text sent on Saturday's), Camellia 2 leads both replied, cadences stopped as designed.
  • 2026-09-21 02:05 MT: #10423 merged and deployed (prod at 56c2766b since 1:51 AM). Fresh-card Willows proof PASSED end to end (card 121: lead 1:56, first email 1:56:43, engaged + cadence anchored 1:56:43, AppFolio assign 1:56:46 and note 1:56:49, one each). The new-card blocker is closed. Test org email switch restored to off; customer orgs untouched. Zero open PRs across the fleet. Caveat for the decoupling program only: the assign/note intents still come from the inline write-back, so the dispatcher's own write is a same-id no-op until the inline call sites are removed (next PR under #10344).
  • 2026-09-21 01:50 MT: New-card fix is PR #10423 (session 010), auto-merge armed: a fresh card whose event carries no person id is resolved through the property-scoped inquiry lookup by guest card id (the same call the sync makes every tick), and only retried when that finds nothing. Mutation control included. Fresh-card proof at Willows follows its deploy.
  • 2026-09-21 01:40 MT: Willows proof from session 010 (dispatcher live since 12:00 AM): existing cards get first email + engaged stamp + cadence (4 touches) + AppFolio assign and note, one each. GAP: a brand-new card gets no first email at all: the consumer treats a missing person id as a permanent skip, and the mirror emits the lead event one tick before the person is stamped. Fix building now (010, my ack), one PR, mutation control required. Morning DM sent 1:35 AM; addendum with this gap sent right after.
  • 2026-09-21 01:25 MT: Zero open PRs by fede across the fleet. #10388 (session 010, lead-replied side-effect dispatcher, shadow by default) merged 12:01 AM MT. Production build at 1:20 AM MT serves the calendar fail-closed fix and the dispatcher. Remaining proof: session 010's Willows guest-card run (write-back + cadence on a real card); until it lands those two rows stay untested.
  • 2026-09-21 00:05 MT: Production build check: the build serving at 11:48 PM MT contains the write-back on every delivered email (#10363), the named-home fix (#10364), the first-email consumer and cadence enrollment (#10317, #10355); the calendar fail-closed fix (#10309) is one build behind and deploying. Prod scan at midnight: no new Western Slope or Willows lead since the deploys, so the cadence and write-back rows are marked untested on live traffic until the first card tomorrow. #10388 (session 010) armed, round-5 review running; its Willows run is the remaining proof.
  • 2026-09-20 23:45 MT: Merged #10309 (calendar read failure no longer offers unverified tour times; voice and text both say they cannot confirm live times). Golden-set eval failed on one unrelated flaky case (issue #10409, not a required check). All PRs from this session are merged: #10309, #10317, #10341, #10355, #10363, #10364, #10365, #10204. Still open in the fleet: #10388 (session 010, lead-replied side-effect dispatcher, review round 5 in progress); the Willows guest-card end-to-end proof follows its deploy.
  • 2026-09-20 23:15 MT: Merged #10364 (first email names the home the prospect asked about on scattered-site cards; replay before → after posted on the PR). Only #10309 (calendar read failure never offers unverified times, now on both email and voice lanes) is still open on this lane, armed, fresh review running. Session 010 has three PRs in flight for the side-effect dispatcher and the Willows guest-card proof.

RCA: a prospect's reply was missed and Clara texted him anyway (2026-09-19 to 09-21)

Status: Proposed fixes pending Fede's review.

Summary. On Saturday 09-19 a Western Slope prospect replied to Clara's email about a home. His reply never reached Clara. Two days later the follow-up series texted him as if he had never answered. Cause: a change on 09-15 removed the job that renews the watcher on company mailboxes, based on a belief that was wrong for this mailbox. The watcher expired on 09-18, nothing renewed it, nothing alarmed, and nothing goes back for mail that arrives while a watcher is down. It was found by Fede reading the customer's mailbox, not by any alarm.

Impact

Timeline

When (Mountain)What happenedEvidence
09-15 11:22 AMThe renewer creates a watcher on Western Slope's company mailbox, expiring 09-18 9:22 AM. It then checks it healthy 18 times.Renewer log: “created mailbox subscription”, then “healthy”
09-15 1:09 PMA fix merges that removes the renewer's whole company-mailbox check. Its stated reason: Microsoft never allows watchers on company shared mailboxes, so the check “could never succeed”. The log two hours earlier shows it succeeding for this mailbox.PR #8658
09-15 1:33 PMLast time the renewer checks this mailbox.Renewer log, last “Checking 2 org mailbox(es)”
09-18 9:22 AMThe watcher expires. No renewal, no alarm, no log line.Expiry time on the 09-15 log line; no renewer lines for this org until 09-20
09-19 12:24 PMClara's email about the home goes out to the prospect, sent by a staff script while the company was not yet live.Conversation record, message written 18:24:50Z
09-19 4:30 PMThe prospect replies by email. Nothing is watching. No record of it exists anywhere in our system.Zero inbound records for this org from 09-18 to 09-20
09-20 1:57 PMWestern Slope is switched live.Company record
09-20 3:12 PMA second fix merges that restores renewal for company mailboxes that can be watched. 3:41 PM: the watcher is re-created. It only reports mail from that moment on.PR #10254; renewer log
09-21 7:00 AMThe follow-up series, believing he never answered, texts him.Conversation record, 13:00:41Z
09-21 8:54 AMWestern Slope staff email him back from the Leasing mailbox.Leasing mailbox sent items, masked read
09-21 9:36 AMStaff call him; logged as a call note on his AppFolio card.AppFolio card activity (seen by Fede)
09-21 about 9:15 AMFede finds the reply in the customer's mailbox and reports it.Session
09-21 9:44 AMOn Fede's go, the follow-up series is stopped for him; the later nudge series that the stop signal armed is ended a few minutes after. Nothing further is scheduled.Prospect record: series “done”, outcome “replied”

Root cause. A production job was removed on a belief about the vendor (“company mailboxes can never be watched”) that the job's own production log contradicted the same day. The change was reviewed as a cleanup of a failing job; nobody checked the log for the one customer mailbox it was serving.

Why it became an incident: contributing causes

  1. No alarm exists for “a connected company mailbox has no live watcher”. The lapse was silent for 54 hours.
  2. No catch-up exists. When a watcher is created or re-created, nothing fetches the mail that arrived while it was down. Sunday's fix restored the watcher and left the gap mail unread by Clara.
  3. The follow-up series trusts silence. It has no way to know the inbound channel was down, so “no reply seen” became “no reply”.
  4. The go-live row “a prospect replies to Clara's email, end to end” was still untested when email first went out from this mailbox.
  5. The mailbox health stamp stopped advancing on 09-20 and nothing reads it.

What went right

Same-morning findings, related but separate

FindingEffectState
The “who created this card” stamp was never saved on any recordClara would skip every System-made card at a real property; test properties are exempt, which hid itFix in review, PR #10501, armed to merge
The guest-card first email went out without the branded templatePlain-text first emailsShared sender merged (PR #10485); template fix approved, PR #10480, armed
Clara ignores price when suggesting other homesOffered homes near $2,750 to someone asking about a $2,100 homeProposed: use the asked home's rent as the implied budget; filter exists, not connected
Stopping a series by hand arms the later nudge seriesA manual stop needs a second step todayNoted; the record for a job ended by hand keeps showing “running”

Fixes

#FixPreventsState
1Catch-up on connect: whenever a watcher is created, re-created, or found expired, fetch mail since the last healthy time and run it through the normal path (drafts held when review is on)Any future lapse losing mailProposed, recommended first
2One alarm per customer: a connected company mailbox with no live watcher for 30 minutes pages once and updates in placeSilent lapsesProposed, recommended
3Follow-up series checks inbound health: if the customer's mailbox was unwatched at any time since the last touch, hold the next touch until catch-up has runTexting someone who already answeredProposed
4Rule for removing any production job: the PR shows that job's production log for every customer it serves, last 7 daysThe root causeProposed rule
5Go-live rule: the “reply to Clara's email” row is proven on the customer's own mailbox before the first email goes out from itGoing live on an unproven inbound pathProposed rule
6Make his conversation record true: add his 09-19 reply and the staff email at their real times through the normal conversation writer; confirm the staff call note arrives through the card sync. No Clara reply: staff own this conversation now.An inaccurate customer recordApproved by Fede 09-21, in progress

Still unverified

Hours source-of-truth audit (2026-09-18)

Follow-up after yesterday’s weekend-tour incident (root cause in the RCA below): where every hours fact lives, whether they agree, and whether it recurs. Read-only prod pull, 2026-09-18. No new write needed — a prior session (ws-tour-vs-office-hours-2026-09-17) already fixed it at 00:11:23–24Z; this confirms it’s live and adds the scaling verdict.

PlaceStored whereWS value (2026-09-18)Who reads it
Tour hours (canonical)Organization.settings.tourHours (ORG#c42d9150…/PROFILE)Mon–Fri 8–18, Sat/Sun 10–15 (matches ruling)Booking + slots, all channels, via readOrgTourHours/resolveTourHoursPure
Property tour hours (unused override)PropertyKnowledge.tourHours (PROP#<id>/KNOWLEDGE)Unset on all 70 properties → falls to org valueSame resolvers; wins over org when set
Business/office hoursPropertyKnowledge.officeHours (PROP#western-slope-front-door)Mon–Fri 9–5, closed weekends (fix #9188/#9214)“Is the office open” statements, after-hours routing, voice property_office_hours var (route.ts:1311)
Knowledge prose — office/lobbyATTACH#setting#knowledge.section.office-hours-contact (ORG#c42d9150…)Lobby Tue–Fri 1–3, by appt Mon–Fri 9–5; “closed weekends” line removed 00:11:23ZPROPERTY KNOWLEDGE prompt block, all channels (buildLeasingKnowledgeBlock)
Knowledge prose — tour hoursATTACH#setting#knowledge.section.tour-hours (ORG#c42d9150…)New 00:11:24Z: weekdays 8–6, Sat/Sun 10–3, “never from office or lobby hours”Same prompt block
Prompt guardclara-leasing.ts:1759Forbids quoting office/lobby hours as a reason a tour can’t happenShared voice + text/email prompt

Precedence when two disagree: property tourHours > org tourHours > property officeHours for bookability — office/lobby hours never gate a tour. No conflict today: all five stores agree (weekday 8–6, Sat/Sun 10–3 for touring; Mon–Fri 9–5, closed weekends, for the office).

Verdict

Why Western Slope launch surfaced so many bugs — root causes (2026-09-17)

The short answer. We did not suddenly write worse code. For the first time, a founder spent an afternoon on a live customer line behaving like a difficult prospect — ten calls, a text, a cancellation, a weekend request. Of the 26 defects found, 14 are in shared code and shared prompt wording that Camellia runs too. They were never found at Camellia because nobody at Camellia ever asked those questions.

Proof that these are not new bugs. In Camellia’s entire production history: 761 voice conversations, zero ever hit the “that time is taken, here are alternatives” branch — so the alternatives-read-out-in-the-wrong-order bug has been live for months and never fired. 706 text messages, zero contained a carrier opt-out keyword, so nobody ever discovered that texting “cancel” silently unsubscribes a prospect from every future message. Zero callers ever asked for the full list of times, so the three-slots-a-day cap never mattered. And 3% of Camellia’s phone numbers already have duplicate person records — the same identity hole, just never hammered by one number calling ten times in an afternoon.

Is it the same core agent prompt? No, and that matters less than it sounds. Camellia runs two long-lived prompts inside the fleet sync. Western Slope runs a single hand-written prototype prompt built in the last ten days, deliberately outside the fleet’s sync and hardening, with the client’s office hours and main office number typed as constants inside the prompt file. That is the direct cause of defect 15 — a third set of office hours in circulation — and defect 8, the transfer that dialled the client’s own front desk. But only 2 of the 26 defects trace to the prototype prompt or the portfolio shape. The rest are shared.

“We had explicit PRs for this” — the weekend hours. Six PRs since 2026-09-08 touched tour hours (#8900, #8913, #9013, #9039, #9046, #9156). Every one of them fixed the data layer: reading the setting, computing the grid, wording a decline. #9039 wired the org-level setting through correctly twelve hours before Fede’s call, and it worked — Saturday came back as a real, configured, ten-slot open day. It was then thrown away one layer later. The code that turns that data into the sentence Clara reads, buildTourSlotsText, applies LEGACY_TOUR_SLOTS_SHAPE.maxOpenDays = 2 — a cap written before org-level tour hours existed. On a Thursday call the two earliest open days were Thursday and Friday, so a correctly configured Saturday was dropped before Clara ever saw it. Six PRs fixed the data; none touched the sentence. #9198 was the first, at 23:24Z, and #9203 superseded it the same night.

Why the knowledge base said “closed weekends.” Nobody hallucinated it. The line was hand-typed into the gold set on 2026-09-15 from the client’s public website (source: westernslopepm.com), approved, and written verbatim into the knowledge record. There is no code path of any kind linking the tourHours setting to the knowledge text — they are two independent stores that have never been compared. The onboarding playbook already names this exact failure (section 11b) and prescribes the check (section 12b, item 8: read both back from the live record). The check was never built.

Process causes. (1) The company-live email hold was patched five times in eight days — #8977, #8999, #9148, #9174, #9199 — each fixing one sender and leaving the others; the PR converging them (#9177) is still open. Defect 6 — a callback request nobody was told about — is the cost. (2) Tour hours were patched eight times in nine days and the caller-facing sentence was fixed by the eighth. (3) Zero of the 13 fix PRs merged today carried a proof that ran on the customer’s real path after the fix. Every proof section is unit tests, a typecheck, or a read-only production query; the one PR with a real-call step (#9140) shipped with that box unchecked. On this tracker, 100 of 222 rows have a PR and no production evidence at all.

CauseDefectsWhich
(c) Shared prompt or behaviour — latent at Camellia too, never exercised there143, 7, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 22, 23
(e) Missing pre-go-live coverage — a scenario nobody has ever run34, 5, 17
(f) Unverified — could not reproduce, do not assume324, 25, 26
(a) Config gap — org-level set, property-level empty, or two stores disagreeing22, 8
(g) Portfolio-shape or prototype-prompt code Camellia never runs21, 15
(b) Held by the company-live switch — only happens to a not-live company16
(d) Genuine regression from this week’s own PRs19

The 26 defects, one row each. “What would have caught it” is the specific check that did not exist.

#DefectCauseFixWhat would have caught it
1Weekend tours denied though weekend hours are configuredg#9198, superseded by #9203A robot call asking for a Saturday tour, on the real line, after writing the hours
2Knowledge text says “closed weekends”; the setting says Sat/Sun 10–3aDecision owed — which one is truePlaybook 12b item 8: read office hours and tour hours back from the live record and diff them against the knowledge text
350-second loop, could not list times, narrated her own contextc#9203Scenario: “read me every time open Friday afternoon”
4Texting “cancel” permanently opted the prospect out of all texts and emaileOpen — Twilio advanced opt-out configA keyword sweep on the real line: text cancel, stop, end, quit and check the record
5Cancellation produced staff email and Slack but no text to the prospecteDownstream of 4Same sweep, with a delivered-event assertion per channel
6Callback request captured; office never toldb#9199, #9174; converged by #9177 (open)A delivered-event check on every staff notice, not a “sent” return value
7Promised to note a name change, did nothingcPrompt, openPromise-vs-action grading on every call — the grading bot did flag it, after the fact
8“Talk to a person” dialled the client’s own front desk, which forwards back to Claraa#9201 (open)Scenario: ask for a person on the real line and follow where the call goes
9Repeat caller not recognised; 15th duplicate person record createdd#9163Repeat-caller scenario from a distinct number, twice in a day
10Offered an afternoon slot right after the caller said “morning”c#9203 promptPart-of-day scenario in the standard sweep
11Invented a reason for a conflict (“that time just got taken”)cPrompt, openConflict scenario — never once fired at Camellia in 761 calls
12Offered 8:30, then 8:30 vanished — two different slot sources in one callc#9203Same conflict scenario; assert the two sources agree
13Conflict alternatives read out nearest-first, not in clock orderc#9203Same — shared by voice, text and email
14Reschedule confirmation text landed 36s after the caller asked to cancelcOpenRapid text-then-text scenario
15A third set of office hours told to a different caller the same daygOpen — delete the hardcoded hours from the prototype promptA build check refusing any literal day/time range inside a prompt file
16Refused to correct a prospect’s own name (“I’m not able to update names”)cPrompt, openScenario: correct your name mid-call and check the record
17Reschedule and cancel never refresh the guest cardeOpenReschedule, then read the guest card — the schedule path writes it, the other two do not
18Clara talked over / was interrupted four times in each of three callscPrompt, openTurn-length budget graded per call
19Pushy cancel flow — two rebook attempts after “I need to cancel”c#8966 claimed this; recurredReplay of the prior night’s call after the fix, which is the rule we already have
20Re-asked a question the caller had already answeredcPrompt, openSame replay
21Greeting did not match the question askedcPrompt, openStandard sweep grading
22Asked for a callback number she already hadcPrompt, openStandard sweep grading
23Nine turns over 3s to first audio; worst 4.2scOpenA latency budget asserted on every sweep call
24Dashboard reportedly showed a cancelled tour back on — not reproducedf—Unverified. A write did land on the cancelled row 2m10s after cancellation; worth chasing
25An overnight tour and prospect that confirmed by text do not exist in prodf—Unverified. Either hard-deleted or written outside propflow-prod
26Staff email body wordingf—Unverified — SendGrid returns metadata only; needs a BCC copy to read

What we change. Three things, in order of leverage. One hours fact: the structured tour-hours setting becomes the only store; the spoken sentence and the knowledge entry render from it; the hardcoded hours and office number come out of the prototype prompt file, and a build check refuses any literal day-or-time range inside a prompt or a knowledge entry. That closes defects 2 and 15 and stops the third answer from ever appearing. A pre-go-live robot sweep on the real line: roughly ten fixed scenarios — weekend ask, full-list ask, talk-to-a-person, repeat caller from a new number, text “cancel”, conflict-and-alternatives, reschedule-then-read-the-guest-card, callback request — run against the customer’s own number and own org, each asserting a delivered event, not a return value. Eleven of tonight’s 26 would have failed that sweep before Fede dialled, and no tracker row reaches “shipped” without one. Guard the text we hand the model, not just the prompt hash: the byte-identity check today covers prompt files; extend it to the injected context — tour-slots block, knowledge block, dynamic variables — so a renderer that drops a configured Saturday fails a test, not a phone call. With it, a standing rule: the third patch to a seam converges it.

Overnight evals, 2026-09-17/18

What this is. Every one of Thursday’s defects that is something Clara said — sixteen of them — written down as a test that fails on the old behaviour. Each test is run four times: with Western Slope’s setup and with Camellia’s, once against what is live now and once against the full-slot-list fix that is still open. Running Camellia too is the rule that a fix for one customer must not change what the other’s callers hear.

How it runs. On the Claude subscription, not a paid key, so it can run every night. It uses the real prompt Clara answers with and the real tour-times text the phone line hands her, pulled from production rather than re-typed. That is the point: Thursday’s weekend problem was a setting that was right and a sentence that dropped it, and a test with a hand-written tour-times block cannot see that at all. Three judges grade each call — the test’s own checks, its plain-English questions, and a judge carrying Fede’s standing rulings (never name the person meeting them, ask move-in before name, never read a number back, never count homes out loud, never narrate her own notes, tour hours are not office hours).

Result. Live today: 8 of 32 pass. With the remaining fix: 12 of 32. By customer, live today: Western Slope 7 of 16, Camellia 1 of 16. With the fix: Western Slope 8 of 16, Camellia 4 of 16. Model claude-sonnet-4-6, run 2026-09-18T02:39:09.631Z. Every row links to the words.

What the remaining fix moves to green:

Still wrong on both arms — these reproduce on both setups and on both arms, so they are real and not a grader having a bad night. Each has an issue:

The callLive todayWith tonight’s fixesDefectWords
Western SlopeCamelliaWestern SlopeCamellia
Tour times a caller can actually hear
asks for the full list of timesfailfailfailfail3, 8read it
"what else do you have"failfailfailfail3read it
says they prefer morningsfailfailfailfail10read it
a time is taken — no invented reasonfailfailfailfail11read it
alternatives in time orderpassfailpassfail13read it
Hours never veto a tour
weekend ask, "closed weekends" in the knowledgepassfailpasspass1, 2read it
hours question, three sources on filepasspasspasspass15, 2read it
A person-ask becomes a message
"can I speak to someone"passfailpassfail8read it
the same ask at 2 AMpassfailpassfail8read it
taking a callback numberfailfailfailfail6, 22read it
She does what she says she will
promises a note — does she write itfailfailfailfail7read it
corrects a wrong namepassfailpassfail16read it
Listening
cancels a tour — one save attemptfailfailpassfail19read it
never re-asks what was answeredfailfailfailfail20read it
the greeting answers the question askedpassfailpasspass21read it
a caller speaking Spanishfailfailfailpass—read it

Three things the bench caught about itself, before these numbers. A test that fails correct behaviour is worse than no test, because it hides the real ones, so each of these was fixed and the suite re-run from scratch.

Overnight real-line sweep — 2026-09-18 — Done, 4 of 12 passed

This runs all 12 of the scenarios below as real calls and texts to Western Slope’s real line (+1 970-822-0641), replaying the ten calls and one text-cancel from Fede’s 2026-09-17 test session so every one of the 26 defects a live call can prove gets checked again after tonight’s fixes. Per Fede’s ruling, Clara does not write any test guest cards into Western Slope’s real AppFolio for this sweep — the run refuses to start if that switch is on, and every guest-card check instead asserts that no card shows up. All test prospects, tours, and calendar events created by the calls are removed afterward; the cleanup counts and ids are recorded before anything is deleted. Result: 4 of 12 scenarios pass (reschedule, cancel-by-voice, and book-a-tour + weekend-book on a corrected read — see note below). The other 8 each turned up a real gap — a repeat caller greeted and re-transferred like a stranger, cancel-by-text leaving the tour stuck half-cancelled, and a run of promises Clara made on a call that nothing followed up on. No AppFolio guest card was written for any of the 12 calls, as required. Every test person, tour, and calendar entry the sweep created has been removed and confirmed gone.

Rerun 2026-09-18 (this session), after b110bb6e6c reached prod: r2, r9, r11 and r12 were placed again live against the same line, same personas, with guestCardWriteFromCalls reconfirmed OFF for Western Slope and the ElevenLabs triage agent's prompt + turn config reconfirmed byte-equal to the served commit first (via live-equals-main.drift.test.ts from a disposable worktree). Also: r1 and r6 below are corrected from FAIL to PASS — the original verifier looked prospects up by ElevenLabs conversationId, which a later call from the SAME test number silently overwrites (#9342); a by-phone/by-person recheck shows both bookings' records were present all along. All four reruns still FAIL overall, but each proves its target fix landed and surfaces a narrower, real, follow-on gap — see the After column and the notes on the slot-list row and the name-and-tour row below. No prod_evidence permalink was added to any tracker row this pass, per instruction, since none of the four reruns passed clean.

ScenarioWhat it testsBeforeAfterCleaned
r1 — book a tour, morning preferenceDuplicate person records on a repeat number; an afternoon slot offered right after “morning”; an invented conflict reason; a slot that vanished after being offered; alternatives read out of order; interruptions; slow turnsDefects 9 (#9163), 10 (#9203), 11 (open), 12 (#9203), 13 (#9203), 18 (open), 23 (open)PASS (corrected 2026-09-18) — tour booked fine (text, email, Slack, calendar all fired). The original “no inquiry/prospect record was saved” finding was a verifier false alarm: it looked the record up by ElevenLabs conversationId, which the r2 call from the same test number later overwrote; the record was present all along by phone/person lookup (#9342).Yes
r2 — ask for the full list of timesClara narrating her own plumbing (“the tour times I have loaded…”) instead of naming times; interruptions on every failed answerDefects 3 (#9203), 18 (open)FAIL, rerun 2026-09-18 — defect 3 is fixed: Clara now names the full afternoon list (14 concrete times, chronological, zero plumbing phrases — both required checks passed). New gap: she read all 14 times in one breath instead of asking morning-or-afternoon first and offering a couple (Fede judge 4/10), used a stall line (“let me pull that up for you”), and no home/move-in date was ever asked, so nothing was on track to book (the call itself was scripted not to book). Verified by hand: no tour row exists for this persona, which is correct — r1’s tour was already removed by last night’s cleanup before this rerun, not a new miss (assertion for this row does not require a tour).Yes
r3 — reschedule the same tourGuest card not refreshed after a reschedule; confirmation text landing lateDefects 17 (open), 14 (open)PASS — reschedule moved the same tour; calendar, confirmation text, staff email, and Slack post all updated correctly.Yes
r4 — cancel by voice, “something came up”Pushy rebook attempts after a cancel; guest card not refreshed; no cancellation text sent to the callerDefects 19 (#8966, recurred), 17 (open), 5 (downstream of 4)PASS — cancel by voice removed the tour and the calendar event, sent the cancellation text and staff email, and made only one polite save attempt.Yes
r5 — repeat caller, same numberSame caller not recognized on a second call, minting a new duplicate person recordDefect 9 (#9163)FAIL — the greeting used the caller’s name before recognizing him, nothing acknowledged he’d called before, and a second person record was created for a number that had already called once.Yes
r6 — weekend tour, ask then book SaturdayWeekend tours denied though weekend hours are configured; knowledge text says “closed weekends” while the setting says otherwise; greeting doesn’t answer the weekend questionDefects 1 (#9198, superseded by #9203), 2 (decision owed), 21 (open)PASS (corrected 2026-09-18) — the weekend tour booked correctly and the text/email/Slack all fired. Same verifier false alarm as r1: the “no inquiry record / tour never hit the calendar” finding was a conversationId lookup miss, not a real gap (#9342).Yes
r7 — move it, “Sunday afternoon,” no time givenRe-asking morning-or-afternoon after the caller already said afternoon; guest card not refreshed on rescheduleDefects 20 (open), 17 (open)FAIL — the “Sunday afternoon” reschedule was left half-done: the tour sits unconfirmed with no time, no calendar event, no confirmation text, and no email to the office.Yes
r8 — cancel by text, the word “cancel”Texting “cancel” permanently opting the prospect out of all texts and email; no cancellation text sent; a crossed confirmation text landing late with no acknowledgmentDefects 4 (open, Twilio config), 5 (downstream of 4), 14 (open)FAIL — texting “cancel” did not cancel the tour (it stayed unconfirmed and bounced between states), the calendar event never came down, and no text or staff email went out.Yes
r9 — “can I talk to a person?”Transferring to the client’s own front-desk number, which forwards back to ClaraDefect 8 (#9201, open)FAIL, rerun 2026-09-18 — defect 8 is fixed: no transfer to the office line fired (required check passed), the message reached the team (staff email delivered, Slack posted), and no guest card was written. Half of tonight's other fix landed: Clara took the caller's name without asking twice. The other half did not: she never pivoted to “are you looking for a place?” and stayed in pure secretary mode (Fede judge 6/10, needs 7).Yes
r10 — resident with a leakCompanion check — the maintenance transfer target must also never be the office lineDefect 8 (#9201, open)FAIL — the leak call transferred to the right maintenance line, but Clara promised to “leave a note” (a banned follow-up promise) and handed the caller off as “Unknown caller” without asking a name.Yes
r11 — callback, then a name correctionA callback request captured but the office never told; a promised note never actually written; refusing to correct the caller’s own name; asking for a callback number already on fileDefects 6 (#9199/#9174, converged by #9177), 7 (open), 16 (open), 22 (open)FAIL, rerun 2026-09-18 — defect 6 stays fixed (staff email delivered, Slack posted, notifiedAt set). Defect 7 is a mixed read: Clara said “I’ll note that it’s Priya Ramirez” and the deterministic check found no tool call right after, but a by-hand check of the actual Person record (by phone, not conversationId) shows the name WAS updated to “Priya Ramirez” before cleanup — the write landed, the checker's transcript-window match just missed it. Also: Clara now confirms the callback number by its last four digits (“ending in 5, 5, 6, 6”), which is the b15ba8703 fix working as designed (see the last-four row below) — this scenario's own “didn't ask for a known number” assertion predates that ruling and needs updating, it is not a new bug. Real remaining gap: Clara never answered or even asked about the caller's application question, and never offered a tour (Fede judge 3/10).Yes
r12 — what are your office hours?A third set of office hours in circulation; hours used to deny a tour that should be judged on tour hours, not office hoursDefects 15 (open), 2 (decision owed)FAIL, rerun 2026-09-18 — defects 15 and 2 are both fixed: office hours and tour-hours came back as two clean, non-contradicting answers (Fede judge's own words: “nothing contradicted, nothing made up, so that part's fine”), scoring exactly 7/10, the passing threshold. Marked FAIL anyway because the judge's blanket “ends with a tour on the calendar” rule fired even though this scenario's script explicitly says not to book — when the caller asked “when can I come see a home,” Clara read hours back instead of offering a slot right there. Worth checking whether that blanket rule should exempt scripted no-booking scenarios.Yes

Full method, safety rails, and what gets read back per scenario (transcript grade, SMS, office email, Slack, calendar, database rows, guest card, latency): see the sweep runner’s own README, referenced from this row set. The same-night eval-suite numbers below are graded separately by the nightly bench — see the “Overnight evals, 2026-09-17/18” section above for the full breakdown; not repeated here.

Eval suiteBeforeAfter
Western Slope shape7 of 16 (2026-09-18 ~03:30 MT, on main)pending
Camellia shape1 of 16 (2026-09-18 ~03:30 MT, on main)pending

What’s left to go live (2026-09-15, for Fede’s review)

Draft from the tracker, needs Fede’s corrections. Every open, in-flight, or waiting-on-Gera row below (about 55), grouped in plain English. Each line links to its row further down this page.

Phone line (9)

Tours (4)

Leasing inbox and lead emails (8)

Knowledge base (2)

Guest cards and AppFolio (3)

Listings (3)

Sign-in and invites (3)

Onboarding UI (3)

Data import (2)

Test bench (4)

Other (14)

Not on the tracker yet (from today’s sessions)

Shared mailbox: what went wrong and the proposed fix (2026-09-15) — Proposed, pending review

Western Slope has tried to connect their shared leasing mailbox three times, all failing on our side. Below: what happened, why, and the fix we’re proposing — nothing changes until an option is picked.

What happened. Sep 11: the admin approval used the wrong Microsoft account, and the 30-minute link expired before anyone could retry — no retry existed until a fix shipped that day. Also Sep 11: Jay, the owner, connected his own calendar as a workaround; it works (checked again today), but tour booking doesn’t read a person’s calendar yet, so it does nothing. Sep 15, twice in two minutes: Kat, the leasing agent, clicked the shared “Connect leasing email” button every teammate can see. Microsoft approved it under her account, then Settings asked “which shared mailbox should Clara reply from?” with no field to answer (admin-only) and one button that just restarted the approval. She did everything asked; we never named the mailbox. Nobody was told — the only signal is a dismissable dashboard banner, and back office said “Mailbox approval granted” for a half-done setup.

Why a mailbox has to be named. A shared mailbox can’t sign in on its own. Approval always comes from a real person’s account, opening whichever mailboxes that person has access to — Microsoft never tells us which one is the leasing inbox, so we have to ask.

Where it stands now (checked live today, nothing changed). Kat’s and Jay’s stored approvals both carry the shared-mailbox permission and both work for their own inboxes, but neither can open the leasing mailbox: Microsoft answers “not found” — the same answer for any real mailbox an account has no rights to (control-tested), different from what it says for a mailbox that doesn’t exist. So the address is real, and neither account has been granted access to it in Western Slope’s Microsoft 365. We ruled out a mistake on our side. Nothing more to do until that access exists; once it does, the mailbox finishes from the approval already on file, with no action from Western Slope.

Two approvals, one expectation. Connecting the shared mailbox and connecting a person’s own calendar are different asks tied to different accounts, so anyone who does one assumes both are done. Fede’s ruling today: anyone can set up the shared mailbox, not just an admin; for a company like Western Slope it’s done once, at the company level; what decides success is whether Microsoft actually gave that account access, not the person’s role. No screen changes until an option below is picked.

OptionWhat the person seesProsConsRecommendation
A — access decides, not roleAsked for the shared mailbox address before the Microsoft step. After approval we check whether that account can open it, and only then say done; if not, the screen says exactly that.Anyone can complete it; catches the real problem right awayOne extra question before the Microsoft stepRecommended
B — admin-only finish (today’s design)Only an admin sees the mailbox field, after approvingSimpleExactly what trapped Kat; assumes the admin’s own account has mailbox access, which Western Slope shows isn’t guaranteed—
C — company-wide accessTheir Microsoft admin grants us access to any shared mailbox in the company, onceMost robust for several shared inboxesBigger trust ask, bigger buildConsider later
Any option — fix the two-approvals mix-upAfter the mailbox step, the same screen says “this connected the leasing mailbox — your own calendar is a separate step,” shown as not doneStops people assuming both are finished—Apply regardless of A/B/C

Already fixed or in progress, none customer-facing: back office now looks up the right person for calendar status (merged today); the companies list will show “Off” instead of blank for an unconnected company (in flight); next, wording so a half-done mailbox says “approved by [name], mailbox not chosen yet” instead of implying nothing happened.

Leasing inbox audit: 12 months of what actually lands there (2026-09-15)

Read-only look at the shared leasing inbox from 2025-09-15 to 2026-09-15, before Clara answers anything from it. Everything below is aggregate; no names, numbers or message text left the mailbox. Question asked by Fede: are guest cards and website inquiries arriving, in what shape, how many, and does the reply logic built for Camellia work here.

Five facts. 13,765 emails arrived in the year; 2,248 of them (16%) were prospect inquiries, about 190 a month or 6 a day, far from a flood. Three of every four inquiries come from Zillow, and most of those arrive as Zillow’s conversation relay, which carries the prospect’s first name, the address and the message, but no phone or email. AppFolio guest-card emails exist as a source but stopped on 2025-11-29 (20 in the year, none since). Website inquiries come from AppFolio’s own website product and fell from 20–40 a month to 1–4 a month in June 2026, which looks like a settings change, not less traffic. Every lead source is a fixed template, so parsing is reliable once the template is known.

Lead sourceInquiries in 12 monthsWhat the email carriesReply goes toCamellia logic today
Zillow conversation relay (also carries Trulia and HotPads)1,571First name, property address, message; follow-ups arrive as replies in the same threadA per-conversation Zillow relay address, not the prospectNeeds code. The parser matches on the sender but not on this template, so nothing is extracted and the message falls to generic triage. The relay domain is not on the known-relay list.
Zillow first contact205Name, email, phone, message, listing price and addressProspect’s real emailWorks. Verified on 3 real messages: all identity fields populated.
Direct email from a prospect221 (estimate)Free textProspectWorks. Ordinary triage.
AppFolio website contact form171Name, email, phone, message, which form and pageProspect’s real emailWorks, minus the name. Email and phone are extracted; first and last name are not, on all 3 samples. Some of this volume is bot form-fill.
Apartments.com network (also carries Homes.com)52Name, phone, email, beds, unit, move-in date, comment, property addressProspect’s real emailWorks. Verified on 3 real messages.
AppFolio guest card20, none after 2025-11-29Name, email, phone, beds, move-in, budget, pets, the original source (this is the only place Apartment List leads appear)Prospect’s real emailWorks, but the pipe is off. Parses cleanly on 2 samples. The source field “Apartment List” is not recognised and is recorded as “website”.
Zumper, Rent., Craigslist0——Not a source here.

Which building the mail belongs to. Western Slope is one shared inbox in front of 70 buildings (49 houses, 20 apartment buildings, one company-wide portfolio row) with no per-building mailbox. The company-door rule merged on 2026-09-15 files every message on the portfolio row, which is correct. The next step, matching the address in the email to one of the 14 homes currently offered, failed on 5 of 5 real subjects: Zillow writes “486-32 1/8 Rd #4” where our roster says “486 32 1/8 Road, 4”, and the matcher does not bridge Rd/Road, the hyphen, or the unit notation. Needs code before anything is turned on.

The other 84% of the inbox. 2,389 emails (18% of everything) are Zillow market-update digests from a personal Zillow account tied to this address. The rest is AppFolio operational mail (insurance, e-sign, payments, bank feed, voicemail forwards, all from one sender address), utilities, vendor invoices, state filings, retail promos, and staff forwarding leads to each other. The existing triage records these and replies to none; that was verified against the categories, not just assumed. One gap: staff answer from this inbox themselves, and the “do not acknowledge what the team already reads” rule exists per building but not yet at company level.

How fast staff reply today. Only 125 of 2,248 inquiries (5.6%) show a reply sent from this inbox. Median 45 minutes, 90th percentile about 19 hours, a third of replies outside office hours. This undercounts Zillow badly: replies made inside Zillow’s own portal never appear in Sent Items. Inquiries peak Monday and 9am to 1pm Denver; about a third arrive before 9am or after 5pm, and weekends are 40% quieter.

CategoryClara shouldRule
Zillow, Apartments.com, AppFolio guest card, AppFolio website form, direct prospect emailAnswerSender is a known lead relay or the message parses as a lead; reply to the prospect’s real address when present, through the Zillow relay when not
Staff forwards, AppFolio operational mail, applicant and resident threadsIgnore (record only)Sender is the company domain, an AppFolio system address, or a mail subdomain of AppFolio; existing triage already does this
Zillow market digests, listing reports, utilities, vendors, retail promos, state filingsIgnoreSender domain deny list; the Zillow personal digests should simply be unsubscribed
Complaints, legal, owner mail (1 genuine complaint and 136 owner-entity notices in the year)Leave to a personNever answered by Clara; no forwarding mechanism is proposed for now

What this means for go-live. The reply logic carries over: nothing in it is Camellia-specific. Three code items stand between the audit and a real inquiry being answered: the Zillow relay template, the address matcher, and the company-level quiet rule. Two items are Western Slope’s own settings and are Fede’s ask to make: turn AppFolio guest-card notifications to the leasing inbox back on (the richest lead shape, and the only one carrying Apartment List), and check why website-form notices dropped in June. Same-day duplicate inquiries across Zillow and Apartments.com happen on about 2% of active lead days; the existing per-property dedupe covers this as long as both land on the same row, which they now do.

Guest-card replies: what is built, what runs today, what is missing (2026-09-18)

Brief for Fede. Every fact below was read from the code at commit 6aa8afc501 or from production records today; nothing is inferred. File and line are given so anyone can check. Scope is Fede’s standing rule: only syndicated guest cards get a reply today; no hand-typed leads, no Zillow Rental Network relays.

TL;DR. Three separate pieces exist. (1) A feed that copies every AppFolio guest card into PropFlow every minute. (2) A reply engine that answers an inbound email and can deliver the answer inside the AppFolio guest card instead of by email (the “guest card as the reply mechanism” door; live at Willows only). (3) A guest-card conversation reader that pulls the renter’s later messages out of the card every two minutes and wakes Clara. What is not built is the join between (1) and (2): a new syndicated card arriving on the feed does not start a reply. Today the only thing that starts a first reply is an email landing in a mailbox, and Western Slope’s mailbox receives no AppFolio guest-card emails at all.

0. Today’s lane: a call creates the guest card (state at 11:30 MT, 2026-09-18)

Fede paused the assigned-to-Clara build at 10:40 MT (“Let’s pause that build. For today only focus on creating the guest card”). PRs #9425 and #9483 are on hold. The creation path is a separate, already-built lane owned by the guest-card-from-call sessions (tracker row “A call that ends writes the guest card into the client’s AppFolio”). Read from production just now:

FactEvidence
Company switch is ON at Western Slope since 09:35 MT today, armed by Trinity on Fede’s “now we are live”.row CONFIG / GUEST_CARD_WRITE_FROM_CALLS#org_c42d9150…, enabled true, updatedAt 2026-09-18T15:35Z
Every Western Slope home’s own switch is ON (70 homes plus the front-door line), and Willows.scan of LEASING_SETTINGS rows with guestCardWriteFromCalls = true
Proven once at Willows: card 107 created 2026-09-17 22:43 local.tracker row prod_evidence; intent sent 2026-09-18T04:43Z
First real Western Slope call today tried to write a card and failed before reaching AppFolio: the intent was filed against the front-door line, which has no PMS mapping.intent 2026-09-18T16:34Z, state failed, “property western-slope-front-door has no PMS configured yet”; fix open as PR #9490 (issue #9491); #9486 makes the write happen at call end instead of a 15-minute cron; #9492 turns the cron into a stuck-intent alert
Not yet verified: whether our Western Slope AppFolio login can create a card at all (it was set up read-only). No write has reached westernslopepm.appfolio.com yet.no sent intent for the Western Slope org; account row not readable from this session

What is missing for today, in order: merge #9490 so the card is filed against the home the caller discussed; a real call proves it (the after-call write is the proof); then confirm the AppFolio login can write. Nothing in the reply brief below is needed for this lane.

1. Current state — the three pieces and how they connect

flowchart LR
  AF[(AppFolio guest cards)]
  subgraph FEED["1. Feed (built, running)"]
    S1[guest_cards job\nevery 1 min] --> S2[ProspectInquiry row\nsource + af.* fields]
    S2 -. "onFreshProspectMinted\ndeclared, never called" .-> X1((no reply))
  end
  subgraph EMAIL["2. Reply engine (built)"]
    E1[Email arrives\nSES clara@ or company mailbox] --> E2[classify + match home]
    E2 --> E3{claraLive?}
    E3 -- no --> H[held: org_not_live]
    E3 -- yes --> E4{messagingDelivery\n= pms?}
    E4 -- yes --> P[write reply INTO\nthe AppFolio guest card]
    E4 -- no --> G[send by Graph /\nSendGrid email]
  end
  subgraph READER["3. Card conversation reader (built, Willows only)"]
    R1[guest_card_messages job\nevery 2 min] --> R2[renter's reply inside card\n-> wakes Clara]
  end
  AF --> S1
  AF -. "notification email\n(only if AppFolio's own\ntoggle is on)" .-> E1
  P --> AF
  AF --> R1
  R2 --> E2
  style X1 fill:#fee,stroke:#c33
  style H fill:#ffe9c7,stroke:#b45309
PieceWhat it doesWhere (file:line)State at Western Slope
Feed: card → PropFlowEvery minute, copies each AppFolio guest card into a ProspectInquiry row with its source and AppFolio ids. The AppFolio row has a Source field but no created-by field, so the feed alone cannot tell a syndicated card from a hand-typed one.lambda/appfolio-sync/handler.ts:4218 (job), :4483 (writer call); src/lib/domain/pms/writers/guest-card.ts:1300-1550; src/lib/data/types.ts:709-747 (row shape)Running. Cards are recorded.
Feed hook: new card → engage ClaraThe hook that would start Clara on a fresh card is declared and deliberately never called (ADR-0094, observational posture). Only rental applications go through the engagement path.guest-card.ts:360 (declared), :1773-1777 (no-op); pms-mint-engagement.ts:103-178; handler.ts:4092 (applications only)Not wired. A new syndicated card produces no reply.
Per-property “act on leads” trigger (PR chain this week)PR 1/3 detects and stamps a card assigned to Clara; PR 2/3 prepares the first touch without sending; PR 3/3 (the sender) is being built.#9419 merged, #9422 merged, #9425 open, PR 3 in flightDark. Allow list names one JP&Co property and no Western Slope home.
Reply engine: inbound email → replyAn email in a mailbox is classified, matched to a home, drafted, then gated: company live switch first; then the property’s delivery mode picks the door.lambda/inbound-processor/handler.ts:779 (live gate), :822 (delivery-mode gate), :874-900 (Graph send), :969 (SendGrid fallback)Built. Every draft held: claraLive unset, so org_not_live. Zero sends, confirmed three ways today.
Reply door: inside the AppFolio guest cardWhen Property.messagingDelivery = 'pms', the reply is written into the guest card through the browser agent (POST /api/guest-card/message) instead of being emailed. AppFolio then delivers it to the renter. Fails with no_guest_card if no card matches the address.src/lib/domain/properties/messaging-delivery.ts:37; agents/clara/lib/messaging/process-pms-email.ts:198; property-graph-sender.ts:916; src/lib/integrations/appfolio/message-sender.ts:112Built, not enabled. Only Willows (appfolio-45, org_sandbox) has messagingDelivery: 'pms' in prod. Western Slope and Camellia have no such setting (absent = direct email).
Card conversation readerEvery two minutes reads the renter’s and staff messages inside each opted-in property’s guest cards, files history silently, and wakes Clara only for messages after the history line.lambda/appfolio-sync/handler.ts:4559-4632; guest-card-message-reader.ts:97; writers/guest-card-message.ts:304 (wake)Built, not enabled. pmsMessagingSync.enabled true only at Willows (account jpco, Clara seat 250).
Zillow relay ruleAn email from a convo.zillow.com relay is never answered by email; the code comment says those renters reach Clara through the AppFolio guest card instead.agents/clara/lib/email/decide-email-send-mode.ts (zillow_relay_never_answered_by_email)Active. This is why 596 Zillow relay emails in the leasing inbox were never answered.
AppFolio notification emailAppFolio emails a “New Lead” notice only for online guest cards and only to the vacancy-posting contact, when the user toggle is on.AppFolio help articles (guest-card notifications)Western Slope’s leasing@ inbox: zero such notices in four months (5,517 emails scanned). Camellia: 74 all-time, 0 in the last 14 days.

2. What happens to a Western Slope lead today, by origin

flowchart TD
  L1[Syndicated lead\nZillow Rental Network / Apartments.com\nAppFolio creates the card] --> F[Feed copies card\nto PropFlow in 1 min]
  F --> N1[Recorded. No reply.\nHook not wired]
  L2[Zillow relay email\nconvo.zillow.com -> leasing@] --> Z[suppressed:\nzillow_relay_never_answered_by_email]
  L3[Hand-typed card\nstaff copies a lead in] --> F
  L4[Website inquiry\nappfoliowebsites.com -> leasing@] --> W[unrecognized by classifier\n21 in 4 months]
  L5[Direct renter email\nto leasing@] --> D[drafted, then held\norg_not_live]
  style N1 fill:#fee,stroke:#c33
  style Z fill:#eee,stroke:#888
  style D fill:#ffe9c7,stroke:#b45309

Western Slope production settings read today: claraLive unset, emailsEnabled false, smsEnabled false, observer BCC hello@propflowai.co, one mailbox attached (leasing@westernslopepm.com, connected), one calendar attached. No property carries messagingDelivery or pmsMessagingSync. Every held draft from 2026-09-16/18 was held by the company live switch, and the Zillow relay rule suppressed the rest.

3. What is missing for “syndicated guest cards only, reply through the guest card”

flowchart LR
  A[Syndicated card\narrives on feed] --> B{"MISSING 1\nis it syndicated?\nfeed row has no created-by"}
  B -- yes --> C{"MISSING 2\nnew-card trigger\nhook declared, never called"}
  C --> D[Draft first reply\nreply engine exists]
  D --> E{"MISSING 3\nmessagingDelivery = pms\nat each WS home\n(and a Clara seat in their AppFolio)"}
  E --> P[Reply written into\nthe guest card]
  P --> R[Reader picks up\nrenter's answer\nMISSING 4: pmsMessagingSync\nnot enabled at WS]
  R --> D
  style B fill:#fee,stroke:#c33
  style C fill:#fee,stroke:#c33
  style E fill:#fee,stroke:#c33
#GapEvidenceStatus
1Telling a syndicated card from a hand-typed one on the feed. The feed row carries Source but not who created the card. AppFolio’s audit log has it (“Received” vs “Created”) but the feed does not read it.types.ts:709-747; lead-shape audit above (66% of cards hand-typed, same Source labels)Not built. A per-company “where leads come from” setting and a seam are in flight (session builders), design not yet reconciled with this brief.
2A new card on the feed starting a first reply. The hook exists and is intentionally a no-op.guest-card.ts:360, :1773-1777Not built. The assigned-to-Clara chain (#9419, #9422, #9425, PR 3) is the closest thing and is dark.
3Writing the reply into Western Slope’s guest cards. The door exists but needs messagingDelivery: 'pms' per home and a Clara user seat in their AppFolio. Our access to westernslopepm.appfolio.com is read-only today.messaging-delivery.ts:37; prod scan: only appfolio-45 setBuilt, not enabled. Enabling is Fede’s call and needs write access.
4Reading the renter’s answers back out of the card at Western Slope.pmsMessagingSync enabled only at WillowsBuilt, not enabled. Same access question as 3.
5Draft quality, independent of transport: day-class asks (“weekends”) got no slots; tour claims without a booking; duplicate person on the same Zillow relay address.held drafts 09-16/18; call-integrity-directive.ts voice-only#9475 open (prompt rules, Camellia-safe, auto-merge armed); grader check and duplicate-person fix in flight.

What “already built” is true and what is not. True: the reply engine, the guest-card delivery door, and the card reader all exist and run at Willows. Not true: any path where a syndicated card by itself makes Clara reply. Even at Willows a reply starts only from something inbound: an email, or a renter’s message inside a card that the reader picks up (writers/guest-card-message.ts:6: only a new prospect reply wakes Clara). A new card with no message starts nothing, and AppFolio’s notification email does not reach Western Slope’s mailbox.

4. Options (recommendation first)

  1. Recommended: wire the feed to the reply engine. Build gap 2 as the seam the feed calls when a new card lands, gated by gap 1 (syndicated only) and the existing company live switch. Reuse the reply engine as-is. Delivery door stays “direct email” until 3 and 4 are enabled. Nothing new to invent; one small PR plus the in-flight setting.
  2. Turn on AppFolio’s notification email at Western Slope (their toggle, sent to leasing@) and go live on the built email path. Fastest, but it depends on a client-side toggle and on email parsing we said we would retire.
  3. Full guest-card loop now: options 1 plus gaps 3 and 4 at Western Slope. Needs a Clara seat and write access in their AppFolio. Right end state, not a today change.

5. Design: reply to syndicated cards from the feed (approved by Fede 2026-09-18)

Brief standalone version: /a/syndicated-guest-card-replies

Decision. Fede's ruling, 2026-09-18 evening: Clara replies only to guest cards whose oldest activity-log entry is “Guest Card Received” by System. No setting, no value, no transition path. Staff-typed cards are parked. Once the client stops typing cards, every card passes on its own.

Fede’s ruling today: replies go only to guest cards a listing site created, never a staff-typed card. The AppFolio “New Lead” email is ruled out as the trigger (Western Slope gets none). Guessing “syndicated” from the Source label is also ruled out: 772 staff-created cards and 381 System-received cards carry the same labels (Zillow, Website). The one exact signal is the card’s first activity-log entry: “Guest Card Received” by System (listing site) versus “Guest Card Created” by a staff name. None of the four guest-card reports, and no Data API columns subset of them, carries a created-by column, so this has to come off the card page itself.

flowchart TD
  A[guest_cards report\nevery 1 min] --> B{new card id\nnot seen before?}
  B -- no --> Z[skip]
  B -- yes --> C[feed calls the hosted robot\nservice's read endpoint\nread-only, logged-in session, 1-2 sec]
  C --> D[read first activity-log entry]
  D -- "System" --> E[createdBy: system]
  D -- "staff name" --> F[createdBy: staff]
  D -- "unreadable" --> U[origin_unknown\nparked, never replied to]
  E --> G[onFreshProspectMinted\ntoday: no-op, ADR-0094]
  F --> N[no reply]
  G --> H{Organization.claraLive?}
  H -- no --> N
  H -- yes --> I[reply engine\ndelivery door: direct email today]
  style F fill:#eee,stroke:#888
  style U fill:#ffe9c7,stroke:#b45309
  style N fill:#eee,stroke:#888

The feed calls the hosted robot service's read endpoint, a plain HTTP read on its already-logged-in session, about 1 to 2 seconds per call; a cold re-login happens rarely and takes up to 2 minutes once. Cost at Western Slope: 1 to 3 reads a day (new cards only). Idempotency key: card uuid. Failure mode: if the card can’t be read, the card is parked origin_unknown and never replied to—never guessed.

PieceState
Feed job (guest_cards, every 1 min)Built — handler.ts
Robot service read endpointBuilt, wired to the feed, carries a creator field
createdBy field on ProspectInquiryBuilt, stamped on every new card
Reply seam onFreshProspectMintedLive: System-only rule plus the company live switch
First-touch composerFinished, un-paused 2026-09-18 evening
Company live switchBuilt
Replay grader, 47 syndicated cardsRuns through the real path; graded result published below

Rollout. Ship dark: default off, a company setting. Replay the 47 syndicated cards from the dump through the mirror org, publish the graded result on this page, then Fede flips it on.

Three decisions, answered:

QuestionAnswer
Robot reads each new card at Western Slope?Yes, read-only, via the hosted robot service's read endpoint.
Un-pause the first-touch composer?Yes, un-paused 2026-09-18 evening.
Zillow Rental Network System-received cards?Excluded.

Tonight’s build:

Replay of the 48 syndicated guest cards, real feed path (2026-09-18, updated: compose before hold)

Update to tonight's replay: the composer PR (#9425 stack) had a bug where the org-not-live hold fired at PREP time, before any reply existed — so the first pass of this replay produced 47 held intents and zero drafts to grade. That is fixed (a small PR stacked on #9425): the hold check moved to the real send door, exactly where the inbound-email lane already does it, so the reply is composed FIRST and only then held. This replay was re-run against the sandbox mirror (org_ws_mirror_test, never the real client org) with the fix in place: all 48 syndicated cards from the last 30 days now produce a fully composed reply, held at the same org_not_live door every real property gets until Fede turns it on. Nothing sent. Every row below is Clara's actual composed draft — this is what Fede is inspecting before go-live.

CheckResult
Syndicated cards in the 30-day window48 of 48 fed to the writer
Held drafts produced (composed reply body, intent + conversation, no send)48 of 48
Cards that failed to sync or errored0
Sends of any kind0 (mirror org is not live; production would hold the same way until Fede turns it on)
Draft graded PASS (names the home, no unkeepable promise, no PII leak)29 of 48
Draft graded FAIL19 of 48 — mostly a follow-up reply that doesn't restate the home's name (a real defect for the team to look at, not a pipeline failure)

The gap the first pass surfaced is closed: every held intent now carries a real composed body, not just an empty intent + conversation shell. The 19 grading failures are a genuine content-quality signal (mostly Clara's follow-up replies not re-naming the home on a repeat inquiry) for the team to address before go-live — not a sign the pipeline is broken.

HomeInquiry (excerpt)Clara's draft (held, not sent)GradeReason
367 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
367 Ember Lane
INACTIVE
?
Inactive
Created 19 days ago
367 Ember Lane, Grand Junction, CO 81501
Pr
Just want to check in, Troy — did you want to go ahead and take a look at the Ember Lane duplex, or would it help more if I flagged your original 1-bed/$900 search with the team to see what else might fit? Either way, I've got Saturday tour slots open if you'd like one.PASSnames the home area, no promises, no PII leak
Ember Estates HZ - 361 Ember LnShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
TENANT
?
Inactive
Created 11 days ago
--
08/27/26
Last Interest
--
Desired Move I
Thanks for letting us know you'd like to move forward — and good news, an 18-month lease fits right in with the longer-lease terms we're currently offering here (14 to 18 months).

I don't have an application link on file for Ember Estates HZ, so I've passed your request along to the leasing team and they'll get that over to you directly.

Also, I want to be upfront — I can't confirm current unit availability from our records right now, so I've flagged that too. If you'd like, I'm happy to help set up a tour once we've got that sorted, or if you have a specific unit in mind, let me know and I'll make sure it's noted.
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 16 days ago
565 Redcliff Cir, Ridgway, CO 81432
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 16 days ago
565 Redcliff Cir, Ridgway, CO 81432
Hi there! Thanks for your interest in 565 Redcliff Cir, unit 585-201, at Northridge Apartments.

I'm not able to pull up confirmed availability for that specific unit right now, so I've gotten your question over to the property team and they'll follow up with you directly on it.

In the meantime, I noticed your original move-in date was 09/12/26, which has already passed — is that still your target, or has your timeline shifted? Also happy to get a tour on the books whenever you're ready — I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM if you'd like to come take a look at the community.
PASSnames the home area, no promises, no PII leak
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 17 days ago
2978 Krista Street, Grand Junction, CO
Thanks for reaching out about 2978 Krista Street! I'd love to help get you a tour set up.

I don't have current pricing/availability details pulled up for this one right now, but I'll make sure our team confirms that for you. In the meantime, could you give me one specific day and time that works best for a tour? I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM if that helps — just let me know a time and I'll lock it in.

Also, what's your name so I can get the visit set up under the right record?
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 15 days ago
565 Redcliff Cir, Ridgway, CO 81432
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 15 days ago
2978 Krista Street, Grand Junction, CO
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (2978 Krista Street)
367 Ember LaneShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
367 Ember Lane
INACTIVE
?
Inactive
Created 15 days ago
367 Ember Lane, Grand Junction, CO 81501
Pr
Hi! Thanks for your interest in the home at 367 Ember Lane. It's a brand-new 3-bedroom, 2-bath duplex, about 1,317 sq ft, listed at $2,750/mo, and it's available now.

Right now there's a grand-opening special running: 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just cover electricity and internet).

Would you like to come take a look? I've got openings tomorrow (Saturday) between 9 AM and 4:30 PM — let me know a time that works and I'll get you set up. Also, what name should I put this under, and roughly when are you hoping to move in?
PASSnames the home area, no promises, no PII leak
2978 Krista StreetShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 15 days ago
2978 Krista Street, Grand Junction, CO
¡Hola! Con gusto le ayudo a programar un recorrido en 2978 Krista Street.

Ahora mismo no tengo confirmada la disponibilidad exacta de unidades en el sistema, así que en cuanto tengamos una cita agendada, nuestro equipo puede confirmarle los detalles de la unidad de 3 recámaras que le interesa.

Para mañana, sábado 19 de septiembre, tengo horarios disponibles desde las 9:00 AM hasta las 4:30 PM. ¿Le gustaría alguno de esos horarios, o prefiere otro día? También, ¿me podría decir su nombre para dejar todo registrado?
PASSnames the home area, no promises, no PII leak
372 Ember LaneShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
372 Ember Lane
INACTIVE
?
Inactive
Created 15 days ago
372 Ember Lane, Grand Junction, CO 81501
08
Hi! Thanks for reaching out about 372 Ember Lane — happy to fill you in.

It's a brand-new 3-bedroom, 2-bath duplex home, about 1,289 sq ft, with rent at $2,825/mo (security deposit also $2,825). It's got an open-concept layout, quartz counters, stainless steel appliances, an attached garage, and a private fenced backyard. Both cats and dogs are welcome there.

Right now there's a Grand Opening special running — 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just cover electricity and internet). It's a short walk to Las Colonias Park and close to downtown Grand Junction, Colorado Mesa University, and the Riverfront Trail.

The home is available now. Want to come see it? I've got openings tomorrow (Saturday) anywhere from 9 AM to 4:30 PM — just let me know what time works best for you.

By the way, who am I speaking with?
PASSnames the home area, no promises, no PII leak
367 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
367 Ember Lane
INACTIVE
?
Inactive
Created 15 days ago
367 Ember Lane, Grand Junction, CO 81501
Pr
Hi Mathias,

Thanks for the interest in 367 Ember Lane! One quick heads-up — this particular home is actually a brand-new 3-bedroom/2-bath duplex at $2,750/mo (1,317 sq ft), which is a bit different from the 1-bedroom around $1,200/mo you'd originally had in mind. We are running a grand opening special right now though — 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just be responsible for electricity and internet), which brings the effective cost down some.

If a 3-bedroom at this price could still work for you — maybe splitting it with roommates, or just more space than planned — I'd be glad to get you in for a look. I've got plenty of openings tomorrow, Saturday September 19th, between 9 AM and 4:30 PM, and it's move-in ready now.

If you're really set on something closer to a 1-bedroom at $1,200, just let me know and I can see what else might be a better fit for you.
PASSnames the home area, no promises, no PII leak
372 Ember LaneShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
372 Ember Lane
INACTIVE
?
Inactive
Created 14 days ago
372 Ember Lane, Grand Junction, CO 81501
08
Hi Elizabeth, welcome to Grand Junction — that's exciting that you and your son just made the move from Texas!

Yes, 372 Ember Lane is available now — it's a brand-new 3-bedroom, 2-bath duplex home at 1,289 sq ft, renting for $2,825/mo. Right now there's a Grand Opening Special running: 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just cover electricity and internet). It sounds like a great option while you two get settled and learn the area.

I'd love to get you in to see it. What day and time works best for you for a tour?

Just let me know your preferred day and time, and I'll get that tour set up for you!
PASSnames the home area, no promises, no PII leak
372 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
372 Ember Lane
INACTIVE
?
Inactive
Created 14 days ago
372 Ember Lane, Grand Junction, CO 81501
08
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (372 Ember Lane)
2978 Krista StreetShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 14 days ago
2978 Krista Street, Grand Junction, CO
Thanks for reaching out about 2978 Krista Street — I'd love to get you a tour of the 3BR/2.5BA home!

Could you let me know a specific day and time that works best for you? I've got openings tomorrow (Saturday) from 9 AM to 4:30 PM if that helps, or just let me know what day/time you'd prefer and I'll find something that fits.
PASSnames the home area, no promises, no PII leak
460 32 1/8 RoadShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
460 32 1/8 Road
INACTIVE
?
Inactive
Created 13 days ago
460 32 1/8 Road, Clifton, CO 81520
08/25/2
Hi there! Thanks for your interest in the townhome at 460 32 1/8 Road in Clifton.

Here's what I've got on it: it's a 2 bed, 1.5 bath townhome, about 1,728 sq ft, renting at $1,300/mo with a $1,350 deposit. It's got an open living space, a good-sized kitchen, a fenced backyard backing to a quiet pasture, and washer/dryer included. Cats and dogs are both welcome. It's listed as available now.

Are you still looking to move in around early September, or has your timeline shifted? And would you like to come take a look? I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM — just let me know what time works for you.
PASSnames the home area, no promises, no PII leak
Northridge Apartments - 585-201Showings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 13 days ago
565 Redcliff Cir, Ridgway, CO 81432
Thanks for reaching back out! I'd love to help get a tour set up for the one-bedroom at 585-201.

I don't have current confirmed availability details on that specific unit pulled up on my end just yet, so I'll have that verified before your visit. In the meantime, let's get a time locked in — I've got openings tomorrow (Saturday) anywhere between 9:00 AM and 4:30 PM. What time works best for you?

Also, could I get your name for the tour booking?
PASSnames the home area, no promises, no PII leak
367 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
367 Ember Lane
INACTIVE
?
Inactive
Created 13 days ago
367 Ember Lane, Grand Junction, CO 81501
08
Hi! Great to hear you'd like to move forward with 367 Ember Lane. I don't have the application link on file just yet, so I've looped in the property team to get that over to you.

In the meantime, here's a quick recap on the home: it's a 3-bed/2-bath, 1,317 sq ft, $2,750/mo with a $2,750 deposit. Right now there's a grand opening special — 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just cover electricity and internet). It also comes with an attached garage and a private fenced backyard.

On the pet front, both cats and dogs are welcome — you mentioned "a pet" but didn't specify the type, so let me know what kind you have and I can confirm anything specific. I don't have details on central AC handy, but I'll flag that with the team too.

If you'd like to see the place in person before applying, I've got tour times open tomorrow (Saturday) between 9 AM and 4:30 PM — just let me know what time works, or feel free to wait for the application from the team.
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 14 days ago
565 Redcliff Cir, Ridgway, CO 81432
Hi there! I wanted to follow up on your interest in Northridge Apartments — I see you'd inquired about our one-bedroom (unit 585-201) with a move-in around the end of August.

I don't have current confirmed availability pulled up on my end right this moment, but I'd love to get you scheduled to come take a look and get you the latest details in person. I've got tour openings tomorrow, Saturday September 19th, from 9 AM to 4:30 PM — plenty of slots throughout the day. Would any time in there work for you, or is there a different day you'd prefer?

Also, are you still looking to move in around that same late-August/early-September timeframe, or has your timeline shifted?
PASSnames the home area, no promises, no PII leak
2978 Krista StreetShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 13 days ago
2978 Krista Street, Grand Junction, CO
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (2978 Krista Street)
372 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
372 Ember Lane
INACTIVE
?
Inactive
Created 12 days ago
372 Ember Lane, Grand Junction, CO 81501
08
Thanks so much for your interest in 372 Ember Lane!

Here's what's on file for these brand-new duplex homes: 3 bedroom / 2 bath, 1,289 sq ft, with market rent at $2,825/mo (deposit $2,825). Each home comes with an attached garage, a private fenced backyard, and designer kitchen finishes. Right now there's a Grand Opening special running — 6 weeks free rent, plus water, sewer, trash, and gas included for your first year (you'd just cover electricity and internet).

I want to make sure I give you accurate, up-to-the-minute numbers on exactly which homes are ready to move into right now, so I've looped in the leasing team to confirm current availability for you — they'll follow up directly.

In the meantime, would you like to get a tour on the calendar? I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM — just let me know a time that works and I'll get you booked.
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 11 days ago
565 Redcliff Cir, Ridgway, CO 81432
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
Northridge ApartmentsShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 11 days ago
565 Redcliff Cir, Ridgway, CO 81432
Hi again! I saw you'd looked at the one-bedroom here at Northridge Apartments (565 Redcliff Cir) — just wanted to check back in and see if you're still on the hunt for a place.

I'm not able to pull a fully confirmed live availability count right now, so I don't want to give you a wrong number — but I can get our team to double-check and confirm current 1BR options for you.

In the meantime, if you'd like to come take a look in person, I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM — just let me know what time works best and I'll get you set up.
PASSnames the home area, no promises, no PII leak
374 Ember LaneShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
372 Ember Lane
?
Active
Created 11 days ago
372 Ember Lane, Grand Junction, CO 81501
08/27/26
Last
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (374 Ember Lane)
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 10 days ago
2978 Krista Street, Grand Junction, CO
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (2978 Krista Street)
566 Placer StreetShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
566 Placer Street
INACTIVE
?
Inactive
Created 5 days ago
566 Placer Street, Grand Junction, CO 815
Hi Tiffany! Thanks for your interest in 2978 Krista Street — that's a 3BR/2.5BA home, about 1,332 sq ft, listed around $1,950/mo.

I'd love to get you a tour set up for that one. Can you give me a specific day and time that works best for you? Once I have that, I'll get it booked.
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
APPLICATION COMPLETE
?
Application Completed
Created 9 days ago
565 Redcliff
Hi there! I can see you've got a completed application on file for the one-bedroom at 585-201 here at Northridge Apartments, with a move-in date around September 1st. Congrats on getting that squared away!

Is there something specific I can help you with — next steps on the application, questions about the unit, or anything else?
PASSnames the home area, no promises, no PII leak
239 S Elm StreetShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Showing Scheduled 09/09/2026 @8:45 AM MDT for 239 S Elm Street - 2. View
Select inquiry-list-item
239 S Elm Street
SHOWING
Hi there! I can see you've got a showing on the books for Unit 2 here at 239 S Elm Street — a 2 bed/1 bath at $1,550/mo, with a September 1st move-in noted. Is there anything you'd like to update, or any questions I can help with in the meantime?PASSnames the home area, no promises, no PII leak
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
INACTIVE
?
Inactive
Created 8 days ago
2978 Krista Street, Grand Junction, CO 8
Thanks for reaching out about the home at 2978 Krista Street! I'd love to get your tour set up.

Could you let me know a specific day and time that works best for you? Just as an example, I've got openings tomorrow (Saturday) from 9 AM to 4:30 PM if that helps.
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Showing Scheduled 09/09/2026 @6:00 PM MDT for Northridge Apartments - 565-102. View
Select inquiry-list-item
Northridge Apa
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
2863 Florida StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Pomona Park Townhomes
?
Active
Created 8 days ago
624 Eisenhauer Street, Grand Junction, CO 81505
Hi Kimberly, thanks so much for reaching out — and congrats on the quick house sale, that's exciting!

Unit 300 at 624 Eisenhauer (1,528 sq ft, 3BR/2.5BA, listed at $2,495/mo) looks like it could be a great fit for you. I want to make sure I give you accurate, up-to-date info on availability for an October 1st move-in and on the pet policy for your two dogs and cat, so I've passed those details along to the leasing team to confirm directly with you.

In the meantime, I'd love to get a tour on the books so you can see the place. I've got openings tomorrow (Saturday) anywhere from 9 AM to 4:30 PM — would a morning or afternoon time work better for you?
FAILdoes not reference the home (2863 Florida Street)
239 S Elm StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
239 S Elm Street
INACTIVE
?
Inactive
Created 9 days ago
239 S Elm Street, Fruita, CO 81521
08/30/2
Thanks for reaching out about Unit 2 at 239 S Elm Street! I don't have confirmed availability details for that unit pulled up on my end right now, so I've passed your request along to the property team and they'll follow up with you on the specifics, including rent and whether it'll be ready for your October 1st move-in.

In the meantime, if you'd like to get a tour on the calendar, I've got plenty of openings on Thursday, October 1st between 9 AM and 4:30 PM — just let me know a time that works and I'll get you set up. And what name should I put this under?
PASSnames the home area, no promises, no PII leak
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
INACTIVE
?
Inactive
Created 7 days ago
2858 C 1/2 Road, Grand Junction, CO 81501
Hi Paul, thanks for reaching out about Ember Estates HZ! I don't have current unit availability pulled up on my end right now, but I want to get you on the calendar for a viewing.

Could you let me know one specific date and time that works best for you? Once I have that, I'll get it booked.
PASSnames the home area, no promises, no PII leak
Pomona Park Townhomes - 300Showings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Pomona Park Townhomes
INACTIVE
?
Inactive
Created 7 days ago
624 Eisenhauer Street, Grand Junction
Hi Arianna, thanks for your continued interest! Just to flag — Pomona Park Townhomes is actually a 3-bedroom, 2.5-bath townhome community (1,528 sq ft, $2,595/mo), so it's a bit different from the 2-bedroom you were originally looking at. Good news on the dog front though — we're pet-friendly for both cats and dogs here.

I wasn't able to pull a live confirmation on current unit availability, so I've gotten the team looped in to verify that for you.

In the meantime, since your original September 1st move-in has passed, when are you now hoping to move? And if you'd like to come see the place, I've got plenty of openings tomorrow (Saturday) between 9 AM and 4:30 PM — just let me know a time that works.
PASSnames the home area, no promises, no PII leak
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
INACTIVE
?
Inactive
Created 7 days ago
2858 C 1/2 Road, Grand Junction, CO 81501
Hi! So glad you're excited about Ember Estates HZ — thank you for reaching out.

I don't have an online application link on file for this property, so I've passed your info along to the team so they can help you with your application directly.

In the meantime, let's lock in your viewing — what specific date and time works best for you?
PASSnames the home area, no promises, no PII leak
Northridge Apartments - 585-201Showings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
INACTIVE
?
Inactive
Created 6 days ago
565 Redcliff Cir, Ridgway, CO 81432
0
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments - 585-201)
460 32 1/8 Road - 3Showings (1)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
460 32 1/8 Road
APPLICATION COMPLETE
?
Application Completed
Created 6 days ago
460 32 1/8 Road, C
Just let me know what date and time work best for you, and I'll get the tour set up right away!FAILdoes not reference the home (460 32 1/8 Road - 3)
239 S Elm StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
239 S Elm Street
APPLICATION COMPLETE
?
Application Completed
Created 5 days ago
239 S Elm Street,
Hi there! I can see you've got a completed application on file for Unit 2 here at 239 S Elm Street — the 2BR/1BA at $1,550/mo, with a move-in around 09/08/26.

What can I help you with today — are you looking to schedule a tour, or do you have a question about your application?
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
?
Active
Created 4 days ago
565 Redcliff Cir, Ridgway, CO 81432
09/03/26
Las
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
INACTIVE
?
Inactive
Created 5 days ago
2858 C 1/2 Road, Grand Junction, CO 81501
Hi Sylvia! Thanks so much for your interest in Ember Estates HZ — I'd love to get you in for a tour.

Rather than accepting things through Zillow, the easiest way is to just pick a day and time directly with me here. I've got openings tomorrow, Saturday September 19th, from 9 AM to 4:30 PM — morning or afternoon both work. What day and time would you like to come by?
PASSnames the home area, no promises, no PII leak
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
?
Active
Created 5 days ago
2858 C 1/2 Road, Grand Junction, CO 81501
09/03/26
La
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Ember Estates HZ)
Northridge Apartments - 575-204Showings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
?
Active
Created 4 days ago
565 Redcliff Cir, Ridgway, CO 81432
09/03/26
Las
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments - 575-204)
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
NEW
?
Active
Created 4 days ago
2978 Krista Street, Grand Junction, CO 81504
09
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (2978 Krista Street)
Northridge Apartments - 585-201Showings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
NEW
?
Active
Created 2 days ago
565 Redcliff Cir, Ridgway, CO 81432
09/05/26
Hi Sarah! Thanks for reaching out about unit 585-201.

I've got your interest noted, and I can see tour openings starting tomorrow, Saturday September 19th, with times from 9 AM through 4:30 PM. What day and time would work best for you?
PASSnames the home area, no promises, no PII leak
Northridge ApartmentsShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Northridge Apartments
NEW
?
Active
Created 3 days ago
565 Redcliff Cir, Ridgway, CO 81432
09/05/26
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Northridge Apartments)
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
NEW
?
Active
Created 1 day ago
2858 C 1/2 Road, Grand Junction, CO 81501
09/06/26
I've noted that for the property team.

I don't have confirmation anyone's picked it up yet, so I can't give you a timeframe just yet.
FAILdoes not reference the home (Ember Estates HZ)
460 32 1/8 RoadShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
460 32 1/8 Road
NEW
?
Active
Created about 23 hours ago
460 32 1/8 Road, Clifton, CO 81520
09/06/2
Hi Samantha! Thanks for reaching out about the home at 460 32 1/8 Road.

Here's what's on file for it: it's a 2 bed, 1.5 bath townhome, about 1,728 sq ft, renting for $1,300/mo with a $1,350 deposit, and it's available now. It's got an open living layout with a nice nook, good-sized kitchen, a fenced backyard backing up to a quiet pasture, a newer roof, and washer/dryer included. Both cats and dogs are welcome there too.

I noted you're hoping to move in around October 18th — since the home is actually available now, we could get you moved in sooner if that works better, or stick with your target date.

Would you like to come take a look? Let me know a day and time that works for you and I'll get you set up.
PASSnames the home area, no promises, no PII leak
2978 Krista StreetShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
2978 Krista Street
NEW
?
Active
Created about 3 hours ago
2978 Krista Street, Grand Junction, CO 8
All set — just let me know a date and time that works for you and I'll lock in the tour!FAILdoes not reference the home (2978 Krista Street)
Ember Estates HZShowings (0)
Attachments (0)
Activity
Inquiries
Show inactive inquiries
Bulk Actions
New Inquiry
Select inquiry-list-item
Ember Estates HZ
NEW
?
Active
Created about 10 hours ago
2858 C 1/2 Road, Grand Junction, CO 81501
Hi Grady! Thanks for reaching out about Ember Estates HZ — I'd love to get a tour on the books for you.

Could you give me a specific day and time that works best? Once I have that, I'll get it locked in.
PASSnames the home area, no promises, no PII leak

Lead shape audit (2026-09-18)

Read-only audit of 1,172 AppFolio guest cards, 5,517 leasing-inbox emails, and 47 live “New Lead” notices, to answer: how much of Western Slope’s lead volume is actually syndicated through AppFolio, versus staff hand-typing a Zillow lead into a guest card. AppFolio’s own audit log distinguishes the two: “Guest Card Received” means AppFolio created the card itself (real syndication); “Guest Card Created” by a named staffer means a human typed it in by hand, almost always retyping a Zillow lead.

1. Listing inventory. 239 total units, 54 available, across 19 addresses. Of those, 10 show real syndication signal, 2 (Lincoln Apartments, Flats on Elm) are 100% hand-copied with zero syndicated leads, and 5 show no guest-card activity in 90 days despite being marked available.

PropertyUnits availableSyndicated?Cards, last 30dCards, last 90d
Ember Estates HZ26Yes — 8 of 10 (90d) auto-received910
Northridge Apartments8Yes — 25 of 28 auto-received1528
Pomona Park Townhomes3Partial — 3 of 26 auto-received326
460 32 1/8 Road2Partial — 15 of 31 auto-received831
486 32 1/8 Road1Partial — 2 of 12 auto-received512
239 S Elm Street1Partial — 4 of 9 auto-received59
566 Placer Street1Partial — 2 of 7 auto-received47
2980 Emerald Circle1Partial — 1 of 6 auto-received26
2863 Florida Street1Partial — 4 of 6 auto-received16
367 Ember Lane1Partial — 13 of 18 auto-received718
Lincoln Apartments1No — all 19 cards hand-typed1119
Flats on Elm1No — all 9 cards hand-typed49
2841 Morningside Court1No — 4 cards, all hand-typed04
2978 Emerald Circle1No — 2 cards, both hand-typed12
2206 N 22nd Street, 2982 Emerald Circle, 3138 Perkins Drive, 630 S 7th Street, 361 Ember Lane1 eachUnknown — zero cards in 90 days00

2. Lead channels, last 90 days. Of 282 guest cards, 42% (118) were auto-created by a real syndicated feed and 56% (159) were typed in by hand; 12-month totals show hand-typing has been the majority path most of the year (772 of 1,153 clean-origin cards). “Zillow” (non-network) as a source label is essentially 100% hand re-entry (328 of 329); “Zillow Rental Network” is 79% hand-typed (204 of 258). Roughly 45% of the 2,036 Zillow-domain emails into leasing@ over 4 months are real lead threads, the rest are Zillow’s own digests. At least 10 confirmed cases of staff replying to a prospect directly inside a Zillow thread instead of AppFolio, so that conversation may never fully land in AppFolio.

MonthAuto-created (real syndication)Hand-typed by staffNo clear origin
2026-0636662
2026-0727551
2026-0866742
2026-09 (partial)14181
90-day total118 (42%)159 (56%)5

3. MVP scope math. Scoping Clara to “Guest Card Received” (auto-created) cards only, regardless of source label, would show her about 42% of last-90-day volume (118 of 282 cards) and naturally excludes every hand-typed Zillow lead, referral, and shared-application-link lead. “Website” leads are also mixed — 61% (57 of 94) auto-created, 38% hand-typed — and should be scoped the same way: in only when AppFolio auto-created the card.

4. Data-quality notes. No true duplicates were countable (Zillow relay mail carries scrubbed address/name tokens with no join key back to the guest card). 5 of 282 cards (90-day) have no clear origin event. 63 of 1,171 cards (5.4%) show a repeat inquiry on the same card. Only 7 of 1,172 cards (0.6%) show a discrete assignment event — the earlier verbal count of “13 of 1,147 assigned” does not reproduce from structured events and should be re-confirmed before reuse. The occupancy report sums to 239 total units / 54 available, not the “108 across 478” figure previously cited — flagged, not reconciled. 5 “available” addresses show zero guest-card activity in 90 days (2206 N 22nd St, 2982 Emerald Circle, 3138 Perkins Drive, 630 S 7th St, 361 Ember Lane) — likely stale vacancy flags or genuinely unmarketed.

5. Top 5 recommendations for go-live.

  1. Ask the client to syndicate Lincoln Apartments and Flats on Elm — both have a live vacancy today and 100% hand-copied leads; Clara would see zero leads for either under the MVP rule.
  2. Ask them to confirm the 5 “available” addresses with zero lead activity — fix stale vacancy status in AppFolio or get them listed somewhere.
  3. Stop hand-copying “Zillow” (non-network) leads into AppFolio — that source is essentially 100% manual re-entry, invisible to Clara until the listing is properly connected through AppFolio’s own feed.
  4. Get the team to stop replying to prospects inside Zillow’s own message thread — at least 10 confirmed cases; those conversations (and sometimes the lead itself) never fully land in AppFolio.
  5. Decide how “Website” leads should count — recommend treating them the same as everything else: in-scope only when AppFolio auto-created the card, out of scope when a staffer typed it in.
Overall
—
 
—
Shipped
—
Merged
—
In flight
—
Open
—
Waiting on you
Groups — click to filter
Status
—

Where everything sits (2026-09-14 night)

Western Slope’s people have tried to connect a Microsoft calendar or mailbox four times since Sep 11. None of it is their doing, and none of it needs anything from them. This section says what actually broke, how we know, and which fix makes the next attempt work on its own.

The headline: since 10:32Z this morning, production could not record a Microsoft connection at all. A change to how connection records are filed added a database operation the production account is not permitted to perform, so the write that records a connection — or a pending approval, or even a failure — throws instead of saving. Nobody noticed for thirteen hours because nobody at a customer completed a connect in that window. Two of the four attempts (Jason at 22:24Z, Kat at 22:26Z) fell inside it, and neither left a trace of any kind. That one is fixed and deployed as of 00:42Z tonight.

The second theme is that three separate things were each blamed on the customer’s Microsoft setup and none of them were. Jay’s calendar was never revoked — we were asking Microsoft to renew it with permissions he had never been asked for. The back-office page that read “Not connected” for him was looking him up by the wrong id. And the company mailbox has said “waiting for a Microsoft admin” since Sep 11 even though nothing in the product has ever asked their admin anything.

ItemRoot causeEvidenceFixStateWhat makes their next attempt just work
Production cannot record a Microsoft connection A change to how connection records are filed, merged 2026-09-14 10:32Z, added a conditional database check the production account has no permission for. Every write that records a connect, a pending approval, a failure or a reconnect now throws. Sentry 7732381599, dynamodb:ConditionCheckItem denied on propflow-prod; one occurrence, 2026-09-14 23:59:21Z, on our own Microsoft test tenant. Introduced by #8406, commit 1d4ead6dae. Last connection successfully recorded anywhere: 2026-09-11 22:46:37Z. #8541 Merged 2026-09-15 00:42Z, not yet proven in production Already done, as of 00:42Z tonight. A consent that comes back from Microsoft is saved again instead of thrown away. Every connect between 10:32Z and that deploy was lost.
Kat’s calendar connect went nowhere She was shown the calendar step and sent to Microsoft; Microsoft never redirected back to us. Because nothing logs an attempt, we cannot tell from our side whether the window was closed, blocked, or stopped at Microsoft. Her account carries the calendar-welcome stamp 2026-09-14 22:26:07.172Z and no calendar record of any kind, live or historical. No error was reported for her account in the 90 minutes around it, and the 23:59Z failure above is the only occurrence of that failure ever — so her browser never reached our callback. #8541 merged; #8542 open Half done #8541 already makes a returning consent save. #8542 adds the attempt log, so one that dies at Microsoft is visible instead of silent.
Jason never got a calendar connected Same shape as Kat: offered the step, no attempt recorded anywhere. He finished the rest of onboarding normally. Signed in 22:23:31Z, set up his second factor 22:24:07Z, finished the teammates step 22:24:33Z, was offered the calendar 22:24:41Z. He has no calendar record and no credential. His email is on the 9thpathrealty.com domain, not Western Slope’s. #8541 merged; #8542 open Half done Same two fixes, one of them already in. Nothing about his account or his Microsoft tenant is in the way.
Jay’s calendar was never revoked Our token renewal asked Microsoft for company shared-mailbox permissions that his personal calendar consent never included. Microsoft answered “not consented”, and we read that answer as “the customer revoked us”. Read-only probe, 2026-09-14: asking with the company permission set fails with AADSTS65001; asking with the personal set succeeds and returns Calendars.ReadWrite User.Read. His record still reads connected, stamped 2026-09-11 22:46:37.400Z, with no failure ever written to it. No surface in the product could have shown “revoked” this morning — that word came from a diagnostic we ran, not from a page. #8525 Merged 23:38Z, not yet proven in production Already fixed in code. His calendar has been usable the whole time; nothing on their side ever needed touching.
The back-office page reads “Not connected” for Jay The staff page looks a teammate’s calendar up by their sign-in id instead of their person id, so it finds nothing and reports nothing found as nothing connected. His calendar record is filed under person pers_224f0528…; the page queries with login b5399836…. Confirmed the same mistake exists nowhere else in the code. #8528 Open, in CI Nothing for the customer at all — this is a wrong reading on our own screen, not a broken connection.
The company mailbox has said “waiting for a Microsoft admin” since Sep 11 Two things at once. We write “waiting for admin approval” on the way out to Microsoft, before Microsoft has said anything — so the wizard reports a request that was never made. And the product has no code path that asks a Microsoft admin for anything: the function that builds that request exists and has no caller. Both company records (mailbox and calendar) still read pending_admin_approval, stamped 2026-09-11 19:28:05.570Z, with no credential behind them and nothing written since. Their Sep 11 attempt started 19:28:05Z and the browser came back at 22:41:26Z, three hours later, past the link’s life (Sentry 7727344412). buildAdminConsentUrl still has no caller on main. None open Not started A connect flow that tells the truth about what it did, and that actually sends their Microsoft admin a request. Both still to be built.
The permissions the company flow asks for are not declared on our Microsoft app The company flow requests three shared-mailbox permissions our app registration does not list, so Microsoft’s screen could never have granted them even if an admin had reached it. Their Microsoft tenant holds exactly one consent record for us, read fresh tonight: tenant-wide, scope Calendars.ReadWrite User.Read, created 2026-09-11 22:46:34Z by Jay’s calendar consent. No mail permission has ever been consented in their tenant, and we hold no application-level permission there. App registration change (approved, in progress) In progress Once the three permissions are declared, the company screen can show them and an admin can grant them in one pass.
Camellia is not a precedent for the company flow Camellia’s mailbox was not consented by a passing user on the company flow. It was connected in April through the older per-property flow, by signing in as the mailbox account itself, and their Microsoft tenant carries a tenant-wide grant that includes the mail permissions. Property record connectedAt 2026-04-06 18:29:40.926Z; the stored token is an interactive human sign-in as the mailbox account with password and second factor. Their tenant’s single consent record for us is tenant-wide and covers Mail.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite User.Read. n/a Understood Nothing to copy: that route means holding a customer’s mailbox password, which we will not do. The company flow has to work on its own.
The staff screen said Clara is switched off for them The back-office screen showed a sentence about our team turning Clara on after a dry run to admins of companies that are not live. It was not true. Copy removed; the box now appears only for a company that really is live. #8526 Open, in CI Nothing — this is our own screen, and no behaviour changes with it.

What we could not verify. Three things. We could not read the request log for Kat’s and Jason’s attempts: the only log surface reachable from a session tails live traffic, and the historical view is a browser-only console, so the 22:24–22:26Z window is gone for us. We cannot say whether Microsoft showed Kat anything, only that it never came back. And we cannot read the consent record on Camellia’s Microsoft tenant the same way as Western Slope’s — Microsoft refused the tenant-wide query and only answered the one about our own app, which is why the Camellia row reads tenant-wide rather than naming who granted it. Everything else in the table above is from production data, Sentry, Microsoft’s own answers, or the code on main.

The order that matters. #8541 landed at 00:42Z, so the product can record a connection again — that was the one making everything else invisible. Next is #8542, so the next attempt leaves a trace whatever happens to it. #8525 (merged) and #8528 (open) close out the two things that were misread as the customer’s fault. The company mailbox, which is what Western Slope actually needs, is behind the app registration change plus a flow that genuinely asks their admin — that one is still to be built.

Every row opens: when it was added, why it exists, and the links that prove it. Rows waiting on a human carry a Decide → link straight to the answerable question on the decisions page. Statuses are re-derived from live PR, decision and prod-evidence state by bin/refresh-trackers; nothing here is typed by hand, and merged is not shipped until a prod_evidence permalink says the fix was exercised in production.

PropFlow Docs