Why two Western Slope callers got no guest card

Two shared-line callers named a home community; neither got a card.

Findings — read-only investigation; 30-day sweep pending · Western Slope

On this page

  1. The answer
  2. Where each call diverged
  3. The mistake
  4. How many more
  5. Resolver vs the 10,000-unit bar
  6. What is being built
  7. Details: architecture, PR history, proofs, evidence

The answer

Both callers named a community, never a full address. The matcher found several homes that fit and, by design, picked none — but the card-writer only reads the ONE home already picked, never the candidate list, so nothing was filed. Silently: the email alert for this was removed. The matcher also skips AppFolio's own records, checking only current listings. Nothing here is switched off.

Where each call diverged

CallerSaidResolver returnedCard?
Jason Peshko"Ember Estates"3 candidates, no primaryNo
Ricky Kale"Amber/Ember Lane," no number2 candidates (resolver, not spoken), no primaryNo

Full transcripts, ids and code trace: Details below.

The mistake

  1. Design gap: a multi-home community was modeled as "list candidates, never pick one"; still an open Fede decision.
  2. Card-writer can't read the candidate list — "several matches" looks like "named nothing."
  3. Reference list is only current listings, never AppFolio's own records — some homes can never match.
  4. 22 September's fixes proved the wrong case correct — a test asserts "no card" is the right result.
  5. The email alert for this was removed — now a silent log line only.
