Home Resolver: lay of the land

How a renter's words become a building and a home today, on every channel, and the one central resolver proposed to replace it. Proposed, pending Fede's review. Nothing here is shipped.

2026-10-29 · session 003 · replaces the Oct 28 email-only page (its prototype numbers were withdrawn) as the hub for this effort · Gera's handoff via Agent Smith: handoff page

The fear: a renter says "I'm calling about Aspenleaf" and Clara cannot find it. Today that happens on a miss, not a wrong guess: on 147 real phrases the code missed 343 of 814 testable channel answers and picked a wrong home 4 times.

Matchers in code
33
31 functions + 2 places the model matches in its head; 145 call sites
Address cleaners
21
1 folds "8th" = "Eighth"
Saved other names in use
0
Situs 0; Western Slope 2 learned by Clara, never confirmed
Misses never recorded
9 of 18
paths where nobody learns the renter's words

Today: four doors, thirty-three matchers, no shared memory

Phone call Text message Email (2 lanes) Guest card (by id) TODAY 33 matchers 21 cleaners 3 name stores that never meet miss → front door, dropped, or "which home?" 4 wrong guesses (after-call best guess) PROPOSED: one resolver 1. Keys we already hold PMS ids, listing ids, dialed line, thread home 2. One cleaner, one name book names, old names, streets, units, nicknames 3. One question, never a loop several fit → ask once; none → street, then hold Every miss is written down
Counts from the consolidated inventory (31 code functions, 2 model-in-head, 145 call sites, 21 normalizers). Harness results from the red run on main, 2026-10-29.
Why the doors disagree: three name stores that never meet

Three name stores exist and never meet: Gera's saved "other names" (read by the phone building search, never by the home matchers or the company-mailbox email lane that Situs and Western Slope leads take), the listing title and description (read by the home matchers, never by the building search), and the newer address index (phone after-call, calendar blocks, text turn-home and phone maintenance; never email filing). Staff have typed no saved names at either customer; Clara has learned two at Western Slope that sit unconfirmed; a PMS import script exists and has never been run. Western Slope's alias note for Ember Estates sits in a field we do not store.

