Vendor Interactions — Architecture Review

2026-08-12 · Fede + Fable (orchestrator) · evidence: 2,581 labeled Camellia emails (2018→today), 60+ bench voice calls, turnover-outbound retros

ACCEPTED — Fede, 2026-08-12 v2 — 10,000-foot review

Thesis

Vendor identity is the foundation for every vendor interaction we will ever do — inbound scheduling today, outbound turnover coordination tomorrow, PO exchange, quotes, chases. We have now watched the same failure on both directions of traffic: comprehension is fine, recognition is broken. Inbound, the pipeline read a carpet-cleaning schedule perfectly three times and dropped it three times because the sender's address wasn't in a table. Outbound, turnover vendor-calling had to be pulled back behind human approval largely because identity flakiness was frustrating people — real vendors greeted as strangers, confirmed bookings voided over a transcription of a surname, a vendor record that turned out to contain our own phone number.

Legend for what follows: FEDE direction from Fede · DATA measured on the labeled corpus / documented incidents · FABLE my recommendation, argued, disagreeable.

1 · The landscape: what vendors actually send us

All counts measured on the golden set: 2,581 inbound Camellia emails matching vendor/scheduling vocabulary, 2018→2026, QA-passed labels. 289 are genuine vendor-scheduling emails; 251 should have produced a calendar action. 112 distinct vendor companies wrote in.

1.1 Two very different species of scheduling email DATA