Full detail, including the AppFolio property-record correction
  1. Design gap. A community or street that covers several homes was modeled from the start as "list the candidates, never pick one." The design page for this exact incident left the underlying question open: "when a lead comes in on the shared line and Clara can't tell which building they mean, should we keep quietly not creating a card… or start saving a visible record instead?" — still marked "Fede still deciding" as of the design doc. Confirmed.
    Correction to an earlier read of the data: "Ember Estates" IS a real AppFolio property — appfolio-399, "Ember Estates HZ," with 27 unit rows (361–374 Ember Ln, 2860A–2868B Florida St; verified live, 27 UNIT# rows under PROP#appfolio-399). Seven of those same homes ALSO exist as separate single-family properties, appfolio-405..411; 363 and 364 Ember Ln exist ONLY as units under 399, with no separate single-family property row at all. The matcher never reads either AppFolio property record — it only reads the scraped public-listings feed, which knows about neither the community property nor its units.
  2. The card-writer was never taught to read the candidate list. The step that files the AppFolio card checks four things, in order: the booked tour, the lead's property, the conversation's property, and one last-resort match on a single saved address. It was never given the "several homes could match" list (homesOfInterest/candidates) as a fifth option, so a caller who named a community correctly and got several real candidates back is treated exactly like a caller who named nothing at all. Confirmed by code.
  3. The reference list is only what's currently for rent, not AppFolio's own records. The matcher compares a caller's words against a scraped feed of 18 currently-offered listings — never against AppFolio's property or unit tables. Two of the real Ember Lane homes (361 and 362) have no listing row at all right now and could never match, no matter how precisely a caller named them. Confirmed live against production data.
  4. The 22 September fixes were proven on the wrong shape of case — and one of them proved the wrong outcome was correct. The six PRs from that day proved their fixes against one exact street address on a synthetic test bench (146 Quillwood Lane, a fictional "Fairhaven" test company): #10881, #10783 and #10805 all reproduced and fixed single-exact-address calls there. #10755's own test suite goes further — it explicitly asserts that when a call names a community with several matches, the system should stamp nothing, and treats that no-card outcome as the correct, passing result. In other words, the exact case in this RCA (a community name, several real candidates) was tested and its "no card" result was signed off as working as intended, not caught as a gap. Confirmed by the PR bodies and test coverage. (inferred: no one on the 22 September work re-examined that assertion against "several matches, zero cards, forever" as a product-level miss.)
  5. The refusal used to alert someone, then that alert was removed. PR #10903 (2026-09-22) added a team email whenever a call ended in no-pms-property. PR #11361 (2026-09-23, titled around reducing noise) removed that email. Today a call that resolves to several homes or none produces only a log line ("uncarded lead recorded silently… by product decision") — no outbox row, nothing queued, nothing that retries or pages anyone. This is a contributing cause, not the root cause: even if the matching gap above didn't exist, this pattern of calls would now fail with zero visibility. It also conflicts with Fede's 2026-09-24 ruling that a refusal to act is an engineering alert, never a silent one.

How many more

Full 12-row table and the log-coverage caveat: Details below.

30-day sweep, full table

Window: 2026-08-26 to 2026-09-25, all 62 inbound Western Slope voice calls. Runtime logs only start 2026-09-23T18:08Z, so 58 of these 62 calls have no log coverage at all — "no log found" below means no log exists to check, not that nothing happened.

Date (MDT)CallerWhat they saidWhat got stampedCard?
09-18 08:13 AMUnknown caller"Pomona Park Townhomes"Nothing — despite a clean single-property matchNo
09-18 10:32 AMStephanie"Pomona Park townhomes"Resolved to appfolio-392Yes
09-18 01:05 PMKaren G."Ember Estates" → asked for 367 Ember LaneResolved on her own inquiry (appfolio-408), but zero writes came from her call; her card later came from a separate Zillow inquiry that absorbed hersNo (from her call)
09-21 01:24 PMOfficer Barrett (not a prospect)An address, not a leasing askNo inquiry created — non-leasing calln/a
09-21 01:48 PMJason P."Book a showing for 367 Ember Lane" — his only exact-address ask; his two earlier 09-21 calls named nothing (asked for a live agent, transfers rang out)Pre-fix code stamped the raw shell "western-slope-front-door-367 Ember Lane" on inquiry 8198eb19; never re-resolved by the 09-22 fixesNo
09-22 08:07 AMKaitlin N.Nothing — 6-second call, dropped after "Leasing."Nothing stamped, correctlyn/a
09-22 12:04 PMUnknown caller"Ember Estates" (also said other, unrelated names)2 candidates, correctly no primaryNo
09-22 12:29 PMDylan L."566 Placer Street" (key pickup)Resolved to an existing cardExisting card, notes only
09-23 09:40 AMBrody R. (existing tenant)Billing dispute, mentioned "Pomona Park"No inquiry created — non-leasing calln/a
09-24 10:43 AMChloeMarket-research question, mentioned "Pomona Park"No inquiry created — non-leasing calln/a
09-24 05:28 PMJason Peshko"Ember Estates," no number this timeHit the several-candidates branch (3 candidates, no primary); the candidates don't include 367 Ember Lane, the address he'd named on 09-21 and which still sits unresolved as a raw shell on this same inquiryNo
09-24 05:48 PMRicky Kale"Amber/Ember Lane," no number spoken2 candidates, correctly no primaryNo

Resolver vs the 10,000-unit bar

"Imagine we're scaling to 10,000 units. And there's nuance on the names, Ember Estates or Ember Lane, that should all match the same." — Fede. Today: exact addresses always resolve; a community or bare street correctly returns several candidates rather than guessing; but the reference data is incomplete, a garbled name resolves to nothing, and the same street spelled two ways ("Ember Lane" vs "Ember Ln") in the source data can silently split a community's own homes into found and missed.

Full comparison table
CheckWhat it does today
Reference data comparedOnly currently-offered listings (18 of 70 onboarded WS properties) — not the full portfolio, not AppFolio's own property/unit tables.
Exact addressResolves cleanly to one property (e.g. "367 Ember Lane" → exactly one home).
Community name ("Ember Estates")Deterministic, code-only match against marketing text. Correctly returns several candidates, never guesses one. Capped at 3 candidates (slice(0,3)).
Street only ("Ember Lane")Same deterministic path, narrows to the homes on that street, still several — never guesses one.
Zero vs several matchesBoth cases stop short of picking a primary home. A "several" case and a "zero" case both leave the lead with no primary home, so the card-writer treats them identically.
Speech garble ("Ember States"/"Amber Lane")No fuzzy or sound-alike tolerance anywhere in the deterministic matcher — a garble that doesn't survive basic text normalization matches nothing. (Kale's case didn't even reach this: he said "Amber Lane" but the model transcription step already normalized it to "Ember Lane" before the matcher ran, so the matcher itself wasn't tested by this case.)
Spelling of the same street, two waysThe exact-address tier normalizes street suffixes (ln→lane), but the looser containment tier used for a street-only mention does not. Probed live: "Ember Lane" found 367 and 372 (listed as "Ember Lane") but missed 363 and 364 (listed as "Ember Ln") — same street, inconsistent suffix spelling in the source data, no normalization on that path. (inferred: the exact code line for the unnormalized containment check.)
Model vs deterministicOnly the first step — pulling out the words the caller used — is model-guessed. Everything after that (matching those words to a real home) is plain, deterministic code, with comments suggesting the rules don't change at higher unit counts. (inferred: not actually tested at 10,000-unit scale.)