What the harness measured (red run on today's code)

147 phrases, every one taken from a real place: Situs and Western Slope guest cards and calls, Eileen's onboarding calls, Ember Estates, and 14 recorded incidents. Each phrase runs through the real entry function of 6 channels against the customers' real building lists. Local only, zero CI.

ChannelPassFailUntestable
Company mailbox email785217
Listing-site "New Lead for X" email448617
Phone, during the call82650
Phone, after the call107400
Text on the company line805017
Staff desk hint805017
All47134368

Untestable = spoken-only phrases (speech garbles) on text and email. 52 of the passes are "nothing happened" on phrases where Clara should have asked which home; no channel asked. Prototype scores on the same phrases: below.

The ten most telling misses
  • "2858 C 1/2 Rd" (Ember Estates' old name, three real prospects): missed on all six channels.
  • "374 Ember Lane": held under two records, so the listing-site email drops it as ambiguous and the mailbox files it on the front door.
  • "2988 Krista" (a recorded production miss): front door on mailbox and text, dropped on listing-site email.
  • "Aspen Leaf Apartments" (Tyler's lead): dropped on listing-site email; five channels resolve it.
  • "1456 Bunting Avenue, Apartment 4": no home during the call and on the staff desk.
  • "Old Town 109": after the call, guessed Aspen Leaf, a wrong building.
  • "71st Place Apartments, unit 303": no such record; after the call, guessed Zephyr.
  • "2796 Krista Street": should ask (2976 Krista or 2976 Emerald); after the call, guessed 2978 Krista.
  • "486 Tracy Drive": should ask; guessed 484 Tracy.
  • "the Lamplighter apartments", "the Yulara" (floor-plan name): missed everywhere. These stand for most failures: nicknames, spellings and floor-plan names the records do not contain.

All four wrong-home guesses come from the after-call step that keeps its best guess when several homes match.

Three local prototypes on the same 147 phrases

PrototypeRight of 147Wrong homeAsked, rightlyAsked, should have found itChannel results right of 814
Today's code—40—471
P1: keys, then one cleaner over the full home list1320105760
P2: P1 plus nearby-streets geography1320105760
P3: P1 plus a model tie-break on the undecided 40139–140010–111–2778–780
P1 on property names and addresses only (no unit lines)11201017644

What moved the number: the unit street lines the home list already holds (112 to 132). Saved other names added nothing on these phrases; geography added nothing. The model sees only the 40 phrases the rules cannot decide, answered the same way on 38 and 40 of them when asked twice, and every model answer passes two fixed checks (a house number must belong to the home it picks; a word that only names a place never picks a single home). The 7 it still misses are names no record holds ("The Oaks", "the Yulara", "Elevate"), two speech garbles, and an owner-company name; none files a wrong home. Caveat: the place check was added after one wrong file in the run, so the zero is tuned on these phrases. Local only, model answers cached, no production reads or writes.

The resolver: one capability, three layers, one exit

Before

Each door matches its own way. A miss ends at the front door, a dropped email, or a question with no memory. The renter's words are recorded on at most 9 of 18 paths and read back by none.

After

Every door calls resolveHome(words, company, context) and gets back one home, a short list with one question, or "none" with the one question to ask. Every miss is written to the name book.
  1. Keys first. A guest card's PMS id, a listing id when a relay email carries one (today every link is stripped before parsing and no id is kept), the dialed line, the thread's home. No words compared.
  2. One cleaner over one name book. Building names, every past name after a rename, unit labels, unit streets, property addresses, listing addresses, nicknames the customer told us, and names learned from misses. Lenient: "Aspen Leaf" inside "Aspenleaf Apartments" counts; "E 8th" is "East Eighth"; "2860A" is a house number. The only guard is uniqueness within the company.
  3. One question, never a loop. Several fit: name them and ask once. None fit: ask once for the street, then file with a hold and tell the team. Never "I can't find that" twice, never a guess.

Geography (nearby streets, neighborhoods, landmarks) plugs in as a name-book source, not a fourth layer. Maintenance and other modules call the same function later.

Decisions for Fede (options, with a recommendation)

#QuestionOptionsRecommendation
1Several homes fit the wordsa) ask once with the list · b) best guess (today, after the call) · c) front doora. The 4 wrong homes in the run all came from b.
2Names Clara learns from a missa) active on arrival (your Oct 28 Pick A) · b) a person confirms first (Gera's ADR-0147)a, guarded by uniqueness. b is why "2858 C 1/2 Rd" sat unconfirmed twice.
3A home held under two records (Ember's 27, Situs's 17 DU houses)a) the single-home record is the home, the community is a marketing parent · b) the building's unit wins (ADR-0147)a. The PMS setup is the customer's call; the resolver must accept either name and never pick a different home.
4Past names after a rename in AppFolioa) kept automatically as other names · b) typed by staffa. Nobody typed any at two customers.
5Where a miss endsa) hold with one question and a team note · b) silent front door (today) · c) dropa. 126 conversations sat on the front door in October, none moved.
6A model in the loopa) none, rules only · b) model only as the tie-break for "several" or "none" · c) model decidesb. Rules get 132 with zero wrong homes; the model on the undecided 40 adds 7 to 8 more, still zero wrong. Build P1 first, add the tie-break as its own PR.
Evidence levels and caveats
  • Measured on real data: the harness run; the resolver and normalizer counts (joined on function definition, file:line in the record); the Situs and Western Slope property and guest-card dumps.
  • Read from docs or dumps, not live: Western Slope's two learned names (the handoff's read of the building-names store, Oct 29); the Sep 7 and 14 AppFolio exports for Ember Estates.
  • Search negatives: "the sync never writes other names" rests on searching src, agents, scripts, lambda and infra; the one writer found is a manual import script.
  • Harness limits: each channel driver is narrower than production (Situs voice runs on names only, no listing snapshot); 9 "should ask" fixtures pass when nothing happens; Camellia names were not tested against a JP&Co roster.
  • Subagent review steps were rate-limited twice; those files were spot-checked by hand, not re-reviewed.
  • History: about 200 PRs in eight weeks touched this logic; the GitHub search capped at 400 results, so pre-September work is undercounted.
Record: inventories, data audit, transcripts, harness

All files are in session 003's scratchpad, folder amberlane/: consolidated.md (33 matchers, 31 composers, 145 call sites, 21 normalizers, keys unused, misses unrecorded), inventory/voice.md, inventory/text-and-guest-card.md, inventory/email.md, inventory/data-sync-staff.md, inventory/geo-spoken-home.md, alias-architecture.md, history.md (timeline, 22 incidents, 14 rulings), data-audit.md (75 caller phrases), situs-transcripts.md (8 calls, 81 passages), transcript.md (Western Slope Ember call), our-side.md (Ember in AppFolio vs our record), smith/handoff.txt.

Prototypes: scripts/home-identity-harness/prototypes/, results in results/prototypes-2026-10-29.md, local commit only. Harness: local branch fede/home-matching-harness, scripts/home-identity-harness/channels/, runner npm run test:harness:home-matching, results in results/before-2026-10-29.md, mutation control in results/mutation-control-2026-10-29.md. Not pushed, no PR.

Data facts worth keeping: Situs 53 properties / 442 units, Western Slope 90 / 254, saved other names in use 0 / 0 (2 learned, unconfirmed, at Western Slope); 19 live Situs AppFolio properties and 13 Western Slope ones are missing from our records (Fox Street Apartments is one renters ask about); guest cards name the home in 168 distinct ways at Situs (27 not an exact match) and 182 at Western Slope (60 not); 83 of 90 Western Slope property names are just the address. Zillow still advertises Ember Estates as "2858 C 1/2 Rd"; Clara learned it twice and nobody confirmed it.

What the customers said (verbatim, Eileen, Sep 29): "we call it Aspenleaf colloquially… they'll either say IH Holdings 22 or Aspenleaf, or they'll say 60-90 Wadsworth." "At Bryant Gardens there's 4 buildings with 4 separate addresses." "someone could call you and say, I'm calling from the Elevate property… that's only the 85 building at Bryant Gardens." Western Slope, Oct 28: "it's also caused a lot of confusion for Clara, reading our AppFolio."

PropFlow Docs