149 of 289 are templated scheduler-system emails — but 127 of those are a single vendor (Miracle Method's "What to Expect — Unit 403 — PO #693" family, with unit, PO and a 3-day window in the subject line). Strip that one vendor and the world is 88% free-text human email: the cleaning company owner writing "we are scheduled to start tomorrow Thursday 8/13 & Friday 8/14, 8 a.m., 6th floor," the painter whose subject line is just his company name, the fire-protection dispatcher offering "next available tech 9:30am Friday" without a date. Elevator and glass companies sit in between — portal confirmations plus a human "our tech is en route" on top.

Consequence: a template parser is the right tool for exactly one lane per vendor system; the general case is judgment over prose.

1.2 Sender addresses are not a usable vendor key DATA

Among repeat vendors, 54% wrote from two or more addresses; 31% from two or more domains. Only 3 emails in eight years ever announced an address change. The elevator company used ten addresses across two corporate domains (they rebranded) plus a billing platform; the utility-billing vendor used eight across three; the law firm sends from its own domain and a Zendesk sender; the cleaning company moved from AOL to a company domain mid-relationship. Among vendor mail: 653 company-domain personal addresses, 86 shared dispatch/role mailboxes, 48 freemail (AOL/Gmail — over-represented among small trades that actually schedule), 19 no-reply senders.

Consequence: any design keyed on "the address on file" is structurally wrong, not just under-populated. Addresses are evidence, never keys.

1.3 Company names drift too DATA

49 distinct stated-name vs roster-name divergences: ThyssenKrupp → TK Elevator (renamed 2020, 57 emails), Anchor Pest Control → "Complete Pest & Wildlife Services dba Anchor," Abbotts Fire & Flood → Abbotts Cleanup and Restoration (no shared words), Alpine Glass → Alpine Glass Acquisition LLC, the law firm adding a third partner name. All were confidently resolvable by a human reading context. One was a genuine trap: "Noble Electric" fuzzy-matched to "Noble Energy Conservation" — different companies, different trades. And 12 scheduling emails came from businesses on no roster at all (laundry-machine servicer, parking operator, Google Fiber install).

Consequence: name matching must be judgment-with-evidence (trade, history, context), not string distance alone — string distance both misses real renames and invents false ones.

1.4 The traps outnumber the targets ~10:1 DATA FEDE

Fede's instinct — "filter marketing/spam; only schedule jobs for vendors we're actually working with" — is what the data screams. Against 251 real calendar actions stand 2,330 no-booking emails, many engineered by reality to look bookable:

Consequence: precision is the binding constraint, not recall. The gate that does the heavy lifting isn't "is this a vendor?" but "is this an active working relationship talking about agreed work?" — recent thread history, open jobs/POs with that company, a visit being committed rather than discussed. That gate is a first-class stage in the architecture below.

1.5 Scheduling language assumes shared context DATA

Of 266 emails with extractable schedules: only 50 state an explicit time window; 126 say a bare weekday ("crew will be there Thursday"), 82 say "today/tomorrow," 39 more use relative phrasing ("week of Nov 24, business hours"). 141 are multi-day jobs. 43% of scheduling emails are replies on threads the office started — and those omit property, scope, and system because the office already said it. Reschedules are starkest: of 22, only 2 restate the original date; 16 reference it purely by riding the same thread (one painter's Friday→Monday move lives on a thread titled "RE: phone number?").

Consequence: a per-message system cannot even reschedule — it can only double-book. Processing must be conversation-level: the model reads the thread, not the message.

2 · What broke last time: the outbound record DATA

The turnover workstream built full outbound vendor coordination — voice calling with a PM-approval queue and autonomous redials (live today on the test line; ~60 bench calls, never a real vendor), and email dispatch (built, but hard-redirected to a test mailbox since 7/23; auto-dispatch of turnover work stopped 8/4 — everything now waits for a PM). It never rolled out to real vendors, and the biggest single reason was identity. The incident log, verbatim from the retros:

Sorting the post-mortems: the failures that frustrated people trace overwhelmingly to (a) a nearly-empty contact store (78 of ~814 vendors with a phone, 27 with an email, zero learning — a contact that misses once misses forever), (b) binary exact-match recognition with no confidence tiers, and (c) duplicated matchers with inverted safety postures. Latency, IVR turn-taking, and process gaps were real but separable. Fixing identity once, as shared infrastructure, is the prerequisite for ever re-arming outbound — which is why this review treats inbound scheduling as wave one of a foundation, not a feature.

3 · Target architecture

3.1 The flow

email voice voicemail SMS (future) VENDOR RECOGNITION — one service, all channels evidence weighed together, like a human: • stored contact points (phone / email / domain) • provenance (our thread? our dial?) • stated identity (signature / spoken name) • relationship context (open jobs, POs, history) → vendor company + confidence tier + evidence record CONTACT GRAPH (learned) contact points on the VendorCompany, per client org: phones · emails · domains, each with provenance + confidence read WORKING-RELATIONSHIP GATE — precision backbone (traps ≈ 10× targets) active engagement with this vendor? committed visit — not a pitch, marketing, an invoice, or an out-of-office? no normal triage yes CONVERSATION-LEVEL EXTRACTION reads the thread + prior calendar events, not one message: resolves "tomorrow" and bare weekdays, tells a reschedule-of-existing from a new visit book / update / cancel calendar already shipped, channel-agnostic LEARNING LOOP confident match ⇒ save contact point write FUTURE, same foundation: outbound turnover dispatch · PO exchange · quote chases email-first, human approves exact content before send; voice re-arms after inbound proves out

3.2 The data model

CLIENT ORG BOUNDARY (e.g. JP & Co) — nothing learned crosses this line, ever VendorCompany the business: name, trade mirror of the client's own PMS vendor card (828 on the Camellia roster) VendorContactPoint ×N ← NEW phone · email · domain (freemail-guarded) per contact: provenance (PMS sync, inbound email/call, outbound reply, manual) · confidence · first/last seen · observed→confirmed many per company; dispatch@ may map to N companies belongs to VendorMembership role: owner / dispatcher / tech · properties covered Person only humans we actually know ("Sylvia at Metro") optional: contact point ↔ known human What stays on the Person spine (unchanged) tenants & prospects · identity claims with the one-identifier-one-human rule · consent / TCPA records never merged or minted by inference (2026-08-09 ruling) business mailboxes and tech cells no longer forced through this model — that mismatch caused §2

The pieces, and who says so

PieceWhat / whyProvenance
Company-centric contact graphNew VendorContactPoint rows (phone / email / domain, with freemail guard) hanging off VendorCompany — many-to-many, provenance + confidence per contact, optional link to a known human. Deliberately NOT Person-spine claims: the spine's one-identifier-one-human rule is right for tenants and structurally wrong for dispatch mailboxes and dozens of techs.FEDE FABLE concur; §1.2 shows even this is only evidence, never a key
One recognition service, judgment-basedReplaces today's four scattered matchers (email claim walk, three voice rungs, two name matchers). Evidence weighed together by a modern model — "reply on our thread, signed Metropolitan Building Maintenance, domain metrobm.com, about the carpet job we requested" resolves the way a human resolves it. Kills the Shabba/Chapa class: one noisy string can no longer outvote the rest of the evidence.FEDE ("common sense as a human would") + DATA §2 (duplicated matchers)
Working-relationship gateBookings require an active engagement: recent thread, open job/PO, or established history — and a committed visit, not an availability pitch. This, not identity alone, is what beats the 10:1 trap ratio.FEDE (filter marketing; only vendors we work with) + DATA §1.4
Conversation-level processingThe classifier/extractor sees the thread and prior calendar events, not a lone truncated body. Required for replies (43% of scheduling), relative dates (§1.5), and any reschedule at all.FABLE — I consider this non-negotiable; per-message processing caused both the inbound drops and the audit's worst findings
Learning loopConfident resolutions write contact points with provenance; next contact from that address/number is instant. Reuses the shipped provenance pattern (observed → usable for recognition/calendar; confirmed → usable for outbound dispatch).FEDE; mechanics FABLE; Decision 1 sets aggressiveness
Start loose, tighten on evidenceWeak-evidence outcomes are calendar-only — a wrong match is one deletable event, a missed visit is a no-show a PM eats. Every automated write records its evidence, so abuse is detectable and tightening is data-driven.FEDE FABLE concur — with the §4 rails as the price

Where I'd push, beyond the settled direction FABLE

4 · Hard rails (what makes loose safe)

5 · Delivery: small PRs, fleet-built, replay-gated

Measurement is replay against history, not new prod telemetry (Fede): the golden set (251 must-book, 2,330 must-not) is the merge gate; the subscription replay harness scores every PR against it. Current prod baseline: effectively 0 of 251 caught — the recognition dictionary is empty.

WaveShipsStatus
1 · SafetyOut-of-office guard before the vendor lane + truthful "armed" comments on outbound callingMERGED (bot-approved, tested, 2026-08-12)
1b · HarnessGolden-set replay harness (recognition + extraction scoring, pluggable resolvers)
2 · Thread provenanceReply-on-our-thread recognition + relationship gate v1next — alone catches the entire §1.5 reply class
3 · Stated identitySignature/display-name/domain judged against roster, conversation-level extractionafter 2 beats the harness
4 · Learning loopContact points written on confident resolutions (per Decision 1)after 3
5 · LaterVoice adopts the shared recognizer · vendor-scheduling category in the triage menu · PO answering via HITL email (Decision 3) · outbound turnover re-arm · onboarding mailbox mining (future, per Fede) · attachment readingnot in scope now

6 · Decisions — ALL SETTLED (Fede, verbally, 2026-08-12)

1 · Learning: store contacts automatically on confident match — no human review, no quarantine, no user-facing tiers (provenance kept internally).

2 · ADR-0097: carve-out accepted, scoped strictly to vendor contact points (implied by #1).

3 · Replies/PO: NO outbound of any kind until identity + calendar is working and baked in prod. First pass = recognition + calendar only.

4 · Seeding: YES — email from the last 2 years only + call history (small) + AppFolio extra phones + production backfill renaming ALL matching "Unknown Caller" records (label-only, no merges).

Original option cards kept below for the record:

1 · How aggressively does the system learn new vendor contacts?

2 · ADR-0097 says email signals never create entity records. Contact points conflict.

3 · Vendors ask us for POs (the carpet vendor did). Voice can answer; email can't. PO mode is on for zero real properties.

4 · Seed contact points from history before the learning loop starts?

Appendix · Corpus quick facts

FactNumber
Labeled emails / span2,581 · Feb 2018 → Aug 2026
Vendor-scheduling emails / calendar actions owed289 / 251 (231 book · 19 update · 1 cancel)
Distinct vendor companies writing in / roster match rate112 / 91%
Roster vendors with a stored email address0 of 828
Repeat vendors using 2+ sender addresses / 2+ domains54% / 31%
Trap:target ratio / low-confidence share of scheduling~10:1 / 17% (the realistic unattended-automation ceiling)
Scheduling emails that are replies on our threads43%
Reschedules that restate the original date2 of 22
One vendor's share of all scheduling volume45% (templated refinishing system)
PropFlow Docs