Lead to home matching: Ember Estates miss

Ember Estates case record. Superseded 2026-10-29 by Home Resolver: lay of the land.

Results in, 4 asks open · 2026-10-28 · team only · no code PR until Fede says go

"The issue is that we couldn't locate the property."

Fede, 2026-10-28

Open asks for Fede

The problemChoicesWe pickIf you say nothing
1. Website contact forms. Western Slope's website "Contact Us" leads: 7 since Oct 3, none answered by Clara (dropped as an auto-reply before reading; fix in progress). Situs had 3.A: Clara answers them.
B: leave them.
AIt ships anyway: a dropped lead is a bug.
2. Ember homes stored twice. All 27 Ember homes exist twice: in the community (listing, price) and as a house (lease). MoreA: the house is the home.
B: the community copy is; move every lease.
C: keep both, patch links.
AClara keeps mixing the copies' prices.
3. Build the home-finder. Clara misses the home when a lead types a street we do not store (Ember, 3 times). Tested on a year of leads: right home twice as often, never wrong. MoreA: the one small fix (answer from the handed property, hand unit streets, tools take the thread's property, search only with no property).
B: the four-step home-finder as designed.
A: small fixNothing ships; misses continue.
4. Two unmatched names. Two leads named Barcelona by its owner's company name and a listing site's nickname. MoreA: add both to Barcelona's knowledge base.
B: leave them.
AThose leads stay unmatched.
Results (Oct 28): before and after

Proof of concept: how often each set of matching rules finds the right home, over a year of real leads

Withdrawn Oct 28 evening. The numbers in this table and the "What it means" paragraph below were a text-only simulation scored on rows that do not occur in production; see Second pass. Kept for the record only.

TodayNew rulesRules + model on leftovers
Right home, of the 500 leads whose text names a home47% (237)90% (452)92% (459)
Right home, of all 916 leads26% (237)49% (452)50% (459)
Wrong home0% (0)0% (0)0% (0)
Known misses still missed (% of 251)93% (234)4% (9)0.8% (2)

What it means: 416 of the 916 leads (45%) are guest cards whose text names no home at all ("can I schedule a time to see this?"). Those are not a matching problem: AppFolio already filed each card under its property and that is where the home comes from. Of the 500 leads whose words do name a home, the rules find it for 92%, up from 47% today, and never pick a wrong home. The 41 still open: 13 land on an Ember sibling (the Ember decision), 20 name nothing specific ("the 205 floor plan", "Lakewood, CO 80214"), 4 carry a Zumper listing id no past card taught us, 2 need an alias we do not have, 2 have unknown truth.

Second pass, Oct 28 evening: the prototype numbers are withdrawn

Fede's read: guest cards arrive with the home, and Clara is handed the property, so no lookup is needed. An independent pass over the real data confirmed it. The earlier numbers scored text-only rows that never occur in production.

Real failures: 30 leads

What went wrongLeadsDetail
Reply looked the home up by name although the thread already had the property5 people (6 events)Ember 3, Northridge 2
Dropped before any matcher ran19Website contact form 10, AffordableHousing 6, lead-scope 3
Email with no card, misfiled on the front door65 at Western Slope, 1 at Situs

The known misses on this page, checked one by one

CaseReal event?Thread had the property?Fixed by answering from the handed data?
Ember, Oct 12, Alec B.YesYesYes (unit streets also let Clara confirm the address)
Ember, Oct 26, Shannon W.YesYesYes
Ember, Oct 28, Micheal M.YesYesYes
Northridge, Oct 7, Thomas R.YesPartly (tagged "likely")Yes, if the tagged property's units are handed
Northridge, Oct 28, Breck L.YesYesYes (the application takes the thread's property, not a text reference)
Lincoln, 1456 Bunting, Sep 15 and 17Yes (email, no card)NoNo, it is filing; the Oct 1 fix covers it
Situs Aspen Leaf Apartments, Oct 27Yes (email, no card)NoNo, it is filing; a separate fix is open
Flats on Elm 1250No, made upn/an/a
18 Situs fixture casesNo: AppFolio filed each correctlyYesNothing to fix on this path

Of 38 "known misses", 8 were real events. 6 of those are the same mistake. The "251 known misses, 93% missed" counted test rows, not leads.

The simplest design

  • Card: the card's property is the answer, never a lookup. Unit = AppFolio's unit id, else the exact label, else "this property's open homes". Hand unit streets with the home facts.
  • Existing thread: the thread's property. Application and other tools take the thread's property and unit, never a text reference. Search only when the thread has no property.
  • Email: mailbox binding first; then subject and body through one address list. The two drop rules exempt known lead relays.
  • A search miss on a thread that has a property: internal alert, answer from the property. Never a staff email.
  • No alias confirmation step, no eight-layer cascade.

Throw out, keep

Throw out: the 916-row "right home" rate (26% to 50%), the 251-row "known misses" rate, the Situs router 35 of 48. Keep: the 38 cases as a regression list split real / simulated / synthetic, the 50 of 53 email filing number, and the mirror and unit facts.

Report: /Users/federicochapa/agents/003/reports/Lead-to-home failures second pass 2026-10-28.md. Scripts 01 to 08 in resolver-poc/second-pass/.

Percent of 916 leads: 974 real leads and named cases at Western Slope, Situs and JP&Co, minus JP&Co's 58 emails (the mailbox already files them; the new name rule matches all 58). Known misses: percent of the 251 still missed today. 13 Ember parent-or-sibling picks count as neither right nor wrong. Source: resolver-poc/summary-for-fede.md.

Replay of today's live matching code, with and without the chosen fix (simulated)

TodayPick A planted
Known misses still failing on the channel they happened on (of 16)1610 (9 on email filing)
False matches on the year's corpus0 of 7930 of 793
Situs mailbox router: cards filed on the front door35 of 4835 of 48

Source: property-locate/results/before-2026-10-28.md. Detail in section 6 and section 7.

Decisions so far
  1. Decided (Fede, Oct 28): a search miss is our bug. It raises an internal alert and Clara answers from the card's property; never a question to client staff.
  2. Pick A, decided (Fede, Oct 28, "ok"): one alias list for every channel, filled automatically from building, unit and listing addresses plus listing ids; ids first, words last. Loosened name rules (A1) stay in as a late fallback (Fede: "I think it's a good last fallback"). No paid address service (A5) for now (Fede: "no, this not yet"). The proof of concept and the harness are done (Oct 28): Pick A stays, with two amendments (see Results).
  3. Pick C, first email: one home, its live listing price, or no price.
  4. Decided (Fede, Oct 28, "we don't want a human there"): the alias system's "suggested, waiting for a person to confirm" step is removed. "2858 C 1/2 Rd" had been learned twice at Western Slope and sat unconfirmed because no person was ever in that loop. Sync-built aliases are active on arrival; a learned phrase is confirmed by the engine from evidence (the card it arrived on already names the property), never by a click.

Acceptance bar (Fede, Oct 28): "whatever solution here needs to cover 100% of the misses": every known miss resolves to the right property and the full year's corpus shows zero wrong matches, before any code ships. Known misses include Ember "2858 C 1/2 Rd" (Oct 12, Oct 26, Oct 28), Northridge "575 / 585 Redcliff Cir" vs stored 565 (Oct 7, Oct 28), Flats on Elm "1250 Elm Avenue" vs stored 1240, and Aspen Leaf, Lampliter and Olde Town Terrace at Situs. All five Western Slope cases sat on threads that already carried the right property.

Where it stands (Oct 28): not met. With Pick A planted, 10 of 16 known misses still fail on their own channel (9 of them on email filing) and false matches stay at 0; the proof of concept leaves 2 of 251 unreached. Detail in sections 6 and 7.

Why this is its own page

The fix spans Western Slope and Situs and every channel (email, text, phone). The existing pages are closed incident write-ups (Ember Estates, September) and a Situs-only report.

1. What happened: one cause, two symptoms

Micheal M. asked on Zillow about "2858 C 1/2 Rd, Grand Junction". No email reached us: AppFolio created guest card 3053 and filed it on Ember Estates itself. Clara's reply ran on Ember Estates. Inside that reply she searched for the address, nothing matched, and she treated it as a home we might not manage.

Cause: address not matched in-reply search found nothing Symptom 1: emailed Western Slope's leasing inbox "asked us something we could not answer" (our miss, sent to them) Symptom 2: replies built from mixed homes $2,300 in one email, "$2,550 or $2,795" in the other
One cause, two symptoms. With no home located, Clara asked the team, and the price facts fell back to every open home at the property.
#What happenedWhere in codeEvidence
1Cause. Clara's in-reply property search returned nothing. AppFolio had already named the property on the card.search_properties → resolvePropertyByName reads building names, building addresses and active aliases, never unit addressessearch 14:09:36 UTC (turn disp_29568bcd, on appfolio-399); stopped draft dstop_9a37538f: "I'm not showing that address"
2Symptom. Clara emailed Western Slope staff about our own miss.forward_to_property_manager staged a note; flushAutonomousTeamNote sent it because the draft deferredemail msg_93d03868 to Western Slope's leasing inbox, 14:09:51 UTC; matter matter_12e6dcd5 (left alone)
2bConsequence. A draft check forced a rewrite that dropped the honest line and invented a reason for two prices.first-email check draft_checks: no-tour-times stopped the draft; the retry was sentstop dstop_9a37538f (outcome sent_after_retry); sent msg_35826329 14:10:56 UTC: "$2,550 or $2,795 a month depending on lease length", the address caveat gone. Your rules: checks only block; nothing rewrites her message.
3Symptom. The two emails described different homes and prices, one a delisted home.decideGuestCardHomeFacts fell to "whole property"; openHomeTypes took the lowest rent$2,300 = unit 365 (1,228 sq ft, delisted Oct 27); $2,550 = 363; $2,795 = 364. Lease length backs neither.
4Observed only. Two AppFolio interest records a minute apart, two emails.n/amessages 7681 / 7682 on card 3053. Fede: "The second inquiry for the same person on the same property is not necessarily the bug here." No options proposed.
2. Why the property was not found

Ember Estates has two addresses. Our building record holds one; the other sits on two of its unit records, where the search never looks.

OUR PROPERTY RECORD Ember Estates 374 Ember Lane matcher reads this TWO EMBER UNIT RECORDS "2858 C 1/2 Road - 361 Ember Ln" and "... - 2862B Florida Street" search never reads units ALIAS LIST "2858 C 1/2 Rd" learned, suggested, no target only active rows are used
The data was there; nothing confirmed it. Clara had already missed this exact address twice before: the alias row was created Oct 12 and seen again Oct 26. It sat as a suggestion nobody would ever confirm. Zillow's daily report also maps listing 13959823 to 2858 C 1/2 Rd; we skip that report.

Related, not the center: Situs email leads are filed by a different matcher that does not read the alias list either; "Aspen Leaf Apartments" missed "Aspen Leaf" on Oct 27 (harness).

3. Pick A (decided): how Clara finds the property a lead means

How Clara turns the words in a lead into one of our properties, and the options we weighed.

Oct 28 results: Pick A stays decided, with two amendments: the mailbox router reads the same alias list, and one twin rule for a home that is both a unit and its own record (sections 6 and 7).

Matching lives in the PMS adapter layer behind a written interface. Core flows never name AppFolio; listing ids are stored with a provider prefix.

OptionWhatEmber?Aspen Leaf?Cost
A1 Loosen name rulesLooser contains / suffix rules. Not rejected: Fede (Oct 28) "I didn't reject this… I think it's a good last fallback". Runs after ids and aliases, before the model; the proof of concept measures its gain and false matches.NoYesS
A2 One alias list, every channelEmail, text and phone all read one list, filled automatically from building addresses, unit addresses, listing addresses and listing ids, with address normalising ("C 1/2 Rd" = "C½ Road"). The engine confirms learned names itself; no human queue.YesLikelyM
A3 Listing ids onlyKey on Zillow's zpid / listing id from the link and the daily report.YesSecond lead onM
A4 Lead address per buildingEach building gets its own inbox address (JP&Co today: 151 of 151).Email onlyYesS build, L rollout
A5 Outside address serviceClean addresses with a paid geocoder. Fede (Oct 28): "no, this not yet". The proof of concept measures a free geocoder only, to size what it would add.UnverifiedUnverifiedM + spend
A6 Model decidesHand the model the full property list plus the card's own property and let it pick.LikelyLikelyS

Cells are reasoned, not measured, except one: harness control C1 shows an active "2858 C 1/2 Rd" street name finds Ember Estates with today's code. A1 to A5 come from the 003 Situs report; A6 is new here.

4. Decision 1 (decided): a search miss is our bug

"so this is first bug. we should not email the customer this is an engineering bug."

Fede, Oct 28

Before

Search misses, Clara emails the client's leasing inbox "is this one of our managed properties?"

Decided

Our search cannot see a property AppFolio already named on the card: raise an internal alert, and Clara answers from the card's property. Never a question to client staff.

Decided by Fede, Oct 28 The fix is owned by another session; this page does not open it.

5. Pick C: which home and price go in Clara's first email

Your 10/22 rule: never over-share availability. This case adds: never a delisted home's price.

6. Proof of concept: which matching rules we really need

Which matching rules we need: we ran each rule over a year of real leads and kept the ones that add right homes without ever picking a wrong one. Prototype only: local, read-only, no repo change, no CI. Every matching layer was run alone and stacked over 974 real leads and named cases at all three customers.

Withdrawn Oct 28 evening. The numbers in this table and the "What it means" paragraph below were a text-only simulation scored on rows that do not occur in production; see Second pass. Kept for the record only.

TodayNew rulesRules + model on leftovers
Right home, of the 500 leads whose text names a home47% (237)90% (452)92% (459)
Right home, of all 916 leads26% (237)49% (452)50% (459)
Ember parent or sibling home (not counted wrong)0.3% (3)1% (13)1% (13)
Wrong home0% (0)0% (0)0% (0)
Known misses still missed (% of 251)93% (234)4% (9)0.8% (2)

What it means: 416 of the 916 leads (45%) are guest cards whose text names no home at all ("can I schedule a time to see this?"). Those are not a matching problem: AppFolio already filed each card under its property and that is where the home comes from. Of the 500 leads whose words do name a home, the rules find it for 92%, up from 47% today, and never pick a wrong home. The 41 still open: 13 land on an Ember sibling (the Ember decision), 20 name nothing specific ("the 205 floor plan", "Lakewood, CO 80214"), 4 carry a Zumper listing id no past card taught us, 2 need an alias we do not have, 2 have unknown truth.

Percent of 916 leads (974 minus JP&Co's 58 emails, left out above); known misses as a percent of 251. The table below counts JP&Co's emails, which is why its totals (240 / 523 / 530) are higher.

Per customer and channel (rows whose words name a place)

Customer, channelRowsTodayNew rulesRules + modelWrong
Western Slope guest cards13171 (54%)120121 (92%)0
Western Slope emails115111 (97%)111111 (97%)0
Western Slope named cases1681616 (100%)0
Situs guest cards9229 (32%)8182 (89%)0
Situs emails1691414 (88%)0
Situs named cases1269 (7%)119124 (98%)0
JP&Co guest cards43440
JP&Co emails580*58580

* Simulated without the per-building mailbox step; production files these by mailbox today. 0 regressions against today.

Keep: 7 layers, in this order (each adds leads, none picks a wrong home)

  1. Link ids learned from past guest cards (Zumper building and listing ids, padmapper ids, Zillow building links). 12 leads nothing else gets, including Balsam Manor = Barcelona. L1z
  2. Exact aliases built at sync, including every unit's street. Renters type a unit's street while the building is filed under another (Ember, Northridge, Lampliter, Barcelona, Lowry Flats). First rule to fire on 355 rows; fixes most misses. L2
  3. Loose address match plus one-letter typos ("Radcliff", "Aspenleaf", "Richtofen"). L3 + L3t
  4. One-word building names ("Camellia House", "Zephyr 10", "Dahlia #10"), with a guard for words that are also states, streets or cities. 38 rows only this gets; all 58 JP&Co emails. L3b + L3n
  5. Unit labels like "585-201": 7 Northridge leads. L3u
  6. Street-only match, as the last rule ("3295 S Bryant", "1391 Zephyr"). L3s
  7. The model, last, on leftovers only: +3 (Lamplighter twice, Old Town Terrace). L5h

Design note: layer 4 extends the name rule in PR #22994 rather than replacing it (the widened rule covers every row the PR's rule gets but one).

Not worth it

  • Free geocoding: adds 0 leads the rules miss; 143 answers land on several homes within 150 m of each other.
  • Model first: 3 wrong homes ("2984 Emerald" read as 2982). The rules made none.
  • Zillow home ids: zero rows carry one.

The 2 misses nothing reaches

  • "IH Holdings Nineteen LLC": the owner's legal name; Situs data never links it to Barcelona.
  • "Balsam Manor" typed as words, no link: Zumper's own name for Barcelona (the link form is solved by layer 1).

Both need a name alias on the property. That is a knowledge-base write, so it is Fede's call (open ask 4).

All aliases are built in the PMS adapter at sync; core code only asks "which home?". Sources: scratchpad/resolver-poc/summary-for-fede.md and results.md (session 003).

7. Replay: where today's code fails, before and after

Where today's live code fails, and how much the chosen fix would help. Local replay of today's production matching code over snapshots of each customer and a year of guest cards. No model, no sends, never CI. Each lead's words are read through four channels: Clara's in-reply search, a tool naming a home, the scan over the renter's message, and the company-mailbox router.

TodayPick A planted
Known misses failing on the channel they happened on (of 16)1610
Known-miss rows passing, every channel (of 142)4296
False matches, a year of guest cards (793 rows)00
Situs mailbox router: cards on the front door (of 48)3535

"Pick A planted" re-runs each row with the expected alias list added as active rows. It is a model of Pick A, recorded, never counted as a pass. All 16 planted-defect controls behave.

By family

FamilyCasesRowsPass todayFalsePick A: pass / false
F0 Known misses (every miss a person hit)3814242096 / 0
F1a Email leads (every real lead email, by subject)531501390139 / 0
F1b Full corpus (a year of guest-card inquiries with words)3497932420261 / 0
F1c Text and phone (real search calls, caller quotes)13147014 / 0
F2 Spelling variants (generated)2561,0242420636 / 0
F3 Ambiguity, collisions, foreign addresses175848046 / 0
F4 Decision 1 (a miss on a card that names the property)6610n/a
F5 First reply home facts (Pick C as C1)2200n/a
F7 Sync-built aliases (named facts)232300n/a
F8 Situs mailbox router (the 48 cards)565615015 / 0

F6 (do channels agree on the same words) is rendered from F0 to F3: known misses disagree across channels in 24 of 38 cases today, 13 with Pick A planted.

What the run says about Pick A

  • The mailbox router never reads aliases. Every email-filing number is the same with and without the alias list (15 of 56 rows). It also misses exact stored names: 17 of 20 name rows, mostly "Lampliter Apartments", file on the front door. Amendment 1.
  • Twins. With aliases planted, the text scan sees two records for one Ember home and picks neither: 6 rows go from right to none. Amendment 2: one rule for a home that is both a unit and its own record.
  • Misspellings, "C ½" spellings and Zumper links stay red with aliases ("Lamplighter", "Car Street Flats", "Aspenleaf", "Old Town Terrace", "Brian Gardens", "Radcliff"). They need the late fallback (A1) or link ids.
  • Decision 1 timing. On Oct 28 the staff note went 2 seconds before the email that answered in full. A check only at the end of the turn is not enough: the note has to wait for the final reply, or a miss never stages a team note at all.
  • 1456 Bunting Ave is Lincoln Apartments (four unit rows), not a home outside our list. A label error the run found and fixed.

Data limits

  • Guest cards cover one year (2,894 inquiries); about 12% (349) carry the renter's own words.
  • Western Slope emails start Sep 15; Situs emails cover Oct 23 to 28 only (source: resolver-poc/results.md).
  • Email bodies are not stored, so email leads are read by subject line only.

The morning seed suite (13 cases) still reads 5 of 12 right; its 7 controls behave. Branch fede/lead-home-matching-harness, head 7bf80bddb0, local only, no PR. The harness session's instruction: squash before any push, because earlier local commits hold real first names and one renter surname in the name checks. Sources: property-locate/HARNESS.md and results/before-2026-10-28.md.

8. Ember homes exist twice in AppFolio (open, Fede's pick)

Open, Fede's pick This is separate from the matching decision. Matching finds the property; this is which copy of a home is the record.

Western Slope holds each of the 27 Ember homes twice: once as a unit of Ember Estates (the portfolio, property 399) and once as its own single-family property. Both copies come straight from AppFolio.

WhatLives on
Leases, current tenants, recent applicationsThe 27 single-family copies (the portfolio has 0 leases)
Live listings, price, available dateThe portfolio rows
Leased or not (the truth)Single-family copy
On the market, at what price (the truth)The live listing

The right answer on Oct 28

HomeReading
363 EmberListed, available now, $2,550
364 EmberListed, available now, $2,795
2863 FloridaListed, from Nov 2, $2,775
365 EmberDelisted Oct 27. Clara's $2,300 and 1,228 sq ft came from this home.
374 EmberOccupied. Clara named it as the home.
372, 362 Ember; 2867 FloridaOccupied
19 othersUnleased, not listed

Gaps in the Oct 19 cross-check

  • Lettered house numbers never match (2860A, 2860B, 2862A, 2862B, 2866A, 2866B, 2868A, 2868B: 8 homes). If one gets a lease, its portfolio row still reads open. All 8 are vacant today.
  • One-way only. The single-family copies still count as separate open homes at their own price (363 Ember is $2,825 on its own record vs $2,550 listed). Whether Clara has quoted one: not checked.

Other customers. Situs has the same shape: its "DU Portfolio" (property 43) holds 17 rows; 16 of those houses are occupied or pre-leased (14 occupied, 2 marked vacant-rented). 2281 S Lafayette reads open at $2,500 because "S." breaks the match, though its house is occupied (whether offered: not checked). JP&Co: none.

OptionWhatCost
A (recommended)The home is the single-family record. Ember Estates becomes a marketing parent holding the community's names ("Ember Estates", "2858 C 1/2 Rd", the Zillow building id). Portfolio rows become the listing feed, linked to their home by listing id, then by a letter-aware address plus size.The lease is the durable fact; one id from prospect to resident; fits Gera's "a group sits between" shape.
BThe home is the portfolio unit; the single-family copies become occupancy feeds.Every lease, tenant and maintenance record must be remapped; residents keep two ids per home.
CKeep both copies and patch the links (letters, "S.", a reverse check, price from the live listing).Cheapest, but every home stays twice in search, lists and pricing, and the shape recurs (Situs).

In every option the link is made at the PMS sync boundary (the adapter), never in core flows, and a row that does not link cleanly stays visibly unresolved. Source: research_notes/Ember Estates property addresses/ember_double_representation.md (read-only, Oct 28).

PropFlow Docs