What is being built

No fix is proposed on this page. The design for how Clara should handle a community/street with several matching homes is being written up on the leasing engine designs page.

Details

Architecture as built — step by step, with code citations

1. Entry point — transcript read and home extraction

Two callers converge on one extractor, in src/lib/integrations/voice/postcall-prospect-capture.ts:

  • New-lead path: maybeCreateProspectFromTranscript (postcall-prospect-capture.ts:177-325), called from src/app/api/voice/call-ended/route.ts:2384 when no existing lead was found.
  • Repeat-caller path: stampNamedHomeForExistingProspect (postcall-prospect-capture.ts:670-722), called from route.ts:2393 — added by #10805 so a caller who already has a lead also gets extraction run.
  • Both call one shared extractProspectFromTranscript (postcall-prospect-capture.ts:121-175) against the caller+Clara transcript. Model: FAST_MODEL, forced tool call extract_prospect whose schema carries the homeText field (added by #10755) — "the community, street, or full address the CALLER named," preferring the more specific reference.

2. The matcher

homeText is resolved via resolveOrgHomeForLine (org-home-booking.ts:369-392) — the same seam schedule_tour uses (#9532).

  • Fields compared: exact propertyId first (matchOrgHomeByPropertyId, org-home-booking.ts:158-162), then address/alias tiers (resolveListingTarget/pickOrgHome, org-home-booking.ts:232-264), then (added 2026-09-23) homesQuotedInCall, which requires the whole spoken address to appear in the transcript (org-home-booking.ts:184-220).
  • Normalization: homeKey lowercases, strips punctuation, maps street-suffix abbreviations (appfolio-public-listings.ts:110-125).
  • A community name mapping to several candidates in the listings feed (e.g. "Ember Estates" → homes on Ember Lane/Florida St, matched against listing rows, capped at 3 via slice(0,3)): pickOrgHome returns { home: null, candidates, candidateHomes } (org-home-booking.ts:256-264). The capture module never guesses — it writes one homesOfInterest entry per candidate (postcall-prospect-capture.ts:510-524) and, only if aiNotes is still blank, a note listing the candidates (:536-546). No primary field is stamped in this branch. This is the exact branch #10755's own test suite asserts should produce no card — not a gap the fix wave caught.

3. What gets stamped on success

Inside stampNamedHomeFromTranscript (postcall-prospect-capture.ts:428-584):

  • Primary fields (targetUnitId/targetHomeAddress/targetListingId) — fill-if-blank-or-unresolved only, via deriveInquiryHomePatchIfUnresolved (inquiry-home-patch.ts:85-93) → written with updateInquiryFieldsForProspect (:489-493). Never overwrites a booking that already resolves to an onboarded property.
  • homesOfInterest — append-always via mergeHomesOfInterest (homes-of-interest.ts:78-118), one entry per resolved home / candidate / unresolved raw text; capped at 10, oldest dropped.
  • propertyId is never re-pointed off the org front door (western-slope-front-door). By design, only targetHomeAddress/targetListingId/targetUnitId on the inquiry carry the resolved home (org-home-pms-property.ts:6-12, postcall-guest-card-outbox.ts:48-56).

Guest-card outbox writer requirement (postcall-guest-card-outbox.ts): candidate order is tour → inquiry.propertyId → conversation.propertyId → last-resort targetHomeAddress match (:301-356). resolveIntentPropertyId (:203-210) keeps the first candidate with a real PMS writer. If none of the candidates has one — e.g. every candidate is the front-door shell — it returns { enqueued: false, reason: 'no-pms-property', candidates } and logs a warning, deliberately never enqueuing, never retrying (:358-367, design note at :60-66):

logWarn('GuestCardOutbox',
  `no intent appended for inquiry ${prospect.id}: none of [${candidates.join(', ')}] is a ` +
  'property with a PMS connection — a front-door line is not a building, and there is ' +
  'no home to file the card against. Never enqueued, so the drain never retries it.');
return { enqueued: false, reason: 'no-pms-property', candidates };

So the AppFolio card write depends entirely on targetHomeAddress (or a resolved tour/inquiry propertyId) resolving to an onboarded PMS property — the several-candidates list is never consulted by the writer.

Alerting history on this exact skip: PR #10903 (2026-09-22) added a team email fired on no-pms-property. PR #11361 (2026-09-23, framed around cutting alert noise) removed that email. Today the skip produces only a log line ("uncarded lead recorded silently… by product decision") — no outbox row, no retry, no page. This conflicts with Fede's 2026-09-24 ruling that a refusal to act is an engineering alert, never silent.

4. Replay / bench tooling

  • src/lib/maintenance/eval/robot-call-scenarios.ts — three robot-bench-* scenarios added by #10757 against the Fairhaven synthetic many-homes test bench (+17208071724, property fairhaven-homes), explicitly marked "not executed by the PR that added this scenario."
  • evals/fast-tier/postcall-prospect-capture/ — prompt/model regression harness; extract-prod.py pulls the most-recent real conversations globally, no org or date-range filter (not a 30-day sweep).
  • scripts/harvest-conversations.ts — the actual 30-day-style sweep tool (--days, --property-id, --channel voice), feeding evals/replay/run-replay.ts. This is the mechanism available for the pending sweep, not lane-specific to this bug.
PR history — the 22 September fix wave
PRMergedWhat changedProven on
#91052026-09-18Guest cards from calls: write-intent outbox + AppFolio writer, dark, org switch off.Willows-style dark ship; design doc
#91552026-09-17Write one AppFolio guest card when a call ends (property-level setting, default off).Not WS-shaped; generic property setting
#94902026-09-18Guest-card intent files against the discussed home, never the front-door row.Real WS prod data: "Pomona Park Townhomes, 624 Eisenhauer Street," intent parked 3/3 attempts against western-slope-front-door
#95792026-09-19A booked company home carries its real onboarded property, not the front-door shell.Real WS call ("Karen Green," 367 Ember Lane)
#97452026-09-19One writer per call — outbox owns the org.Willows (appfolio-45)
#107552026-09-22 14:51Extract the home the caller named and stamp it on the lead so shared-line calls get a card. Cites the WS Ember Estates incident directly.WS-shaped incident cited by name; fix built generically
#107572026-09-22 15:31Shared-line replay scenarios for the WS guest-card misses.Fairhaven synthetic test bench, not real WS addresses
#107832026-09-22 16:46A stale bare home address no longer blocks the guest card; loose bare-street matcher added.Fairhaven bench (synthetic)
#107962026-09-22 17:27A lead keeps the list of homes discussed (homesOfInterest), append-and-dedupe, capped at 10.Unit-test only; Ember Estates is the worked example in the design comment, not replayed live
#108052026-09-22 19:03A repeat caller who names a home gets it stamped too, not only a first-time caller.Real Fairhaven bench call; Ember Estates incident by reference
#108812026-09-22 20:27A raw home label no longer blocks stamping the home a repeat caller names.Reproduced live on two real Fairhaven bench calls
#109422026-09-23 00:20A home named on a repeat call is always added to the lead's list, even if a primary is already resolved.Real bench call, mutation control (red without the fix, green with it)
#109032026-09-22Adds a team email alert whenever a call ends with the no-pms-property skip.—
#113612026-09-23Removes that alert (framed around cutting alert noise); the skip now only produces a log line, nothing that pages or retries.—

No PR in this set replays a corpus of real WS AppFolio guest-card data end-to-end. The closest is #9490/#9579 (real WS production conversations, single calls, not a corpus).

Design-intent quotes (docs repo, western-slope-issue-list-2026-09-21.html)

  • The 09-21 design doc's original claim was: "'Ember Estates' is also not one property in AppFolio: it is seven single homes on Ember Lane and Florida Street plus an office record." This RCA corrects that claim — Ember Estates IS one AppFolio property (appfolio-399, 27 units); seven of its homes additionally exist as separate single-family properties. See the roster audit above for the verified figures.
  • "the writer only trusts four sources for which home the caller meant: the booked tour, the lead's property, the conversation's property, and the address the caller asked to tour" and "a conversation on the shared line is tied to the company placeholder at birth and, by design, is never re-pointed to another property."
  • Stated fix plan: "(1) Save the home on the lead the moment it is resolved on a call… (2) Clara must look the home up before quoting rent or specials when a community or address is named." Item (2) — the in-call lookup change — is not what #10755 built; that PR's own body says "the fix is NOT a prompt/tool-call change… It is a data-path fix."
  • Open decision, still unresolved as of the design doc: "when a lead comes in on the shared line and Clara can't tell which building they mean, should we keep quietly not creating a card… or start saving a visible record instead? — Fede still deciding." Multi-home option A (AppFolio-shaped, one inquiry row per home discussed) is "recommend," not yet a locked yes; homesOfInterest is the data half of option A, the "separate card entry" half is not built.
Tests and proofs as built
Test fileData shape exercised
src/__tests__/postcall-prospect-capture.test.ts39 hits for "Ember," 11 for "Fairhaven," 19 for "Quillwood," 7 for "appfolio-45" — mix of the literal WS incident name and synthetic fixtures
src/lib/domain/leasing/__tests__/inquiry-home-patch.test.tsPure-function unit cases, generic
src/lib/domain/leasing/__tests__/homes-of-interest.test.tsmergeHomesOfInterest unit tests: dedupe, cap-at-10, mutation control
src/lib/domain/leasing/__tests__/org-home-pms-property.test.tsLoose bare-street matcher unit tests
src/__tests__/guest-card-outbox-from-call.test.ts50 hits "appfolio-45" (Willows), some Ember
src/__tests__/api-routes-voice.test.ts50 "appfolio-45", 24 "Fairhaven," 26 "Quillwood," 17 "Willows," only 1 "Ember" — the bulk of the last three PRs' regression coverage is Fairhaven/Willows synthetic fixtures, not WS-shaped multi-single-family-under-one-community data

Fairhaven is confirmed synthetic, not real WS inventory: scripts/voice-harness/scenarios/knowledge-exception-fairhaven.yaml header states "TEST COMPANY: Fairhaven Residential (TEST)… None of the 7 addresses below is a real Fairhaven listing," used so robocalls can hit a real many-homes line without touching WS production data.

Resolver audit — in full

A. Roster fields compared

FieldSourceCompared howFile:line
idalways ''never compared — no Unit row backs a homeorg-home-booking.ts:55-57
number (full street address)OrgListing.addressexact / substring / whole-token containmentorg-home-booking.ts:58-59; tiers in listing-resolution.ts:340-378
key (listing externalId)OrgListing.externalIdnot text-compared; stamped on matchorg-home-booking.ts:60-70
aliasTextlisting.title + listing.descriptionname/marketing tier only, last resort, requires a 2+ word Title-Case proper-noun phraseorg-home-booking.ts:87-97; matcher listing-resolution.ts:363-378, :302-309
propertyIdroster row's internal property id, when PMS-joinedexact-equality firstorg-home-booking.ts:109-119, :158-162

An AppFolio property NAME field does not exist as a discrete roster field — confirmed live: PROP#appfolio-405..411 (name) all equal the street address itself (e.g. "374 Ember Lane"), no communityName/marketing field anywhere on those single-family property rows. "Ember Estates" only lives in listing prose (aliasText). A street-only mention ("Ember Lane") is compared, but only via containment against number, never aliasText.

Correction to an earlier read of this data: "Ember Estates" IS a real AppFolio property, appfolio-399 ("Ember Estates HZ"), carrying 27 unit rows (361–374 Ember Ln, 2860A–2868B Florida St — verified live, 27 UNIT# rows under PROP#appfolio-399). Seven of those homes also exist as separate single-family properties, appfolio-405..411; 363 and 364 Ember Ln exist only as units under 399, with no separate property row. The matcher never queries either the AppFolio property table or the unit table — the roster it actually reads is a separately-scraped public-listings feed that knows about neither.

Roster is that listings feed (getOrgOfferableHomes → listOrgListings/offeredOrgListings), i.e. only currently-offered homes — not AppFolio's own property/unit records. Confirmed live: WS org (org_c42d9150…) has 70 onboarded property rows but only 18 OrgListing rows total, of which only 4 are offered:true on the Ember cluster (364/367/372/363 Ember Ln); 374 Ember Lane is delisted; single-family properties appfolio-409 (362 Ember Lane) and appfolio-410 (361 Ember Lane) have no listing row at all and would never appear in the roster.

B. Tolerance

  • Exact normalization: homeKey lowercases, strips punctuation, maps street-suffix abbreviations (appfolio-public-listings.ts:110-125).
  • Fuzzy/partial: address substring + whole-token containment (containsTokens, listing-resolution.ts:386-394); short tokens only count behind a unit designator. This containment tier does not run street-suffix normalization the way the exact-address tier does: probed live, "Ember Lane" matched 367/372 Ember Lane but missed 363/364 Ember Ln, purely because of how the address is spelled in the listings feed. (inferred: exact code line for the unnormalized path.)
  • Community-name matching requires a capitalized, Title-Case 2+ word phrase in listing prose, and returns at most 3 candidates (slice(0,3)) — a community with more than 3 live listings drops the rest silently.
  • Speech garble ("Ember States"): no tolerance at all — straight string/token match, no edit-distance or phonetic layer anywhere in this path. Probed: 0 candidates.
  • Model-based half: only the homeText extraction is model-guessed (FAST_MODEL via extractProspectFromTranscript, postcall-prospect-capture.ts:121-165). Everything downstream is deterministic, pure code — no LLM in the matcher itself.

C. Zero vs several matches

  • Several (e.g. Ember Estates → 3 homes): pickOrgHome returns { home: null, candidates, candidateHomes } (org-home-booking.ts:256-264); capture writes one homesOfInterest entry per candidate, never a primary.
  • Zero (e.g. "Ember States" garbled): also {home:null, candidates:[]}; capture writes ONE homesOfInterest entry with the raw homeText, no propertyId. Thread tag only fires when a propertyId resolved, so zero/several never get tagged — the two failure modes are indistinguishable downstream.

D. Live WS data trace

Real rows: appfolio-405..411 = 374/2863(406)/372/367/362/361 Ember or Florida. Org org_c42d9150… has 70 onboarded properties total but only 18 listings, 4 offered on the Ember cluster. Offline probe (resolver-probe.ts, run via pickOrgHome imported live, no DB writes):

QueryResult
"Ember Estates"3 candidates: 364, 367, 372 Ember Ln/Lane (name-tier match on aliasText)
"Ember Lane"2 candidates: 367, 372 Ember Lane (address-containment on suffix-normalized "ember lane")
"Ember States" (garble)0 candidates — no fuzzy tolerance, resolves to nothing
"367 Ember Lane"ONE HOME: 367 Ember Lane, propertyId=appfolio-408 (exact address match)

Note on the "10,000 units" framing: production WS scale today is 70 onboarded properties / 18 listings. The code comments (listing-resolution.ts header) treat the matching rules as scale-invariant (exact-first, then narrow containment, then a proper-noun-gated name tier), so nothing in the algorithm itself is expected to change behavior at higher unit counts — but this was not tested at 10,000-unit scale (inferred).

Evidence ids

Jason Peshko

  • Person pers_81064e43-e6cb-4bf5-ab4b-8a12262f120d — the same person as the 2026-09-21 Ember Estates calls the six 22 September PRs were built for; he called back on 24 September and failed the same way, on the same inquiry.
  • Inquiry 8198eb19-c020-45fb-8b08-102be80eb147, conversation (09-24 call) conv_voice_73d01668-9683-4295-8f16-7dbc5011ec14, org org_c42d9150-b9ad-46f8-8f5f-b0fe56bacf38 (Western Slope), bound propertyId = western-slope-front-door.
  • He named "367 Ember Lane" only once, on his 09-21 19:48Z call ("book a showing for 367 Ember Lane"). The pre-fix code stamped it as the raw shell "western-slope-front-door-367 Ember Lane" on this same inquiry, and it was never re-resolved after the 09-22 fixes shipped. His two earlier 09-21 calls named nothing — he asked for a live agent and the transfers rang out. On his 09-24 call he said only "Ember Estates," no number, and hit the several-candidates branch fresh.
  • homesOfInterest (from the 09-24 call): 2863 Florida St, 363 Ember Ln, 364 Ember Ln (all Grand Junction, CO 81501) — none of these is 367 Ember Lane, the address still sitting unresolved as a raw shell on this inquiry.
  • Transcript (09-24): caller: "Yes, Ember Estates." → "Where are they located?" → Clara: "The Ember Estates homes are on Ember Lane in Grand Junction — there are a few addresses along that street." Never narrowed to one.
  • aiNotes (09-24 call): "Jason Peshko is interested in three-bedroom, two-bath homes at Ember Estates and requested a showing for 367 Ember Lane… transfer attempts were unsuccessful." — this note is pulling in his 09-21 ask; he did not repeat the address on this call.

Ricky Kale

  • Person pers_6caf599e-3bb7-4348-a16a-ed115c961b13, inquiry ba42fd03-f391-46b5-9d97-bd4cc9c8b422, conversation conv_voice_ae06db35-4eff-468c-bcdb-f40681d5a709, same org/propertyId.
  • No street number was spoken by Kale on this call. The 367/372 Ember Lane entries in homesOfInterest came from the post-call summary step's own resolver candidates — produced by the matcher when it ran "Ember Lane" against the roster — not from anything Kale said himself.
  • Transcript: caller: "The new houses for lease on Amber Lane." → Clara: "Got it — the homes on Ember Lane!" → never narrowed to one; quoted price range only. Call ended with a transfer to an agent, not a booking.
  • aiNotes: "Ricky Kale called asking about homes for lease on Ember Lane… $2,750 to $2,825 a month with a grand opening special…"
  • targetUnitId is blank (""); Peshko's is the malformed string "western-slope-front-door-367 Ember Lane" — not a real Unit.id shape.

Shared

  • Found via phone-index GSI query GSI1PK=PROPERTY#western-slope-front-door, GSI1SK begins_with INQUIRY# (16 front-door inquiries total, matched by name off the person profile rows).
  • Outbox skip reason, verbatim: logWarn('GuestCardOutbox', 'no intent appended for inquiry <id>: none of [<candidates>] is a property with a PMS connection — a front-door line is not a building, and there is no home to file the card against. Never enqueued, so the drain never retries it.') → { enqueued: false, reason: 'no-pms-property', candidates }. Confirmed no write-intent row exists for either inquiry (queried phone-index GSI GSI1PK=PMS_WRITE_INTENT_INQUIRY#<inquiryId>, 0 items each).
  • Switch row: org-level CONFIG / GUEST_CARD_WRITE_FROM_CALLS#org_c42d9150-b9ad-46f8-8f5f-b0fe56bacf38 → enabled: true, armed by Fede 2026-09-18. Not gated off — the skip happens purely on the "no PMS-mapped candidate" path.
  • CloudWatch: searched /propflow/vercel/runtime and /aws/lambda/propflow-agent-runtime-prod by both inquiry and conversation ids, window 20:00–02:00 UTC 9/24–9/25 — 0 matching events in either group (the warning line likely lands in a different sink; could not verify it reached CloudWatch specifically).
PropFlow Docs