Situs Group — What the Records Show (2026)

What a read-only copy of their AppFolio database proves about how Situs operates, set against what Hugo, Noel and Eileen asked us for.

Findings — for the Situs onboarding · read-only AppFolio dump, 2026 activity only, multifamily apartments only · 2026-09-02 · CONFIDENTIAL — internal · companion to the Situs onboarding hub

Read this first

  1. Priority set on 0 of 708 phone and portal tickets; 100% of staff tickets. MEASURED
  2. After 5pm every intake channel takes 11–16 hours to reach a human. MEASURED
  3. 615 maintenance requests and 174 leads arrive yearly with the office closed. MEASURED
  4. Call-centre tickets repeat on the same unit within a week 30.4% of the time. MEASURED
  5. 34 leads a year get no human contact at all; 2.9% move in. MEASURED
  6. 15 of 33 cancelled applications died because the applicant stopped responding. MEASURED
  7. 41 renewals (37%) offered below current rent in 2026; Jan–Aug like-for-like 32.6% vs 2.7% in 2025. MEASURED
  8. 54 upcoming leases sit $206,736 a year below market rent. MEASURED
  9. 370 tenant-billback lines opened, every one $0.00; zero purchase orders. MEASURED
  10. The phone leaves no trace: 7 after-hours calls logged all year. MEASURED

MEASURED = counted directly. PARTIAL = a subset, stated. INFERRED = an estimate with its method.

Portfolio snapshot

This page measures Situs's multifamily apartments and nothing else: 397 doors across 16 properties. MEASURED

Scope. Every figure on this page is computed on the multifamily apartment portfolio only. A property counts as multifamily when it is not a "DO NOT USE" or migration placeholder, holds at least two units in AppFolio's unit directory, and is residential — at least one unit with a bedroom count. That is 16 properties and 397 doors. Excluded: 191 units of commercial (Chase Tower, Wells Fargo Building, IH21 Lux, Greeley Industrial, ICON Eyecare), 20 single-family houses (the 18 Denver-University-portfolio houses, 446 Galapago, the Ski House), 19 units in three "DO NOT USE" and migration placeholders, and 19 units of entity shells, holdings and land.

Asset classRecordsUnitsIn scope?
Multifamily apartments16397Yes — everything on this page
Commercial5191No
Single-family houses2020No
"DO NOT USE" / migration placeholders319No
Company shells, holdings and land1519No
Everything in the database59646

All MEASURED from AppFolio's own unit directory. Corrects two earlier figures: a 1,104-unit count that double-counted the report's total row, and a "345 residential apartments" count that came from the occupancy report — which treated a four-bedroom house on Galapago as an apartment and counted Alton as a single unit.

Detail — the 16 apartment properties, and what we can't see
PropertyDoorsOccupied%Vacant-rentedVacant-unrentedNotice
Alton Apartments55
Barcelona Apartments484287.5606
Lampliter413687.8415
Carr Street Flats342779.4702
Bryant Gardens3333100.0000
Lowry Flats262284.6403
Aspen Leaf242187.5305
Mckenzie241979.2503
Zephyr241986.4304
Cottonwoods222195.5101
Olde Town Terrace2020100.0002
Dahlia Apartments1212100.0001
Mayor Apartments121191.7102
Dexter Apartments111090.9100
6908 Lowell66100.0000
Arizona5480.0101
Total397304 of 341 covered89.1%35135

Doors come from the unit directory; occupancy from the occupancy report, which covers 341 of the 397. Alton is listed there as a single unit, so it carries no occupancy figure — a question for Eileen.

What we can't see: whether AppFolio's occupancy and days-vacant fields match reality. Eileen: she has walked into units marked vacant and found people living in them.

The phone line, nights and weekends

Priority was set on 0 of 401 call-centre and 0 of 307 resident-portal tickets, and 100% of staff tickets. MEASURED

2026 work ordersCall centrePortalStaffBots
Tickets opened401307694917
Arrived after hours or weekend36.2%46.6%14.1%33.8%
Priority set0.0%0.0%100%98.5%
Emergency wording, priority blank22.9% (92)22.6% (80)0.0%0.3%
Linked to a unit97.5%100%78.4%45.0%
Entry permission answered85.8%87.0%62.5%5.1%
Description length, median characters977641219197
Repeat on same unit within 7 days30.4%21.2%24.4%34.0%
Re-assigned more than once29.9%31.6%14.7%10.7%
Edited after creation19.2%11.0%5.9%5.2%
Median hours to an assignee1.01.014.217.9
Median days to finish2.63.47.28.1
Still open2.2%5.4%9.1%28.1%
Open, untouched 30+ days0.0%1.0%8.5%15.6%
Resident updated the ticket online2.2%10.7%0.3%0.3%

All MEASURED on 2,322 multifamily work orders. Duplicate detection is a heuristic: those two rows are upper bounds. Channels assigned by evidence — creator "Customer Service" = call centre; an online-submission event or a creator matching the unit's occupant = portal; a verified employee = staff; PM Assistant, System, Maintenance Performer and recurring templates = bots.

Interpretation (not measured)

Priority is a channel-permission gap rather than a habit: the 0% holds at 0.0% in business hours and 0.0% after hours for both phone and portal, so neither the answering service nor a resident can set severity in AppFolio at all.

The assignment lag is an hours effect, not a channel effect — every channel lands at 11–16 hours after 5pm — so replacing the answering service alone would not move it. The call centre's 1.0-hour headline is a business-hours artefact.

Rework is the one measure where the call centre is systematically worse. On apartments alone the portal is the more after-hours channel of the two (46.6% against 36.2%) and re-assigns slightly more often (31.6% against 29.9%), so duplicates rather than re-assignment are what separate them. The portal's 10.7% online-update rate against the call centre's 2.2% points at callers being unable to see the ticket they already have.

Abandonment sits with the bots and two staff creators (25.0% and 18.6% stale at 30 days, against 0.4% and 0.0% for two others), not with the phone.

Contact-pinning error rates are 8.2% call centre (n=364), 10.0% staff (n=10), 12.5% bots (n=8), 0.0% portal (n=6) PARTIAL. The three small denominators establish no difference between groups.

Estimate (method inside)
EstimateSizeMethod
Emergency-worded tickets that are genuine life-safety~17/yrINFERRED — a tenth of the measured 172; the share is an assumption
Avoidable rework408 duplicate pairs + 48 re-files ≈ 7% of the bookMEASURED, upper bound — heuristic pairing
After-hours maintenance a 24/7 agent absorbs615 a year ≈ 1.7/dayMEASURED
Cost of the AppFolio add-on~$7.1K/yr on the apartmentsINFERRED — $1.50/unit/month from the hub × the 397 apartment doors; across Hugo's ~1,000 doors it is order of $18K/yr

Open work orders quiet for 30+ days: 135 of the 205 quiet for a week; none of them from the call centre. MEASURED

Detail — what they said, and what we can't see
"…using the answering service/feature for after hours / weekend inbound calls / leads that would allow us to retire our MCC line and keep our main line available 24/7… after hours Clara answers all the calls and ports out through the tree when an emergency, etc. arises." — Hugo, email of 27 Aug
"After-hours maintenance goes to the MCC — an offshore call center paid for through AppFolio." — Eileen, 1 Sep. On a live test call the agent could not match "yellow jackets" to the existing "bees" work order, took 8+ minutes, and logged it against the wrong property. That call was on a single-family house, so it sits outside this page's scope — the behaviour still stands as evidence.

Hub page: published office hours Mon–Fri 9–5, closed weekends — 128 of 168 hours a week unstaffed.

What we can't see: call recordings, total call volume, calls that ended without a ticket, the vendor's contractual SLA, and whether the answering service is able to set urgency in AppFolio at all.

Leasing

174 of 658 leads arrived outside Mon–Fri 8–5 and waited a median 15.5 hours for a human, against 33 minutes in business hours. MEASURED

When the lead landsLeadsGot a humanMedian waitTouredMoved in
All658623 (95%)1.2 h43.2%18.4%
Office hours48446233 min47.1%19.8%
After hours17416115.5 h32.2%14.4%
Weekends only555029.4 h30.9%14.5%

All MEASURED. After hours = outside Mon–Fri 08:00–17:00 Mountain, weekends included.

What prospects ask about

TopicMessagesShareNever answered by a human
Scheduling a tour (specific times)1006.4%1 (1.0%)
Deposit / fees / payment895.7%3 (3.4%)
Arrival / en route764.9%4 (5.3%)
Application status / next steps493.2%3 (6.1%)
Price / rent amount382.4%0 (0.0%)
Tour / showing request372.4%1 (2.7%)
Address / location / area301.9%2 (6.7%)
Showing confirm / cancel reply301.9%2 (6.7%)
Income / credit / screening191.2%1 (5.3%)
Availability / still available181.2%3 (16.7%)

All MEASURED, 2026 window, apartments only. Top 10 substantive topics of 1,555 inbound prospect messages, one topic per message. Residue: 25.1% unclassified, 23.4% bare acknowledgements, 14.3% short fragments under 25 characters.

Detail — the rest of the leasing record
MeasureValueLabel
Prospect messages answered by a human95.3%, median 48 minMEASURED
Weekend prospect messagesmedian 2.1 hMEASURED
Complaint messages with no human reply7 of 10MEASURED
Live threads ending in an unanswered message35, of which 1 contains an explicit questionMEASURED — pleasantries filtered from a raw 52; the explicit-question count is the most fragile number on this page
Showings, all in-person, none self-guided417MEASURED
Booked ahead / confirmed before the slotmedian 28.9 h / 1.9 hMEASURED
Cancelled within two hours of the slot47MEASURED
Confirmation texts sent / one-word replies351 / 180MEASURED
Applications1 decided inside 24 h; 6 still pending, oldest opened 30 JanPARTIAL — timings from the 67 apartment applications captured in detail
Screening completed inside AppFolio12 of 248 (4.8%)PARTIAL — the application report carries no property, so this covers the whole portfolio
Zillow / TurboTenant / Zumper / Rent.com → tenants239→13 · 115→3 · 20→0 · 40→0PARTIAL — the source report carries no property, so this covers the whole portfolio
Referrals / drive-bys → tenants37.3% / 20.8%MEASURED
Leads that never sent a message back295 of 658 (44.8%)MEASURED
Same phone number, different name across leads13 cases (22 phones on 44 cards)MEASURED
Median market rent$1,650MEASURED — 388 apartment units

What we can't see: the phone. 173 call events across all 658 apartment leads, 7 of them after hours. Nothing here measures the voicemail channel.

Estimate (method inside)
GapVolumePer yearMethod
After-hours leads answered in minutes+16.6 move-ins$27,390after-hours cohort converting like the fast business-hours cohort × one month's rent
Leads with no human contact35$9,93335 × the business-hours move-in rate × one month's rent
Unanswered live prospect threads35$9,933same method
Rent-ready homes not listed7 units / 331 idle days$17,965331 ÷ 30.4 × $1,650
Total$65,221INFERRED throughout

Each recovered lease is valued at one month of rent. Excluded: the VA hours (658 hand-keyed leads, 351 confirmation texts, the scheduling events), listing spend, the vacancy days behind a 12.1-day application clock, and the phone channel. The conversion uplift is a correlational reference class, not a causal estimate; Situs's own speed-versus-outcome curve is not monotonic.

Proposal — what Clara would do here (not measured)
  • Answer every lead within a minute, 24/7, in English or Spanish.
  • Book the tour inside the conversation instead of a 28.9-hour booking lag and a confirm-or-deny text.
  • Chase the silent applicant on a fixed cadence.
  • Escalate complaints and "can I speak to a person" rather than leaving them unanswered.
  • Write the tour note, a real loss reason, and flag a returning phone number.

AppFolio stays the system of record; every action is written back into it.

Prerequisites. 19 of 42 leasable vacant units are simultaneously vacant, rent-ready and advertised with a rent — the verified set she may speak about. Language tagging first, per Eileen. Build dark, prove on a test property; switching Situs on is a separate decision.

Renewals — phase two, not MVP

41 of 111 cleanly-priced renewals (36.9%) were offered below the tenant's current rent, giving back $41,940 a year. Median change was $0. MEASURED

Rent change at renewal, 111 cleanly-priced leasesLeasesShare
Below current rent4136.9%
Flat6054.1%
0–3% increase54.5%
3–6% increase54.5%
Above 6%00%

All MEASURED. 24 leases excluded because the "previous rent" field held a subsidised tenant portion of $15–$625 rather than contract rent. Hub, R9: "never offer a renewal below current rent."

Detail — the rest of the renewal book
MeasureValueLabel
Expiring Sep 2026 – Mar 2027 with no renewal contact since 1 May43 of 107 (40%)PARTIAL
2026 leases rolling to month-to-month64 of 214 (29.9%)MEASURED
Renewed / cancelled by user / did not renew77 / 35 / 7MEASURED
Tenants with no lease end date25, $33,160/mo; 13 month-to-month since 2022 or earlierMEASURED
Terms offered across the year12-month 219, month-to-month 215, one 6-monthMEASURED
Touches per renewalmedian 9, max 63; 2,293 across 250 leasesMEASURED
Median days from first renewal touch to lease end106 (p25 71, p75 120)MEASURED
Offers sent / accepted / countersigned / cancelled355 / 204 (57%) / 163 / 91MEASURED
Automated reminder emails827 = 2.3 per offerMEASURED
Individually written discount offers82 across 54 tenants: $250 ×14, $500 ×13, $1,000 ×9MEASURED
Their authorsDeiby 29, Lee 17, shared VA login 16 — no principal writes oneMEASURED
"My rent is supposed to have the second half of my lease renewal incentive applied to this month. I signed my lease last month with a $1,000 incentive… My rent is showing 1250 and should only be 750 this month. I don't want to receive a notice for being late. But that is the reason it's late." — tenant, 6 July
"The one that I think would get the hugest ROI… would be the renewals." — Eileen, 1 Sep

What we can't see: the renewal incentive tracker (a spreadsheet outside AppFolio), any recorded reason for a rent cut, and how fresh "market rent" is — 7 upcoming leases carry none and 12 show rent under $300.

Estimate and proposal (not measured)

Re-pricing the 25 month-to-month tenants at 3% is $11,938/yr INFERRED. The rent floor plus the market gap together are credibly $150K–$200K/yr INFERRED; the two are not additive because some leases appear in both.

Phase two, in order: the floor gate first — no offer below current rent, and none built from an empty or zero rent field. Then a priced offer generated on a schedule with the concession on the offer rather than in a text thread. Then one owner for the target expiry window: Hugo wants renewals steered into spring, Eileen wants November–February penalised, and spring 2027 already holds 87 expirations. Accounts in active collections receive no offer.

Maintenance billbacks and the backlog

0 purchase orders exist across 2,322 work orders, and all 370 tenant-billback charge lines total $0.00. MEASURED

Money attached to a work orderWork orders with real contentShowing AppFolio's empty placeholder
Technician labour9491,373
Purchase orders02,322
Invoices17 ($2,510.13)2,305
Tenant-billback charge lines370, all $0.00
Vendor bills153 WOs · 167 bills · $115,072

All MEASURED, verified against the 2,322 multifamily work-order pages with AppFolio's placeholder strings counted as empty. Median vendor bill $360; 163 of 167 paid.

Work orders by category

CategoryWork ordersFrom recategorization
Plumbing / Drain49648
Turn / Make-ready4005
Appliance26311
HVAC21121
Common area / Laundry16793
Exterior / Grounds16666
Pest16238
Doors / Locks / Keys1567
Electrical14124
Other / Uncategorized7070
Windows420
Inspection — new category3535
Safety / Compliance109
Filters / Recurring PM31

All MEASURED, 2,322 apartment work orders in the 2026 window. Method: a keyword pass, then a model pass over the 428 left uncategorized, of which 358 were assigned and 70 stayed Other. A 30-row hand check agreed with 27. Uncategorized fell from 428 to 70.

Detail — category by who opened the ticket
CategoryStaffCall centrePortalBotsOtherTotal
Plumbing / Drain132174116731496
Turn / Make-ready155882290400
Appliance1097635430263
HVAC534242731211
Common area / Laundry22441370167
Exterior / Grounds241061260166
Pest2611211040162
Doors / Locks / Keys623330310156
Electrical622222350141
Other / Uncategorized19111327070
Windows87819042
Inspection211013035
Safety / Compliance1026110
Filters / Recurring PM020103

Bots open 229 of 400 turn tickets, 137 of 167 common-area and 126 of 166 exterior. The call centre concentrates in plumbing (174 tickets) and appliances (76).

Detail — the open pile, and what we can't see
MeasureValue
Open · median age · p90346 · 26 days · 160 days
Open past 30 / 60 / 90 / 180 days145 / 102 / 72 / 19
Completed jobs with a message to the resident afterwards3 of 1,884
Monthly volume Jan → Aug248 → 423, up 71% across the eight months
Median days to finish: Urgent / Normal / blank priority3.7 / 9.3 / 2.8
Median days to finish: in-house vs outside vendors4.0 vs 20–39
Open tickets with no vendor assigned186 of 346

What we can't see: technicians text residents from personal phones, so "3 of 1,884" measures the system of record, not resident contact. Vendor bills sent to an AP email rather than AppFolio are invisible, so $115,072 is a floor.

Estimate (method inside)

212 of the 248 flagged billback tickets carry $0; at the $360 median vendor bill, closing those is ~$76K/yr INFERRED.

1,560.3 unpriced hours at $50–75/h is $78K–$117K/yr INFERRED; no labour rate is recorded anywhere in the dump.

Eileen's own estimate — roughly half of the work orders a year should be billed back and fewer than 100 are — is hers, not ours, and includes owner-billable work. Much of the total is owner-side capital work, and Colorado limits deposit charges.

Inspections

123 of 189 inspections are still marked in progress, and the 310 work orders they generated carry $0.00 invoiced. MEASURED

2026 inspectionsValue
Captured189
In progress / done / new / blank123 / 17 / 5 / 44
Occupied checks / move-out scopes / other100 / 80 / 9
Work orders generated · still open310 · 168 (54%)
Invoiced · labour logged against them$0.00 · 6.0 h
Concentrated in Feb–Mar50 + 71 = 64% of the year

All MEASURED. The inspector field is free text: "2026 inspection" 39, "2026 Inspection" 36, "2026 Inspections" 24, plus "Inspecrion", "Insepection" and "Test". About 87 of 189 name a person.

Detail — what we can't see

Inspection photos and per-item condition ratings: the scrape captured report structure, not images. Whether move-out statements were produced outside AppFolio. Which of the 44 blank-status reports are abandoned rather than mis-saved.

Eileen's ask: an AI first pass on move-out inspections — flag what's missing, email the tech for it, reconcile charges against the ledger, prepare the move-out statement. She rates move-outs and billbacks her second-highest return.

Vacant units versus what is advertised

9 of 35 vacant apartments are advertised nowhere, 7 of them rent-ready and carrying 331 idle unit-days. 17 vacant apartments are advertised while not rent-ready. MEASURED

CutVacantMedian daysp90Not rent-readyNot advertised
Multifamily apartments — in scope3549195199
Single-family houses — excluded56478233
Commercial and shells — excluded661241,3863466
Placeholders — excluded191,5271,8901119
Blended — do not quote125911,5396797

All MEASURED. Corrects an earlier blended median of 33 days and an earlier 63-day "residential" median that included houses. Longest unlisted apartment: Zephyr Storage #18 at 201 days, then Alton 1663-1683-105 at 91 days, rent-ready, $1,410. The five-year-vacant 6900 Lowell rows that used to head this list are a house and a back lot.

Estimate (method inside)
CutForgone to datePer month
Multifamily apartments$133,210$58,192
Commercial and shells — excluded$1,016,736$65,852
Placeholder records — not a real loss$1,441,333$26,935
Blended — misleading$2,646,284$160,179

INFERRED: days vacant ÷ 30.4 × rent, taking the first of scheduled, advertised, new or last rent; units with no rent contribute $0, so the figure is a floor.

The 7 rent-ready unlisted apartments carry $10,425/month of scheduled or advertised rent. Cutting the apartment median from 49 to 40 days across the 92 apartment turnovers is worth roughly $44K/yr INFERRED.

Detail — what we can't see

Whether a unit is unlisted deliberately: AppFolio has no such flag, so a redevelopment hold and an oversight look identical. One scrape of the availability page, so no history of how long a unit sits before it is listed. Zillow and Tenant Turner listing state is not visible, only AppFolio's posted-to-internet flag that feeds them.

"AppFolio 'posted to internet' flag generates the property integration ID that feeds all ILSs — unposting a unit kills the feed even on paid contracts." — Eileen, 1 Sep

Turnovers

59 of 92 turnovers (64%) missed their own target date; the median takes 32 days. MEASURED

Days to completeTurnovers
0–147
15–3026
31–6030
61–906
90+3
No end date20

All MEASURED. 123 rows, 92 of them multifamily; median and p90 (62, max 151) computed over the 72 rows carrying a completed duration.

Estimate (method inside)

48 of 92 turnovers record no cost. At the $1,755 mean of the 44 that do, that is ~$84K of turnover spend never reaching a billing decision INFERRED — smaller if some were genuinely no-cost turns.

If half the 20 turnovers with no end date are genuinely open at ~$1,700 rent, that is ~$16K/month of ambiguous vacancy INFERRED.

Detail — what we can't see

Orca went live the day of the meeting, so none of its data is in this dump: everything here is the pre-Orca baseline. The vendor rate card is outside AppFolio. Labour, purchase-order, billable and inventory columns parsed empty on every turn row. Inspections carry no type field — move-out scope versus occupied check is inferred from which question template was used, and only a handful of distinct unit tokens could be recovered from the 80 scope inspections, so the 42-of-92 match is a floor. Inspection records carry no property link, so only the turn side of this match is scoped to apartments.

Resident communication and language

509 of 2,429 inbound resident texts (21.0%) never received a human reply within 14 days. The median reply takes 14.3 hours. MEASURED

MeasureValue
Captured resident events in the window61,563 — email 28,356 · texts 21,785 · lease and audit 10,632 · notes 790
Residents who texted back at least once422 of 1,036 (40.7%)
Residents who sent an email in11.2%; 151 have no captured contact at all
Inbound texts arriving outside Mon–Fri 8–5459 (18.9%)
Worst day of the weekWednesday, median 19.4 h (Thursday 19.1 h, Sunday 19.0 h)
p90 wait for a reply6.2 days
Outbound texts containing Spanish8,357 (43.2%), reaching 698 residents — 67% of them
Of those, bilingual blasts76%
Inbound texts in Spanish212 of 2,429
Reply to a Spanish message: Spanish / English / none58% / 25% / 17%
Resident records carrying any language tag191 of 729 (26%) — 101 English, 90 Spanish
Spanish-flagged outbound emails9,528

All MEASURED. Spanish detection is keyword and accent based, not a declared field. Hub: about 70% of resident families are Spanish-speaking. Colorado requires communicating in the tenant's desired language; AppFolio has no preferred-language field.

Detail — the sender correction, and what we can't see

Correction to carry. The failure-rate-by-sender table is unusable: AppFolio strips the author from a message once it fails, so the unnamed sender bucket is exactly the failed set and every named sender reads 0.0%. The overall 8.2% rate stands; a per-person rate is not derivable. MEASURED

Failed-text topics: other 602 · maintenance 506 · money 246 · bulk notice 209 · showing 6 · renewal 10. After a failure, a text followed 19% of the time and an email 41%. MEASURED

Email delivery: 17,248 opened (61.3%), 1,085 hard failures (3.9%). MEASURED

What we can't see: about half of resident communication runs on two employees' personal phones and is not exportable, so every response-time figure measures the visible half. No carrier error code is captured, so a wrong number, a landline and a carrier block are indistinguishable. Whether the 61.3% open rate reflects image-proxy prefetching.

"Sending everything in both English and Spanish offends some tenants… Figure out the language tag first, then all templated comms respect it." — Eileen, 1 Sep

Money owed

Residents and corporate accounts at the apartments owe $670,223 across 305 accounts. MEASURED

Who owes itAccountsAmountShare
Residents222$441,46665.9%
Company-named accounts83$228,75734.1%
Total, apartments305$670,223100%

All MEASURED. The company-named bucket is classified from name patterns such as LLC, Inc, Corp and Trust INFERRED and will contain some resident co-signers. September's $428,598 is current-month rent charged and not yet due on the report date — not arrears, do not quote it. Two AppFolio reports still disagree at the portfolio level (unverified).

Detail — aging, and what we can't see
Last paymentAccountsAmount
Within 1 month267$492,133
Never recorded14$62,970
3–12 months ago4$62,111
1–3 months ago20$53,009
Over 12 months ago0$0

Only 5 rows belong to former residents who have moved out ($13,512). 5 balances are under $500. 7 payment plans exist only as note text. MEASURED

What we can't see: what the Ananeo Colorado LLC concentration represents; why the two AppFolio reports disagree; legal status — no eviction filings, demand letters or notices to pay or quit appear in the dump; the terms of the 7 verbal payment plans; cash and money-order payments (30 mentions across 21 residents).

Estimate (method inside)

Recovering 25% of the un-contacted $247,846 is ~$62,000 INFERRED. The 25% assumption has no basis in their own history.

Data quality

521 of 729 resident records (71.5%) carry no tag of any kind; 249 (34.2%) have no phone number and 265 (36.4%) no email. MEASURED

Field on the resident list (729 apartment records)Blank%
Tenant Tags52171.5%
Phone numbers24934.2%
Emails26536.4%
Lease end date506.9%
Unit / tenant / status / type / move-in / rent / deposit1 each0.1%

All MEASURED. 7 upcoming-expiry rows carry no market rent and 12 show rent under $300. Language tags: 101 English, 90 Spanish across 208 tagged rows.

Detail — what we can't see

The rent roll cannot be audited against reality from a CSV. Language detection is keyword-based on message text, not a declared field. The tenant-directory match rate is 557 of 753 names, so untagged counts are floors. Note timestamps are post or last-edited times, not the date of the event described; 150 notes carry a pre-2026 date with a body citing a 2025–26 event.

"Your data is only as good as the people who are updating it." — Eileen, 1 Sep

Work that never touches AppFolio

One message asking residents to stop contacting a staff member's personal phone was sent 554 times, to 551 distinct residents — 76% of the 729-row apartment resident directory. MEASURED

"Dear Tenants, Miriam is currently on maternity leave… We kindly ask that you respect her privacy and not contact her personal phone. For maintenance, call 24/7 MCC at 720-459-5986 (Option 2 for Spanish). For all other questions, call 303-789-3030. Our office hours are 9:00 AM–5:00 PM."

Deduplicated counts: notes deduped on author, timestamp and first 300 characters; texts restricted to non-template sends, where a template is any message body sent to 10+ distinct residents.

Detail — what they said, and what we can't see
"~50% of tenant communication happens on two employees' personal cell phones — $50/month allowance, no visibility, no way to bulk-upload their texts." — Eileen, 1 Sep
"The moment that they find out that it's going to record them, the whole system would collapse." — Eileen, 1 Sep
Techs are 1099 workers who invoice by text photo. A tech was set up as a "vendor" in AppFolio purely so the VAs could text him.

What we can't see: the shadow channel itself. Everything measured here is what leaked into AppFolio; the ~50% figure is Eileen's estimate, not ours. No MCC call logs, no Crexendo records, no Orca data, no spreadsheets, no tech text threads. 51% of notes are truncated, so keyword detection under-counts. An earlier claim that 11 outbound texts publish a staff cell number in the signature is not reproducible and is withdrawn.

Interpretation (not measured)

A record written after the fact is a summary of a conversation, not the conversation. Payment plans, notices to vacate, maintenance commitments and renewal decisions agreed by voice reach AppFolio days later or never, so an agent can contradict a deal a human already made. For residents in the habit of texting a personal mobile, an agent's number is the second channel and silence on it is not silence. Staff resistance is a design constraint: Eileen is explicit that anything reading as surveillance of the on-site team gets routed around.

Inferred policies and conflicts

52,992 staff statements in the 2026 window · 49 topics with evidence · 21 stable rules · 13 conflict topics across 30 conflict rows. MEASURED

No written policy exists in the export: no lease, addendum, house rules or manual. The only written rules are AppFolio's per-lease settings. MEASURED — 0 files matched *.pdf, *lease*, *policy* or *addend*.

TopicVariantsPeople affectedWhoNote
NSF fee — spoken vs system System: $0.00 (594 leases), $50.00 (49), blank (698). Staff quote $50. 643 leases · 18 residents told $50 AppFolio lease settings vs Assistant Lead, Miriam Gallegos, unnamed staff A resident on a $0.00 lease who is told $50 is quoted a charge the system will not raise.
Resident referral credit $500 (1,120 msgs) · $250 (884 msgs) 604 and 477 · 468 received both Deiby Magana (1,078 and 871), Courtney Tolentino, unnamed staff Genuine inconsistency: both figures from the same person, across 13 shared properties, in overlapping weeks. Two campaigns ran at once — an "up to $500" bonus and a "$250, restrictions apply" open-house incentive.
Late fee — spoken vs system System: 10% of rent (139 leases), $0.00 (129), $50.00 (121), $75.00 (83), $25.00 (6). Staff quote a flat $50 to everyone. 485 leases · 79 residents told $50 AppFolio lease settings vs Assistant Lead, Miriam Gallegos, Courtney Tolentino, unnamed staff 364 of the 485 leases are not on the $50 scheme. 100 leases also accrue $5.00 a day with no monthly cap, which no message ever mentions. The system disagrees with the staff, not the staff with each other.
Rent grace period — system only Late fees post after 5 days (263 leases), 4 days (192), 10 days (30) 485 leases AppFolio lease settings Three grace periods run side by side and staff never state any of them. No message states the rent due date.
Free-rent concession on a new lease 6 weeks (141 msgs) · 4 weeks (51) · 8 weeks (13) · 2 weeks (3) 88 · 41 · 8 · 2 — 3 quoted two lengths Assistant Lead, Deiby Magana, Miriam Gallegos, Lee McKibbin, Courtney Tolentino Genuine inconsistency: all four lengths quoted in the same months, by the same people, at overlapping properties.

The lease settles four of these. Late fee: $50 or 5% of rent, whichever is greater, after a 7-day grace, rent due the 3rd — so the flat $50 is wrong and the daily fees appear in no lease. NSF: $50, matching staff, so the $0.00 config is the outlier. Grace period: 7 days, written. Renewal credit: the Renewal Notice Letter states $1,000 paid as 2 × $500. No captured document names a resident referral credit. See Leases and documents. Top 5 of 18 conflict rows, ordered by people affected. Counts are 2026 messages and notes written by a human staff member; the placeholder property and AppFolio's bot accounts are excluded. The shared VA login counts as human. System rows are counted in leases, which is the number of residents the setting applies to.

Stable rules — 21 ready to load as property facts
#FactEvidence (2026)Scope
1Late fee is $50, charged once, when rent is not paid.175 messages to 79 residents, 5 staff, 24 properties, Jan–Aug. One value only.Portfolio-wide as spoken — AppFolio holds five different late-fee schemes.
2Returned-payment (NSF) fee is $50.22 messages to 18 residents, one value only.Portfolio-wide as spoken — AppFolio has it at $0.00 on 594 leases.
3No renter's insurance on file is charged $10.50 a month for landlord liability.88 messages to 34 residents, 4 staff, one value only.Portfolio-wide.
4Key and lockout charges: lockout $50, after-hours lockout $75, house key $75, storage key $75, mail key $150, duplicate key $35.One standing notice sent 2026-05-12 in English and Spanish, reaching 653 residents.Portfolio-wide.
5A unit not prepared for pest treatment, or where access is denied, is charged $50, not reversed.1,315 messages to 377 residents; one value only.Portfolio-wide.
6Pets: $300 refundable deposit plus $35 a month pet rent.11 messages to 8 people; the two figures always appear together.Carr Street Flats, Barcelona, Mckenzie, Lampliter.
7Month-to-month costs $150 a month on top of rent.89 messages to 60 residents, 4 staff, 8 properties.Portfolio-wide.
8Notice to vacate is 30 days, in writing.7 messages to 7 residents; one value only.Portfolio-wide.
9Entry for maintenance is on 24 hours' notice, and the visit goes ahead whether or not the resident replies.The 24-hour figure is stated; the "we are required to give notice, which we are providing" posture recurs.Portfolio-wide. PARTIAL — few messages state the number outright.
10Rent is paid online through the portal; money orders and cashier's cheques are a fallback.1,265 portal messages to 254 residents; 43 money-order messages to 27.Portfolio-wide. Online payments are off on 221 of 1,341 leases.
11No response to a renewal offer rolls the lease to month-to-month at the $150 premium.92 messages to 62 residents.Portfolio-wide.
12Vehicles must be operable with current plates; unauthorised or improperly parked cars are towed at the owner's expense.2,057 + 2,658 messages reaching 656 and 635 residents — the two largest rule statements in the corpus.Portfolio-wide; heaviest at Barcelona, Lampliter, Lowry Flats, Chase Tower.
13No bulk items, furniture or mattresses at the dumpster; bagged household trash only.433 + 87 messages to 175 and 63 residents.Heaviest at Chase Tower, Bryant Gardens, Carr Street Flats.
14After hours, residents call the 24/7 MCC emergency line; non-emergencies wait for business hours; fire or gas means 911 first.2,261 emergency-line messages to 702 residents; 845 non-emergency statements; 305 call-911 statements.Portfolio-wide.
15Maintenance requests are submitted through the resident portal.1,457 messages to 288 residents; one message offers text or email instead.Portfolio-wide.
16Pest treatment requires a completed prep sheet, cannot be refused, and repeat visits are scheduled when a unit is not ready.33 prep-sheet, 470 follow-up and 108 fee messages.Portfolio-wide; heaviest at Lowry Flats, Barcelona, Aspen Leaf.
17Showings are confirmed by replying CONFIRM or DENY before a stated cut-off.719 messages to 399 prospects.Portfolio-wide.
18Offices close for public holidays and reopen the next business day; emergency maintenance stays available.2,910 closure and 2,429 emergency-still-available messages, reaching 944 and 791 residents.Portfolio-wide.
19Residents who write in Spanish are answered in Spanish; most announcements go out in both languages in one send.12,416 bilingual sends to 845 residents; 13,562 Spanish-only sends to 888.Portfolio-wide.
20When staff get something wrong they send a plain correction.304 self-corrections to 220 residents.Portfolio-wide.
21Quiet hours are 10:00 PM to 8:00 AM; children outside must be supervised by an adult.123 messages stating the window; 514 supervision messages to 137 residents.Sent as portfolio blasts; no property-specific variation found.
All 30 conflict rows
TopicVariantMsgsPeopleWhoVerdict
Resident referral credit$5001,088581Deiby Magana (1,078); unnamed (10)Genuine inconsistency — residents received both figures. No captured document names a referral credit
Resident referral credit$250884477Deiby Magana (871); unnamed (12); Lee McKibbin (1)Genuine inconsistency — same person, 12 shared properties, overlapping weeks
NSF fee — spoken vs systemAppFolio: $0.00 (413), $50.00 (49), blank (574)462AppFolio lease settingsSystem contradicts staff — the lease says $50, so staff match the lease and the config is the outlier
NSF fee — spoken vs systemStaff quote $502218Assistant Lead, Miriam Gallegos, unnamedSystem has $0.00 on 413 leases, $50.00 on 49; the lease says $50
Late fee — spoken vs systemFive schemes side by side in AppFolio379AppFolio lease settings, effective 02/2021 to 11/2025259 of 379 apartment leases are not on the $50 scheme; many also accrue $5.00/day with no cap
Late fee — spoken vs systemStaff quote a flat $50 to everyone16877Assistant Lead, Miriam Gallegos, Courtney Tolentino, unnamedBiggest conflict in the portfolio. The lease says $50 or 5% of rent, whichever is greater — $77.50 on a $1,550 rent
Rent grace period — system onlyAfter 5 days (158), 4 days (192), 10 days (29)379AppFolio lease settingsThree grace periods side by side; staff state none of them. Every lease says a 7-day grace, rent due the 3rd
Free-rent concession6 weeks14188Assistant Lead (69); Deiby Magana (44); Miriam Gallegos (10); Lee McKibbin (10)Genuine inconsistency
Free-rent concession4 weeks5141Deiby Magana (20); Assistant Lead (10); Lee McKibbin (9); Miriam Gallegos (5)Genuine inconsistency
Free-rent concession8 weeks138Assistant Lead (9); Deiby Magana (4)Genuine inconsistency
Free-rent concession2 weeks32Courtney Tolentino (3)Genuine inconsistency — 3 residents quoted two lengths
Utility bill-backs — spoken vs systemStaff bill utilities back in 26 messages2611Miriam Gallegos, Assistant LeadRUBS billing is set to No on all 1,036 apartment resident records — computed outside the system of record
Month-to-month premium$1508456Courtney Tolentino (63); Miriam Gallegos (9); unnamed$150 is the rule
Month-to-month premium$111Deiby Magana (1)Not a second policy — a per-unit rent figure caught by the pattern
Application processing timeNo timeframe given2216Courtney Tolentino (19); Deiby Magana (3)Genuine inconsistency — the most common answer is no timeframe at all
Application processing time48–72 hours64Courtney Tolentino (4); Deiby Magana (2)Genuine inconsistency
Application processing time3–5 days43Deiby Magana (4)Genuine inconsistency
Application processing time2–3 days32Lee McKibbin (3)Genuine inconsistency
Application processing time24 hours / next day22Miriam Gallegos (2)Four different answers from four agents in the same months
Renewal bonus$1,00085Assistant Lead (4); Miriam Gallegos (2); Deiby Magana (2)The Renewal Notice Letter states $1,000 paid as 2 × $500 — the written answer
Renewal bonus$50022Lee McKibbin (1); Deiby Magana (1)Written amount is $1,000 as 2 × $500
Renewal bonus$25022Deiby Magana (2)Written amount is $1,000 as 2 × $500
Pet fee$3554Deiby Magana (3); Lee McKibbin (2)Not a conflict — $35 is monthly pet rent
Pet fee$30064Lee McKibbin (3); Courtney Tolentino (3)Not a conflict — $300 is the refundable deposit
Certified funds — spoken vs systemStaff demand certified funds in 2 messages22Deiby MaganaCertified Funds Only is set to No on all 1,036 apartment resident records
Application feeStaff: none / $021one author, Carr Street FlatsFour published answers. One staff message says "we do not collect or receive those fees directly" — likely the application platform's own fee
Application feePublic listings: $45.00 per adult29 listing pagesMarketingThe advertised figure
Application feeArizona AppFolio listing text: $31.001 propertyMarketingA third figure on their own listing
Application feeLeases: silent195 documentsLease documentsNo lease names an application fee at all
Balance blocks renewalStaff: account must be current first44No lease and no renewal letter states this condition — a renewal withheld on a rule nothing in writing supports
Per-topic ledger — all 49 topics with evidence
TopicRule as observedVolumeLabel
Late feeA flat $50 late fee is charged when rent is not paid, and residents are told the exact balance owed alongside it.1,352 msgs · 268 peopleMEASURED
Rent grace period / due dateStaff almost never state the grace period. The system applies one of three: late fees post after 5 days (263 leases), after 4 days (192) or after 10 days (30).0 msgs · 0 peoplePARTIAL
NSF / returned-payment feeA returned payment costs $50, applied to the account, with a request to bring the balance current.47 msgs · 34 peopleMEASURED
Renter's insurance / landlord-liability chargeA resident with no renter's insurance policy on file is charged $10.50 a month for landlord liability until proof of insurance is provided.1,294 msgs · 238 peopleMEASURED
Lockout / lost-key / key-replacement chargeA published charge schedule: lockout $50, after-hours lockout $75, house key replacement $75, storage key $75, mail key $150, duplicate key $35.2,410 msgs · 658 peopleMEASURED
Pest-prep / failure-to-prepare / denied-access feeA unit that is not prepared for pest treatment, or where the technician is denied access, is charged $50, and staff state the charge is not reversed.1,572 msgs · 485 peopleMEASURED
Pet fee / pet deposit / pet rentA pet costs a $300 refundable deposit plus $35 a month in pet rent, added to the monthly total.2,208 msgs · 662 peopleMEASURED
Application feeThere is no application fee.18 msgs · 10 peoplePARTIAL
Month-to-month premiumStaying past the lease end on a month-to-month basis costs $150 a month on top of rent.214 msgs · 142 peopleMEASURED
Resident referral creditResidents are offered a credit for referring a new tenant - and two different amounts were promoted at the same time. On apartments alone the more common figure is $250.3,578 msgs · 591 peopleMEASURED
Renewal bonus / renewal creditSome renewing residents are offered a cash credit. Three amounts appear: $1,000, $500 and $250, and one message describes a $500 renewal bonus paid in instalments.16 msgs · 13 peoplePARTIAL
Free-rent concession on a new leaseNew leases are advertised with weeks of free rent, spread evenly across the term. Four lengths were quoted in the same period.1,520 msgs · 758 peopleMEASURED
Security deposit amountThe deposit is quoted per unit, not as a policy - $750, $1,050, $1,500 and $1,750 all appear, each tied to a specific unit and rent.622 msgs · 297 peopleMEASURED
Security-deposit return timelineNo apartment message states a deposit turnaround at all — the 30-versus-60-day split was said only outside the apartment book, so this rule is Unknown here.no multifamily evidencePARTIAL
Notice to vacateA written 30-day notice is required, listing every leaseholder and the move-out date, submitted through the portal.17 msgs · 12 peopleMEASURED
Entry notice before maintenance24 hours' notice before entering, and staff state the entry is happening rather than asking.27 msgs · 23 peoplePARTIAL
Payment method allowedPay online through the resident portal; money orders and cashier's cheques are accepted; certified funds are demanded only in specific delinquency cases.3,678 msgs · 848 peopleMEASURED
Partial payments & payment plansTwo different approaches are used: a formal signed payment plan, or an informal 'how much can you pay?' that accepts a partial payment. One message insists on payment in full.30 msgs · 26 peopleMEASURED
Balance blocks renewalA resident must bring their account current before a renewal will be offered.4 msgs · 4 peoplePARTIAL
Eviction / legal escalation thresholdDelinquency escalates to eviction or attorney language; a 10-day demand appears occasionally. No balance or day count is ever named as the trigger.1,291 msgs · 519 peopleMEASURED
Collections / delinquency outreach stepsThe sequence is a balance reminder first, a late-fee notice second, and demand or eviction language last.609 msgs · 275 peopleMEASURED
Parking & towing enforcementVehicles must be operable and display current plates; unauthorised, expired or improperly parked vehicles are towed at the owner's expense; some properties require a permit or assign spaces.9,745 msgs · 838 peopleMEASURED
Trash / bulk item / dumpster rulesHousehold trash goes in the dumpster, bagged; furniture, mattresses and other bulk items must not be left there.3,722 msgs · 862 peopleMEASURED
SmokingSmoking indoors is prohibited and is handled as a lease violation; marijuana is called out by name.59 msgs · 48 peopleMEASURED
Guests & unauthorized occupantsAn unauthorised occupant is a lease violation; anyone living in the unit must apply and be screened.35 msgs · 28 peopleMEASURED
Unit transferMoving to another unit requires a new lease or a new application; a cost is mentioned once.16 msgs · 15 peoplePARTIAL
Lease break / early terminationA buy-out or termination fee is discussed case by case; one message says the resident stays responsible for rent until the unit is re-rented.6 msgs · 6 peoplePARTIAL
Emergency definition & after-hours handlingEmergencies go to the 24/7 MCC emergency line; residents are given examples (no heat, flooding, no water, sewage, lockout); non-emergencies wait for business hours; fire or gas means 911 first.7,677 msgs · 785 peopleMEASURED
Maintenance request intake channelRequests go through the resident portal.1,750 msgs · 421 peopleMEASURED
Work-order timing promiseThere is no standing service-level promise. Staff commit case by case: a named date or window most often, then today, then tomorrow, and 'as soon as possible' with no date in a fifth of promises.450 msgs · 288 peopleMEASURED
Permission to enter when resident is absentStaff sometimes ask and wait for a reply, but the standing posture is that 24 hours' notice has been given and the visit proceeds.20 msgs · 16 peoplePARTIAL
Pest treatment complianceThe unit must be prepared to a prep sheet before treatment; treatment cannot be refused; an unprepared unit is charged and re-scheduled.4,648 msgs · 882 peopleMEASURED
InspectionsAnnual or routine inspections are announced in advance; move-in, move-out and housing-authority inspections are handled separately.2,123 msgs · 742 peopleMEASURED
Housing vouchers / Section 8 / DHAVouchers are accepted and processed; the housing authority inspects; the resident's portion changes when the authority recalculates; rent increases are submitted to the authority for approval.102 msgs · 54 peopleMEASURED
Application screening criteriaApplications are screened on criminal and background history, rental and landlord history, credit, and proof of income. No threshold is published for any of them.71 msgs · 45 peoplePARTIAL
Co-signer / guarantorAn approval can be made conditional on adding a co-signer; the co-signer applies and is screened separately.15 msgs · 6 peoplePARTIAL
Holding deposit / holding a unitA deposit is required to hold a unit off the market.20 msgs · 11 peoplePARTIAL
Tours & showingsShowings are booked with a confirmation text the prospect must answer CONFIRM or DENY before a cut-off; most are agent-accompanied; ID or an application is sometimes required first; self-guided showings are rare.2,567 msgs · 663 peopleMEASURED
Move-in requirementsMove-in funds must be paid before keys, and utilities must be transferred into the resident's name.34 msgs · 25 peoplePARTIAL
Move-out & turn chargesThe unit is expected back clean, with all keys returned, and cleaning, carpet and damage costs come out of the deposit.4 msgs · 3 peoplePARTIAL
Utilities & RUBS billingCommercial tenants are billed back for shared utilities; residents at most properties must put their own utilities in their name; building-wide interruptions are announced in advance.149 msgs · 83 peopleMEASURED
Renewal offer mechanicsAn offer goes out with term options and a new rent; if the resident does not respond the lease rolls to month-to-month; the account must be current first.163 msgs · 113 peopleMEASURED
Rent increase at renewalA specific new rent is quoted in the offer. Across 2026 renewals, 45% were flat, 30% were decreases and 18% were increases above 10%.154 msgs · 133 peopleMEASURED
Office hours & closuresWeekday business hours are published; offices close for public holidays and reopen the next business day; emergency maintenance stays available throughout.5,475 msgs · 792 peopleMEASURED
Communication language (English / Spanish)Most portfolio announcements go out with English and Spanish in the same message; residents who write in Spanish are answered in Spanish.52,992 msgs · 1,567 peopleMEASURED
Application processing time promisedProspects asking how long screening takes get four different answers: no timeframe (most common), 48-72 hours, 3-5 days, 2-3 days, or 24 hours.386 msgs · 227 peopleMEASURED
Noise, conduct & quiet enjoymentQuiet hours are 10:00 PM to 8:00 AM: no stomping, running or vacuuming. Children playing outside must be supervised by an adult. Noise complaints are handled as lease violations and staff undertake to speak to the neighbour.554 msgs · 157 peopleMEASURED
Self-correction after a wrong statementWhen staff send something wrong, they follow it with a plain correction asking residents to disregard the previous message.95 msgs · 83 peopleMEASURED
Off-book personal commitment by staffStaff make personal commitments outside any system - dropping off a gift card, delivering a TV, reversing a late fee, applying a credit.83 msgs · 57 peopleMEASURED
17 topics with no rule in the record
Topic looked forWhat was found
Subletting / short-term rentalZero messages in 2026.
How long a guest may stay before joining the leaseZero messages state a number of days. Staff say only that anyone staying must be added and screened.
Income requirementOne application denial cites a "2x rent income requirement". Nothing else states a multiple.
Minimum credit scoreSix messages mention credit; none states a threshold.
Minimum renter's-insurance coverageZero messages state a coverage limit, only the $10.50 charge when no policy is on file.
Daily late-fee accrualAppFolio charges $5.00 a day with no cap on 100 leases. Zero messages mention it — and no lease document mentions a daily fee either.
Rent due dateZero messages state it. Every lease says the 3rd, with the late fee on the 11th; the Rent Increase letter template says the first.
Proration at move-in or move-out68 messages contain prorated figures; none states the rule used.
Work-order service-level promiseNo standing SLA is ever stated. Timing is promised case by case.
Renewal notice periodSix messages mention 60 or 90 days, all about applications or rent increases.
Security-deposit deduction scheduleFive move-out messages in all of 2026. No price list, no standard turn charges.
Pool, fitness or clubhouse rulesZero messages. These amenities do not appear in the record.
Alterations, painting, satellite dishesSix messages, none stating a rule.
Snow and ice removal responsibility11 messages, none stating who is responsible.
Eviction threshold910 messages use eviction or attorney language; none states the trigger. Three mention a 10-day demand.
Written lease, addendum or house rulesNone in the message export. Superseded: 195 lease documents were later pulled — see Leases and documents. The house rules are a Community Policies addendum inside 157 leases, never a standalone document.
Quiet hours outside the blasted properties10:00 PM to 8:00 AM appears in 123 messages, but only inside two portfolio blasts.
Method, definitions and limits
  • Window: 2026-01-01 to the 2026-09-01 capture. Pre-2026 matches appear only in an "earlier history" column and are never added to a 2026 count. Undated records are excluded from both.
  • Corpus: 152,955 staff-authored statements from tenant SMS, tenant email, tenant notes, guest-card messages and notes, application messages and decision reasons, and work-order remarks. 84,346 fall in the window; restricted to the 16 multifamily apartment properties and to human authors, 52,992 remain. 36,078 were dropped as commercial or shell (24,109) or single-family (11,969).
  • Notes were split out of AppFolio's stacked panel into individual notes with their own author and date — 2,087 notes, 1,217 in 2026. Earlier analyses treated a whole panel as one undated note.
  • Assistant Lead is a shared VA login counted as staff. System, PM Assistant, Maintenance Performer and Customer Service are bots and are excluded, as are work-order records themselves. The scope is the 16 multifamily apartment properties only: placeholders, commercial, single-family houses and entity shells are excluded from every count.
  • Three counts per rule answer different questions: messages (how often it was said, blasts included), residents (how many distinct people heard it), distinct wordings (how many genuinely different statements sit behind the volume). One blast can show thousands of messages and a handful of wordings.
  • Property is attached from each resident record's own unit link, and for prospects from the guest card's property cell. Roughly one message in ten could not be matched to a property and is excluded from the multifamily scope.
  • Values are pulled only where the amount is tightly bound to the fee it names ("$50 late fee"), and matches next to balance, prorated or reversal language are dropped. This undercounts rather than inventing a policy out of an account balance.
  • Conflict verdicts come from a split test: two values are a genuine inconsistency when the same resident was told both, or the same staff member said both at a shared property in overlapping weeks; they are per-property when the two values share no property.
  • Quotes are de-identified in place — phone numbers, email addresses, street addresses and greeting names replaced. Situs staff names are kept, because who said what is the point of the ledger.
  • Limits: keyword selection can miss a rule worded in a way nobody searched for, and can over-select a topic, which is why every money topic also reports how many messages actually state a value. Nothing was verified against AppFolio, the phone line, or any document Situs holds outside this export.
  • Full ledger with verbatim evidence: ~/situs-data/analysis/POLICY-LEDGER.md. Tables under ~/situs-data/analysis/tables/policy_*.csv.

Leases and documents

195 lease documents across 115 occupancies and all 16 buildings; 22 letter templates; 83 property attachments, 79 text-extracted; 29 listing pages; 10 settings captures. MEASURED — pulled read-only 2026-09-02, apartments only (16 properties, 397 doors).

Four lease forms are live at once: the 2026 IH Holdings form (69 leases, 13 properties), the older IH Holdings form (79, 10 properties), a standalone month-to-month lease (12, 6 properties), and the Alton / Bryant Gardens 5-year corporate master lease to a nonprofit (11 documents, 2 properties — 88 doors, 22% of the portfolio). MEASURED

RuleWhat the lease saysWhat staff sayWhat AppFolio charges
Late fee$50 or 5% of rent, whichever is greater, once, after a 7-day grace. Rent due the 3rd, fee on the 11th.A flat $50 to everyoneFive schemes side by side: 259 of 379 apartment leases are not on the $50 scheme, and daily fees appear in no lease document.
NSF / returned payment$50$50$0.00 on 413 apartment leases, $50.00 on 49; set at only 1 of 16 properties (Bryant Gardens)
Pest-prep failure feeBlank — an unfilled merge field in 146 of 171 leases; fallback wording is "actual cost of service"$50, described as never reversed — 344 residents
Liability insurance$10.50/mo before 9 June 2026 (40 leases), $10.00/mo from 9 June (29). 102 leases require insurance but name no charge; 23 have no clause.$10.50 quoted into AugustRenters-insurance module off at company level
Renewal creditRenewal Notice Letter: $1,000 paid as 2 × $500, 60-day notice$1,000 / $500 / $250
Month-to-month premium$150/month$150/month
Deposit dispositionReturned within 60 days, itemised"30 to 60 days"; one agent splits 30 to process, 60 to issue
Holdover2× daily rentNever stated to a resident

All MEASURED, quoted from documents on disk. "Contradicts" means the document and the measured staff practice state different things; it does not say which Situs intends to be true.

Not in the documents

Detail — inventory by document type
DocumentPropertiesDocumentsKey values it states
Residential lease (four live forms)15 of 16 executed195 / 171 completeLate fee, NSF $50, deposit 60 days itemised, month-to-month $150, holdover 2× daily rent, 18% interest on unpaid balances
Community Policies addendum — the de-facto house rules15157 (81%)Quiet hours 10pm–8am · guest limit 3 days (64 leases) or 48 hours (27) · no grilling within 10 ft · no drilling or satellite dish without consent · weapons prohibited · pet waste $50 per cleanup
Drug-Free / Crime-Free addendum15157Criminal activity by tenant, household, guest or anyone under their control is grounds for eviction
Pest Control addendum15157Treatment cannot be refused · prep sheet supplied with notice · re-treatment free within 30 days · failure-to-prep fee blank in 146 of 171
Mold Prevention addendum15157Tenant duty to ventilate and report; landlord remediation process
Colorado Radon Disclosure15156Statutory disclosure
Lead-Based Paint · Asbestos disclosures14148 eachStatutory disclosures
Parking addendum13131Numbered spaces · fee $0 in most leases · towing at owner's expense without notice · no repairs, no RV or boat
Tobacco & Marijuana Smoking addendum13129No smoking inside or within 10 feet of an entrance · no cultivation
Move-in / Move-out Inspection Checklist1587 (45%)Checklist returned within 72 hours; silence is binding acceptance of the unit's condition
Jury Trial Waiver & Attorney Fee Cap1042Jury-trial waiver; attorney-fee cap
Insurance addendum723Proof due within 30 days of move-in; failure triggers auto-enrolment in a landlord-liability policy
Pet addendum · ESA / Assistance Animal7 · 316 · 5No animal without prior written consent · landlord may prohibit breeds · $300 deposit + $35/mo (listings)
Storage Unit · Appliance · Exterior Yard3 · 1 · 14 · 2 · 2Unit-specific terms
Property Documents tab10 of 16 have any file83No policy content: 68 police incident reports, 5 parking or unit maps, 2 insurance certificates, 1 trash-day sheet, 2 photos
Public listings29 pagesApplication fee $45.00 per adult (Arizona's own text says $31) · pet $300 + $35/mo (Arizona says $25) · deposit "$750–$1,500 based on application"
Portfolio settings106 property records10 capturesOnline applications OFF · renters-insurance module OFF · texting ON · America/Denver · call centre ON at all 16 · entry pre-authorised false at all 16 · maintenance spend limit $0 at all 16 · 1,534 per-lease late-fee policies

17 distinct addenda types. The Alton and Bryant Gardens master leases carry no renter's-insurance obligation, no month-to-month fee, no security-deposit amount, no parking addendum and no smoking addendum; all six Alton documents are unsigned, and their notice to vacate is 90 days against 30 everywhere else.

Detail — the 22 letter templates

13 tenant: 3-Day Notice · Renewal Notice Letter · Renewal Notice Letter (Section 8) · Non-Renewal Letter · Non-Renewal Letter (Spanish) · Rent Increase · Deposit Disposition Refund · Deposit Disposition Amount Due · Security Deposit Interest · Tenant Payment Information · Tenant Unpaid Charges · 24/7 Maintenance Support Options · Arizona Welcome Letter (English).

6 applicant: Adverse Action Notice · Approval · Approved with Conditions · Denial · Partial Report Denial · Pre-Approval. 3 owner: ACH Setup for Distributions · Owner Bank Account Information · Updated Address for K-1s.

Three carry conflicts. The Rent Increase letter is the unmodified AppFolio default and says rent is due the first of the month; every lease says the 3rd. The Renewal Notice Letter states the $1,000 credit as two $500 payments. The 24/7 Maintenance letter promises "up to a week for non-emergency repairs" — a service-level promise stated in no lease and never quoted to a resident.

Detail — coverage per property
PropertyDoorsOccupancies with an executed leaseLease documentsProperty-tab files
Alton Apartments55004
Barcelona Apartments48891
Lampliter41101210
Carr Street Flats34887
Bryant Gardens33550
Lowry Flats Apartments26891
Aspen Leaf247110
Mckenzie24556
Zephyr23112051
Cottonwoods2214330
Olde Town Terrace208220
Dahlia Apartments127181
Mayor Apartments126121
Dexter Apartments116151
6908 Lowell LLC6440
Arizona5260
Total39710919583

Arizona (2) and 6908 Lowell (4) fall short because that is all that exists — every other occupancy at those two properties has only cancelled documents, verified by exhausting the list. Of 64 policy values recovered from documents, 28 confirm what staff say, 19 contradict it, and 16 are written rules staff have never mentioned to a resident.

The corpus as eval material — internal

1,999 real inbound turns carry an individual human reply. Our only existing real-conversation eval holds 42 rows. MEASURED

ChannelInbound turnsAfter co-tenant dedupWith an individual human reply
Resident texts2,3411,2881,007 (78%)
Prospect turns1,0711,071945 (88%)
Resident emails18218247 (26%)
Total3,5942,5411,999

All MEASURED. 41% of raw resident inbound is duplicate copies on a co-tenant's thread. Individual reply = a staff message whose first 120 characters appear on ≤2 distinct threads; anything wider is a broadcast. PII in the 954-row set: 25 phone numbers, 24 email addresses, 39 dollar amounts, 7 family references — small enough for a hand-verified substitution table.

Estimate (method inside)

Replay-ready — an inbound turn that is substantive (more than 3 words, not a bare acknowledgement) and carries an individual human reply: 809 resident texts MEASURED, 47 resident emails MEASURED, and the prospect turns INFERRED by applying the measured 88% answer rate to the non-acknowledgement turns. Total ≈1,502, against 42 rows in today's real-replays-email-sms.yaml.

Detail — coverage gap against our eval suites
Real situationVolumeSuiteVerdict
Rent / balance / payment question148 texts (11.5%)collections-legal.yaml (32), collections-legal-gate.jsonl (90)Covered
Bare confirmation or acknowledgement285 + 410 turnsmass-comms-confirm-reply.jsonl (217), end-conversation-sms.yaml (9)Covered
Prospect asks for a tour129 turns (9.8%)leasing-tours.yaml (73) + 5 tour suitesCovered
Prospect asks availability or price52 turns (3.9%)leasing-specials.yaml, leasing-tools.yamlCovered
Application status45 turns (3.4%)application-status.ts, post-approval.tsCovered
Renewal / move-out / month-to-month79 texts (5.2%)renewals.yaml (88), renewals-sms.yaml (55)Covered
Maintenance — plumbing, leak, water524 WOs (30.5%)maintenance.yaml (43), maintenance-tools.yamlCovered
Maintenance — doors, windows, locks, keys217 WOs (12.6%)words appear; no case turns on itThin
Maintenance — heat, AC, furnace142 WOs (8.3%)"heat" in 14 files; "furnace" in 0Thin
Permission to enter, and rescheduling a no-access visita recurring work-order theme0 hitsMissing
Renter's insurance / $10.50 liability charge31 staff messages0 hitsMissing
Pest-prep non-compliance and the $50 fee78 messages, 57 WOs"pest" in 15 files; nothing on the feeMissing
A question answered only by a blast34 of 205 (17%)broadcast-leak-gate.jsonl (83) tests the opposite bugMissing
Parking, towing, plate call-outs22 texts (1.5%)36 files, all as an amenityThin
Housing-voucher tenancy work4 texts, pervasive in notes17 files, leasing / fair-housing framingThin
Spanish-language inbound258 texts (20%)21 files; no dedicated lane or pass markThin
Neighbour, noise or conduct complaint11 texts; 45% answer ratetenant-resident-services.yaml (8)Thin
Utility outage or shut-off6 texts + the largest email threads3 filesThin

Verdicts come from a read-only grep and case count over 74 dataset files and 60 promptfoo configs. PARTIAL — a suite could cover a situation under wording not searched for.

Detail — unwritten policies staff quoted to residents
RuleValues staff statedCountsConsistent?
Resident referral credit$250 / $50010 / 3No
Renewal bonus$1,000 / $500 / $500 paid twice3 / 2No
Free-rent promotion6 / 8 / 4 / 2 weeks21 / 4 / 2 / 1No
Lockout / lost-key charge$75 / $50 / $150all three in one standing noticeNo
Pet fee7 distinct amountsacross 14 messagesNo
Partial paymentask what they can pay / a signed planboth occurNo
Late fee$50 flat79 of 80Yes
Renter's-insurance substitute$10.50/month29 of 31Yes
Month-to-month fee$150/month12 of 13Yes
Pest-prep non-compliance fee$50, not reversible78 messagesYes
Renewal while a balance is owedaccount must be current firstone clear statementYes
Notice to vacate30 days9 of 10Yes
Entry notice24 hoursquoted from the leaseYes
Deposit turnaroundnot stated in any apartment messageno evidenceUnknown
Off-book personal commitmentsgift cards, a TV, hand-carried leases11 promisesdesign question
Self-correction after an errora plain "please disregard" message17 messagesYes

Counts MEASURED; the consistency column is INFERRED from the spread, since some variation may be legitimate per-property difference. Six rules were quoted at different values to different residents inside the same year: referral credit, renewal bonus, free-rent weeks, lockout charge, pet fee, partial payments.

Detail — human baseline, and what the corpus cannot do
MeasureSitus staff, 2026
Resident texts getting an individual answer78% (1,007 of 1,288)
Never individually answered22%; 6% got no next staff message at all
Reply speed, business hours / after hoursmedian 62 min / 11.6 h
Answered within 15 min / 1 h / 4 h / 24 h34% / 48% / 61% / 77%
Questions left unanswered17% (34 of 205)
Residents chasing an unanswered ask3.2% (49 of 1,514)
Prospect turns answered88%, median 13 min
Inbound emails answered30% (95 of 317)
Work order created → assigned / → completedmedian 0.6 d / 16.5 d
Promise-keepingnot measurable — 11 promises found, delivery almost never recorded

Limits. The phone leaves zero transcripts. Email is one-way: 317 inbound of 42,746, of which 95 got an individual reply, so any email eval rests on 95 rows. 60% of the 943 notes posted this year have no usable body. One client, one market — these are Situs's policies, not portable answers. The human reply is a reference, not a gold answer: 22% of the time there was no answer, and the corpus contains 22 delay apologies. Broadcast detection is a heuristic PARTIAL.

Where these differ from the other sections: the 22.3%-never-answered figure elsewhere uses "any human reply within 14 days"; this 22% uses "an individual reply within the next 3 messages". Quote one definition, not both.

Proposal — sequencing (not measured)

Step one needs no client data and no permission: author roughly 40 cases across the four Missing gaps — entry permission, the insurance and liability charge, the pest-prep fee decision, and a blast swallowing a live question. These are Clara gaps regardless of Situs.

Step two needs no data: turn the 16 policy rows into a decision page for Situs, six of them live contradictions.

Step three is the 120-row replay suite, stratified toward the four Missing and six Thin situations plus 30 Spanish rows and 30 mid-conversation continuations, deduped on timestamp and first 120 characters, scrubbed with a hand-verified substitution table, graded by rubric against a property fact block on a subscription runner. It is the only step gated on the consent answer.

Clara dry run on real Situs conversations — internal

2,118 real 2026 turns replayed through Clara's production prompts (Sonnet 5 drafting, pinned Sonnet 4.6 judge); 2,114 graded, of which 1,636 are on apartments; 56% acceptable. The other 478 rows were graded but sit outside this page's scope. MEASURED

Run 2 loaded a knowledge base built from Situs's own records and the headline did not move: 56% before → 54% → 56%, against a measured noise floor of 0–3 points. No measurable overall gain. What the facts fixed, they paid for elsewhere; what is left over needs live system state, not a document. Detail in Second run, below. MEASURED

Failure mix: missing-fact 541 (33%) · wrong-action 75 (5%) · wrong-fact 64 (4%) · hallucinated-policy 34 (2%) · tone-or-language 11 (1%). The percentage mix is unchanged by the scope cut; only the row counts fall. MEASURED

Weakest areas (n ≥ 30)Rows% acceptableDominant failure
Prospect: access, codes, directions3247%missing-fact
Access, keys, entry permission3053%missing-fact
Prospect: unit features, parking, utilities2544%missing-fact
Prospect: deposit, fees, specials4856%missing-fact
Rent, balance, payment14251%missing-fact
Facts Clara does not haveRows blocked
Live unit availability list with rents and sizes71
Application status and the screening timeline62
Fee schedule: application, admin, deposit, pet, parking58
Tour and office scheduling calendar45
Access: gate and door codes, key pickup, directions29

All MEASURED. A further 225 rows were blocked by one-off facts with no cluster. Acceptable = the judge graded the draft correct or acceptably different from the human reply.

On 425 rows (26%) the human staff reply was itself wrong or contradicted a stable rule. Those are not Clara gaps. MEASURED

A large share of the 34 hallucinated-policy rows trace to one Camellia-specific line in the leasing prompt — a promise to text access instructions about an hour before the tour, true at Camellia and not established at this client. MEASURED

Three replayed turns in full — inbound, human, Clara, verdict

1 · Entry permission and a maintenance revisit — resident, SMS, English

Inbound: "Hello! I tried calling and couldn't get through. Can you come by Monday afternoon?"

Human reply (Assistant Property Manager, 21 minutes): "Hi Noel, sorry we missed your call. Yes, we sure can arrange for Monday afternoon. I will let the technician know. Thank you so much!"

Clara: "Hi Noel, thanks for getting back to us! I'll pass along your request for Monday afternoon to the maintenance team so they can confirm the technician's availability and get this rescheduled. Per the lease, you'll get 24 hours' notice before they come by. If you don't hear confirmation soon, feel free to call the office at 555-0100 during business hours (Mon–Fri, 8am–5pm)."

Verdict — acceptable-different: Clara relays the request but hedges on confirmation; the human confirmed Monday afternoon directly. Both factually clean.

2 · Notice to vacate and a month-to-month fee dispute — resident, SMS, Spanish

Inbound (abridged): "Hola buena tarde estoy escribiendo para dejar constancia que llamé e hice saber q ya no renovaré contrato… me dicen q tenía q avisar con 30 días antes… me dice la chica q como son 5 días después q aviso q tendría q pagar el mes a mes y no estoy d acuerdo."

Human reply (Assistant Property Manager, 63 minutes): "Hola Juan y Ximena, Por favor envíen su aviso formal de que no renovarán su contrato de arrendamiento a leasing@example.com. Una vez lo recibamos, les enviaremos las instrucciones para su mudanza, con la expectativa de que desocupen la unidad a más tardar el 31 de agosto."

Clara: "Ximena, lamento mucho su pérdida y los problemas de salud que ha enfrentado… para que quede oficial en el sistema necesito que envíe su aviso por escrito a leasing@example.com. Sobre el cargo de mes a mes y su desacuerdo con los $150, entiendo su punto, pero esa decisión no la puedo tomar yo — voy a escalar su caso al equipo de la propiedad… Y sobre el depósito: por contrato tienen hasta 30 días para procesarlo y 60 días para la disposición final una vez que se desocupe."

Verdict — acceptable-different: Clara directed written notice correctly, acknowledged the dispute, escalated rather than deciding it, and stated deposit timelines accurately.

3 · Availability and pricing — prospect, SMS, English

Inbound: "I would like information about a one-bedroom apartment"

Human reply (leasing, 66 minutes): "Hi! Thanks for reaching out… Here's a link to one of our available 1-bedroom apartments… We're currently offering 6 weeks free on select units."

Clara: "Hi Rowan! We have a great 1BR/1BA available — 620 sq ft at $1,299/month. It's a cozy, well-priced home close to the RTD stop on W Alameda Ave. Would you like to see it in person? We still have that tour slot open for tomorrow at 11am if you'd like to take it!"

Verdict — acceptable-different, human was wrong: Clara gave accurate unit details and a tour offer; the human stated "6 weeks free", which is NOT ESTABLISHED in the property facts.

Names, phone numbers, email addresses and balances are substituted; the mapping stays on local disk.

Full gap ranking — all 26 topics
TopicRows% acceptableDominant failure
Package / mail thin n633%missing-fact
Prospect: pets thin n1242%missing-fact
Prospect: access / code / directions3743%missing-fact
Access / keys / entry permission7244%missing-fact
Prospect: unit features / parking / utilities3244%missing-fact
Prospect: deposit / fees / specials5749%missing-fact
Rent / balance / payment16950%missing-fact
Prospect: availability / price7650%missing-fact
Prospect: application / status4055%missing-fact
Prospect: qualification / criteria thin n2955%missing-fact
Prospect: not interested / opt-out thin n1155%missing-fact
Renewal / move-out7556%missing-fact
Leasing / apply / tour4356%missing-fact
Maintenance / repair3256%missing-fact
Parking / tow3256%missing-fact
Appointment / scheduling thin n757%missing-fact
Other / mid-conversation continuation45058%missing-fact
Prospect: other / mid-conversation continuation78159%missing-fact
Prospect: tour / showing9259%missing-fact
Prospect: move-in date / lease term thin n1662%missing-fact
Utilities thin n875%wrong-action
Insurance / liability charge thin n875%missing-fact
Pest thin n1479%missing-fact
Neighbour / noise / conduct thin n7100%
Documents / verification thin n3100%
Voucher / housing authority thin n3100%
Missing facts — the data feeds to build
Data Clara needsRows it blocked
Other one-off facts (long tail)225
Live unit availability list with rents and sizes102
Application status and the screening timeline84
Fee schedule: application, admin, deposit, pet, parking70
Tour and office scheduling calendar (staff availability)57
Access: gate and door codes, key pickup, directions46
Sendable links: application, portal, listing22
Vendor, pest and inspection schedules21
Resident ledger line items and charge breakdown17
Current specials and concessions17
Utilities setup and billing detail14

Individual blocking facts named most often: security deposit amount (5 rows), application screening timeline (5), rental application link (4), application approval status (3), Section 8 voucher acceptance policy (3).

Rows where the human reply was wrong — 539 of 2,114 (25%)
TopicHuman-wrong rows
Prospect: other / mid-conversation continuation194
Other / mid-conversation continuation134
Rent / balance / payment39
Prospect: tour / showing24
Access / keys / entry permission17
Parking / tow16
Prospect: deposit / fees / specials15
Prospect: availability / price14
Renewal / move-out12
Prospect: access / code / directions11
Prospect: application / status11
Maintenance / repair10
Pest10
Prospect: unit features / parking / utilities7
Leasing / apply / tour4
Neighbour / noise / conduct4
Prospect: qualification / criteria3
Prospect: pets3
Package / mail · Documents / verification · Appointment / scheduling · Prospect: move-in date / lease term · Insurance / liability charge2 each
Voucher / housing authority1

The human reply is a reference, not a gold answer, which is why every row is graded against the property facts as well as the transcript.

Method, and why missing-fact dominates
  • Clara's model: claude-sonnet-5 on all 2,114 rows, resolved at run time from production resolveDraftParams(channel) in conversation-manager.ts, not hand-picked. Judge: claude-sonnet-4-6, the pinned EVAL_JUDGE_MODEL, so scores stay comparable with the repo's other evals.
  • Prompt read at run time from evals/promptfooconfig-leasing-response.yaml; the persona block is swapped for a resident persona on resident rows.
  • Replay tier: in-process prompt replay. The full-pipeline harness was deliberately not used — its entry point can dispatch a real send, and this is a third party's residents. Nothing was sent.
  • Corpus: 2026-only inbound turns that received an individual, non-broadcast human reply. Co-tenant duplicates removed on timestamp plus first 120 characters; bare acknowledgements removed.
  • Scrubbing: every resident and prospect name in the whole dump — not just the thread's own participants — plus every phone, email and account balance, replaced through a deterministic local substitution table. The mapping stays on local disk and is never committed.
  • Topic tags come from the same deterministic regex taxonomy as the corpus analysis, with no model call, so stratification is exactly reproducible.
  • Property facts were built per property from the AppFolio property directory plus the resident or unit record. Rules staff quote inconsistently — referral credit, renewal bonus, free-rent promotion, lockout charge, pet fee, payment-plan authority — are written as NOT ESTABLISHED on purpose, so a reply that invents a number is caught as a failure. That is why missing-fact is 33%: the fact block was deliberately thin. Run 2 tested the obvious next move — a richer fact block — and it did not shift the headline; see below.
  • Billing: run on the Claude subscription via OAuth. No metered API key was exported at any point; chooseCredential refuses a metered runtime.
  • Cost and time: 40 minutes wall clock for 2,114 rows, two model calls each (draft plus judge). 14,346,910 input tokens, 1,176,898 output.

Second run: with the derived knowledge base

The same 1,625 apartment rows were replayed twice more, each time with a per-property knowledge base built from Situs's own records. Acceptable went 56% before → 54% under A (values staff quote inconsistently left out) → 56% under B (those conflicts resolved to the ledger's modal value). A control re-run that changed nothing at all moved the same measure by 0 points while 16% of individual rows flipped, so the whole range is inside the noise. Read this as no measurable overall gain, not as a small gain. MEASURED

MeasureBeforeA · conflicts left outB · conflicts resolvedB − before
Acceptable56%54%56%+1
Missing fact33%32%30%−3
Wrong fact4%7%7%+3
Hallucinated policy2%1%1%−1
Wrong action5%5%4%0
Wrong tone or language1%1%1%0

Counts behind the headline: 907 of 1,625 acceptable before, 881 under A, 916 under B. Identical rows, identical models, identical judge prompt — the only variable is the facts Clara holds. All MEASURED.

The noise floor. A control run replayed 498 of the same rows under run-1 conditions exactly — no knowledge base, nothing changed. The judge returned the same label on 372 of 498 rows (75%); 40 rows flipped unacceptable → acceptable and 39 flipped the other way, a churn of 16% of rows for a net of 0 points. A headline movement smaller than roughly 0–3 points is not distinguishable from the judge re-rolling. MEASURED

She stopped saying "I don't know" as often. Missing-fact fell 33% → 30%, and 105 rows that had failed on a missing fact became acceptable. The facts were used; they bought back roughly as much as they cost. MEASURED

Wrong-fact rose 4% → 7%, and most of that is run 1 having undercounted. Of the 85 rows newly graded wrong-fact under B, 67 are rows where Clara said the same kind of thing in both runs — the difference is that the knowledge base carries a real vacancy list, so the judge could finally check her. In run 1 the fact block read Other available units and their rents: NOT ESTABLISHED, so an invented unit or rent had nothing to be checked against and passed. MEASURED

The genuinely new failure is small and specific: on 15 rows Clara hedged in run 1 and asserted in run 2 — quoting a stale account balance or a unit detail she would previously have deferred on. Being handed a confident fact block makes her more willing to state per-row data that is itself out of date. That is an argument for marking which fields are live and which are snapshots, not for withholding the knowledge base. MEASURED

Office hours were wrong in run 1. The run-1 property fact block carried Mon–Fri 8am–5pm; the mined staff record says 9:00 AM–5:00 PM, and it says so in all 13 property blocks. On one row the judge marked the human reply wrong for saying 9am–5pm. MEASURED

Missing-fact cluster that survives the knowledge baseRows beforeRows after BClosed
Live unit availability with rents and sizes6852+16
Application status and screening decision for this applicant6148+13
Fee schedule: application, admin, deposit, pet, parking5850+8
The leasing team's live calendar4531+14
Access: gate and door codes, key pickup, meeting point3534+1
Sendable links: application, portal, listing2014+6
Vendor, pest and inspection schedules1718−1
This resident's ledger line items and charge breakdown1625−9
Current specials and concessions116+5
Utilities setup and billing detail1213−1
Voucher / housing-authority case state107+3
This resident's parking space assignment1314−1
This resident's lease document terms45−1
Uncategorised167174−7

What survives is live system state: which unit is vacant today, what this resident owes right now, whether the application is approved, what is on the leasing calendar, which parking space is assigned. A static knowledge base fixes questions with stable written answers — rules, fees, hours, policies — and does nothing for these. They need integrations, not a document. All MEASURED.

Per-topic result — all 26 topics, before vs A vs B

Sorted by B-vs-before change. A topic under 30 rows is marked thin n and is not a headline. Only three topics at n ≥ 30 improved at all, and every one of them sits at or inside the 0–3 point noise floor.

TopicnBeforeABB − beforeMissing-fact before → BWrong-fact before → B
Appointment / scheduling thin n650%50%83%+3333% → 0%0% → 0%
Package / mail thin n633%67%50%+1733% → 17%0% → 0%
Maintenance / repair thin n2458%67%71%+1225% → 17%0% → 4%
Prospect: unit features / parking / utilities thin n2544%60%52%+836% → 28%0% → 0%
Prospect: access / code / directions3247%47%53%+644% → 31%3% → 6%
Other / mid-conversation continuation33857%61%62%+530% → 28%3% → 3%
Rent / balance / payment14251%50%56%+542% → 35%5% → 6%
Prospect: not interested / opt-out thin n540%40%40%060% → 60%0% → 0%
Prospect: availability / price6351%44%51%038% → 27%10% → 21%
Prospect: application / status3557%49%57%037% → 37%0% → 6%
Prospect: qualification / criteria thin n1338%46%38%062% → 54%0% → 0%
Neighbour / noise / conduct thin n6100%100%100%00% → 0%0% → 0%
Parking / tow thin n2650%65%50%050% → 42%0% → 4%
Voucher / housing authority thin n2100%50%100%00% → 0%0% → 0%
Prospect: other / mid-conversation continuation64258%54%57%−131% → 29%3% → 9%
Renewal / move-out4751%57%49%−238% → 40%6% → 6%
Prospect: tour / showing6857%53%54%−322% → 21%10% → 15%
Access / keys / entry permission thin n2955%48%52%−328% → 17%3% → 7%
Prospect: move-in date / lease term thin n1457%50%50%−736% → 36%7% → 7%
Prospect: pets thin n1050%60%40%−1040% → 40%0% → 0%
Leasing / apply / tour thin n2050%45%40%−1030% → 35%10% → 15%
Prospect: deposit / fees / specials4856%38%46%−1042% → 48%0% → 4%
Insurance / liability charge thin n771%57%57%−1429% → 14%0% → 0%
Pest thin n1275%67%58%−1725% → 25%0% → 8%
Utilities thin n450%25%25%−2525% → 75%0% → 0%
Documents / verification thin n1100%0%0%−1000% → 100%0% → 0%

By language: English 1,480 rows — 55% before, 54% A, 56% B. Spanish 145 rows — 59% before, 54% A, 59% B, with wrong-tone-or-language rising 3% → 6% → 9%.

Regressions — rows that were acceptable before and are not now
Fixed (unacceptable → acceptable)Broken (acceptable → unacceptable)Net
A vs before158184−26
B vs before167158+9

What the 158 B regressions became, and where they sit. Remember the control: 39 rows broke with nothing changed at all, so a large share of this list is judge churn rather than damage.

New failureRowsTopicRows
Missing fact66Prospect: other / mid-conversation continuation72
Wrong fact46Other / mid-conversation continuation20
Wrong action28Rent / balance / payment12
Wrong tone or language10Prospect: availability / price9
Hallucinated policy8Prospect: deposit / fees / specials8
Prospect: tour / showing6
Prospect: application / status5
Everything else26

One example of each failure type, with the judge's own words:

  • Wrong factcorrect → wrong-fact: "Clara claimed the date was 'left out of the English version by mistake,' but the English message clearly states 'Tuesday March' — the date was left out entirely, not just from the English version."
  • Missing fact — "Clara couldn't confirm the human's key point that the last proof was outdated/expired, weakening her response compared to the human's."
  • Wrong action — "Clara confused Kai as an existing resident rather than a new applicant and failed to confirm receipt or next steps."
  • Hallucinated policy — "Clara states the portal accepts any amount the resident enters, a claim not established in the property facts."
  • Wrong tone or language — "Resident wrote in Spanish but Clara replied in English, violating the stated policy of answering Spanish-language messages in Spanish."

The full 158-row list for B and the 184-row list for A are in ~/situs-data/analysis/replay/RESULTS-KB.md.

What variant B adds over A — the six values staff quoted inconsistently
TopicWhat B tells ClaraThe competing values it resolves
Resident referral credit$250 for a resident referral, restrictions apply.$500 also circulated in 1,088 messages to 581 residents; $250 is the standing open-house incentive (884 msgs / 477 residents).
Late-fee grace periodLate fees post after the grace period on the lease — 4 days on most leases.AppFolio runs three grace periods side by side: 4 days on 192 leases, 5 on 158, 10 on 29. Staff never state any of them.
Free-rent move-in concessionThe current new-lease concession is 6 weeks free.6 weeks (141 msgs / 88 residents) is modal; 4 weeks (51/41), 8 weeks (13/8) and 2 weeks (3/2) were quoted in the same months.
Renewal bonusThe renewal bonus is $1,000.$1,000 (8 msgs / 5 residents) is modal; $500 (2/2) and $250 (2/2) also appear. Thin evidence — the ledger calls the volume too small to settle.
Application processing timeAn application is decided in 48–72 hours.The most common staff answer was no timeframe at all (22 msgs); among stated timeframes 48–72 h (6) is modal, then 3–5 days (4), 2–3 days (3), 24 hours (2).
Payment plansStaff can arrange a partial payment or a short payment plan; a plan does not stop the delinquency clock.28 of 30 messages on the topic state a plan was offered or arranged; no single authority rule is stated anywhere.

No property-level conflict survived curation: the handful the miner flagged turned out to be one-off statements about a single resident's account, not two standing answers to the same question, so they were dropped rather than resolved. B's addition is exactly these six portfolio rows.

Method, and what the two runs cost
  • Same rows. The exact multifamily row set from run 1, selected by id — 1,625 rows across 16 apartment property records / 397 units. No row was re-selected, re-scrubbed or re-built. Single-family, commercial and placeholder rows excluded.
  • Same models. Subject claude-sonnet-5 at effort high, resolved from production drafting; judge claude-sonnet-4-6 pinned. Same judge prompt, with the knowledge base appended to the facts the judge is told Clara held — without that, a fact she now legitimately knows would be graded as a hallucination.
  • The knowledge base is built only from data already mined: the 23 confirmed stable rules in the policy ledger, the AppFolio unit directory, vacancy detail, itemised rent roll, showings export, and staff statements mined from the message corpus. No new AppFolio access, no network call.
  • Staff statements were filtered to standing facts after the same substitution scrub as the rows — dated closures, outage notices and one-off prorated amounts were dropped, because loading an event as a policy would measure the curation rather than the idea.
  • Block size: 13 per-property blocks, 1,042–1,496 words each (1,636–2,349 tokens), each sent as its own cached system prefix. Summed across every row served that is 3.36 M tokens under A and 3.64 M under B — what it would have cost without caching.
  • The human baseline does not move — it is a property of Situs's 2026 record, not of Clara. The judge flagged the human reply as wrong on 26% of rows before, 28% under A, 29% under B; the human reply never changed, so that drift is the honest noise floor on how precisely the other deltas can be read.
  • Concurrency capped at 8 on one subscription seat; resumable, checkpointed every 25 rows. Nothing was sent to any resident, prospect or member of Situs staff at any point.
RunRowsWall clockInput tokensOutput tokensCache readCache write
Run 1 (before)2,1180.68 h14,346,9101,176,89800
Run 2 · A1,6330.47 h13,482,199698,7764,950,34343,703
Run 2 · B1,6270.49 h13,741,138706,0205,355,62847,648
Run 2 · control (no knowledge base)4990.22 h3,369,863287,72400

All three ran on the Claude subscription seat through OAuth — no metered API key was used or exported at any point. Full detail: ~/situs-data/analysis/replay/RESULTS-KB.md.

Hardcoded Camellia assumptions — internal

70 findings across every prompt Clara loads regardless of property: 9 break at Situs, 32 produce wrong behaviour, 12 are evals only, 17 are already per-property. MEASURED

Read-only sweep of propflowai and the live AppFolio runner. The AppFolio multi-database identity gap is covered on the onboarding hub and is not re-derived here. Severity: P0 blocks go-live, P1 wrong behaviour at Situs, P2 cosmetic or latent.

What it assumesWhat happens at Situsfile:lineSevFix level
Every property that can send has a phone number compiled into source Outbound never scales: getPropertyPhone() falls through to one global TWILIO_PHONE_NUMBER, so all ~55 properties text and call from one shared number and replies misroute. Used at ~20 send sites; the sibling resolvePropertyFromNumber() returns null, so guarded customer-facing sends skip entirely. Inbound already scales off Property.twilioNumbers. domain/properties/phone-lookup.ts:446-481 P0 Code
English copy is acceptable for a resident whose language was already resolved 13 send sites pass englishByProductDecision(), forcing English on application links, renewal offers, work-order confirmations and maintenance ratings. outbound-language-drift.ts:120-158 exempts those ~18 message kinds from the nightly drift alarm. Roughly 70% of Situs resident families are Spanish-speaking. send-application-link.ts:575,724,1083 · send-renewal-email.ts:251 · notify-tenant-of-pms-creation.ts:190 · tech-sms-dispatch.ts:41 P0 Code
Every AppFolio account has lease templates named "Camellia Lease Renewal" and "Camellia Lease" Neither name exists on situsgroup.appfolio.com. The DOM locator misses, the fallback prompt misses, and the flow can click "Prepare Renewal" with the wrong or no template on a real lease. Production-reachable via runRenewal.ts; renewals are phase 2. lib/renewalPhases.ts:1067,1078,1090,1121 (runner) P0 at renewal go-live Prompt variable — multiTenantConfig.ts:66 declares renewalDefault and this code does not read it
One property publishes listings The listings and availability sync is a one-element array pinned to jpco.appfolio.com/listings, so it never runs for any Situs property — the same surface carrying 8 mis-posted units and 103 unadvertised vacancies. domain/leasing/listings-sync.ts:23-26 P0 Data — Property.listingsUrl
Naming a real property as the disambiguation example is harmless The literal reads "e.g., they've been chatting about Camellia before … 'Are you looking to tour Camellia Apartments?'" and sits in the branch that fires only when the property is unknown — the branch a 55-property portfolio hits constantly. agents/clara/lib/agent/clara-leasing.ts:915 P1 Prompt
One phone number is the right destination for a resident asking for a person and for a vendor officePhone || emergencyPhone is the sole transfer_to_number target. No schema exists for a separate maintenance or call-centre line, and the transfer script says only "Let me connect you with someone on the team". No sender role exists for a relay, so a dispatcher reporting for a resident is treated as the resident. api/voice/personalization/route.ts:690 P1 Code — second transfer destination plus a relay sender tier
Every property is in the Denver metro Asset class is decided by propName.includes('yale'), so all 55 Situs properties are graded Class B against Denver benchmarks, Grand Junction included (~250 miles away). The prompt asserts "Yale 25 Station is a Class A asset in Denver" as fact. The same assumption is priced into work orders at market-estimate/route.ts:39. api/property-reports/insights/route.ts:236-244,268-308,482 P1 Data — per-property market and class field
The whole book of business is in Denver "You are Clara … for apartment communities in Denver, CO." This is CLARA_CORE_PERSONALITY, shared across all modes and channels, so every conversation at every property opens on a false premise. Repeated verbatim in three outbound voice prompts: emergency relay, vendor outbound, renewal outbound. agents/clara/lib/agent/clara-personality.ts:83 P1 Prompt-template variable
Corrections to the record — read before actioning anything

propflowai-pms-agentic-layer is a frozen snapshot, last commit 2026-04-14 against the live repo's 2026-09-01. Three findings sourced only from that tree are already fixed and must not be actioned.

Stale claimLive reality
Every channel hardcodes "Always respond in English"clara-unified.ts:1321-1329 carries a bilingual block with a stored-preference ladder and formal usted
Property has no timezone fieldtypes.ts:3308timezone?: string, read at every date call site
A JP founder's email is hardcoded in the auto-reply exemption listauto-reply-guard.ts:258-263 — env-driven, PII removed

agents/clara/lib is a second @/lib/* root: tsconfig.json maps the alias to both src/lib and agents/clara/lib. A sweep scoped to src/lib alone misses the files holding the largest prompt findings. The live runner is ~/.claude/appfolio-browser-agent, audited separately.

Group A and B — the other 33 findings
FindingWhereEffect at Situs
New-lease sends are structurally impossiblelib/newLeasePropertyAllowlist.ts:20["45","7"]Every Situs property throws. Deliberate: enabling a property is a reviewed code change, so this is a planned onboarding step.
The per-account config layer has no backendmultiTenantConfig.tsInMemoryAccountConfigRepo onlyThe fix the lease-template finding depends on has no persistence and no Situs record.
Concession scraping covers zero Situs propertiesscrapers/registry.ts:10-13A static two-element array; the nightly concession watcher walks only Camellia and Yale, so Clara quotes no specials at Situs.
Quiet hours default to Centralproperty-local-date.ts:57-638:00 Central is 7:00 Mountain, so a bulk-imported property with an unset timezone can be texted an hour before the legal window opens. Data fix: set Property.timezone on all 55 at onboarding.
Property-name matching will collidefuzzy-match.ts:68,76 — thresholds 0.4 / 0.15Situs names are addresses. 375 vs 385 S. Depew and 1375 vs 1385 Everett Ct are confirmed collision cases, so forwarded data mail misroutes or is refused.
Situs staff mail counts as vendor spendload-cost-data-core.ts:48The "not a vendor" filter hardcodes jp-co.com and two JP vendor domains; the vendor-name table beside it is Camellia's roster.
Denver vendors suggested for Grand Junctionquotes/web-search-vendors.ts~28 Denver-branded vendors with +1303 numbers fill maintenance quote gaps.
Every Situs vendor write needs an override flagvendorPhoneSet.ts:88Set([1120])Vendor 1120 is JP's test handyman; the guard becomes routine to bypass.
One shared voice fleet with Camellia as defaultspecialists/fleets.ts:48-53Any Situs-specific voice prompt change alters Camellia's live behaviour unless 55 fleets are cloned.
Per-property Slack channels are compiled inobservability/notify.ts:41resolveChannel throws on an unknown key, so any Situs notification needs a code edit.
~30 hardcoded America/Denver literalsclara-personality.ts:11-19 (todayDenver()) and othersClara's "today" takes no property parameter in the prompt composers. Correct for Situs only because all Colorado is Mountain.
A customer's street address in a shared voice promptvendor-outbound.ts:333"1601 Blake Street, Suite 600" is the worked example for saying an address aloud; already on the fence's known-violations list.

Language — the full picture for a ~70% Spanish-speaking portfolio

The conversational lane is bilingual: detection, formal usted, mid-conversation switching, a stored-preference ladder, Spanish maintenance vocabulary with English enums preserved, and sendEmail that throws without a resolved language. The gaps are in templated sends and voice specialist config.

GapWhereEffect
13 resident-facing sends forced to Englishapplication links, renewal offers and recaps, work-order confirmations, maintenance ratings, tour emailsThe majority path at Situs, and exempted from the drift alarm
Prompt says Spanish, config does notmaintenance-handyman, turnover-intake, unknown-callerA mismatch, not a gap: the model is told to speak Spanish while ElevenLabs is never given Spanish ASR/TTS, so transcription stays in the wrong language. unknown-caller is the resident-facing message desk.
English-only by constructionrenewal-outbound, escalation-callback, emergency-relay, vendor-outbound, after-hours-message-deskescalation-callback delivers the answer to a question that may have been asked in Spanish; emergency-relay is the life-safety lane.
After-hours scripts are English literalsafter-hours-message-desk.ts:56,62,68The trigger list carries only English phrasings, so "¿puedo dejar un mensaje?" matches nothing. This is the Situs MVP lane.
Knowledge base is English-onlyi18n/translate.tsTranslation is wired at one call site (tour reminders); every other knowledge fragment reaches a Spanish-preferring resident in English.
No eval covers itwhole eval suiteCoverage is language-detection unit tests plus "PM summary must be English". Nothing verifies Clara answers well in Spanish, and evals/tracked-gaps.md already records Spanish output quality as a tolerated failure.
Group C — evals and tests only (12)

An explicit import-chain check found zero production imports from evals/, fixtures or scripts/: no fixture leaks into a production prompt or seed path.

The eval corpus is Camellia-shaped: 145 Camellia mentions in leasing-response-quality.yaml, 95 in renewals.yaml, 46 in knowledge-grounding-gauntlet.yaml. Two are hard gates rather than context — clara-application-link.yaml asserts contains: "https://www.camelliadenver.com/#floor-plans" deterministically, so 100% of its cases fail for any other property, and leasing-response-quality.yaml:216-249 grades against Camellia's real fee schedule ($38 application, $250/$100/$35 pet, $80/$95 parking). Both need re-authoring, not re-parameterising.

clara-sms.ts and clara-text.ts compose the persona with no language rule, but every importer is a test file — not live.

Three absences: no end-to-end Spanish conversation eval; no multi-property disambiguation eval; no call-centre-mediated intake eval, though every Situs harness models direct tenant-to-Clara contact.

Group D — 17 already handled per property
AreaEvidence
Fees, deposits, pet policy, office hours, holidaysPropertyKnowledge carries typed per-property fields: 17 fee fields, structured pet policy, per-day hours, holiday calendar. No fleet default.
Anti-fabrication guardsclara-leasing.ts:166 — "NEVER INVENT A FIGURE … Silence in the block means UNKNOWN, never zero and never 'standard'"; deposit-default ban at :219; a dedicated fee-fabrication-guard.ts.
Escalation recipientsResolved per property with no hardcoded or env fallback; Clara is separately forbidden from naming a person or address.
Inbound email and phone routingData-driven: recipient and sender address matching, and Property.twilioNumbers with a forced re-read so a new number resolves on its first call.
Voice greetings and dynamic variablesTemplated on {{property_name}} / {{triage_greeting}}; no Camellia literal in any greeting. Missing fields default to empty with "not on file, don't invent"; after-hours fails closed.
New properties inherit nothingNo DEFAULT_KNOWLEDGE constant exists; the clone script requires an explicit source.
The multi-tenancy fencecustomer-identifier-fence.drift.test.ts — 10 fenced identifiers, 21 known violations pinned to exact counts under a ceiling that may only shrink. Its documented gap is scripts/** and bare display names, which is where the two prompt findings above live.
Not reached by this audit
  • The last ~90 lines of the voice personalization route, and full verification of its ~100 dynamic variables.
  • clara-turnover.ts and clara-delivery.ts — checked for Camellia, JP and Denver literals, none found, but not read end to end.
  • Collections, renewal-policy and turnover prompt bodies were sampled rather than read line by line.
  • The ~30 sibling appfolio-browser-agent-* worktrees, and the runner's workflows and discovery module.

All 70 findings with file:line: ~/situs-data/analysis/CAMELLIA-ASSUMPTIONS-AUDIT.md.

Year over year — Jan–Aug 2025 vs Jan–Aug 2026

Both windows are 1 January – 31 August, because the 2026 dump stops at the 2026-09-01 capture. Multifamily apartments only: single-family houses, commercial, placeholders and entity shells are excluded from both years, so the comparison is like-for-like. All 16 apartment properties appear in both years. Sep–Dec 2025 is shown separately as the season 2026 has not reached. MEASURED

AreaMeasureJan–Aug 2025Jan–Aug 2026Sep–Dec 2025Label
RenewalsOffers above / flat / below current rent71.8% / 25.5% / 2.7%16.3% / 51.1% / 32.6%MEASURED
Median dollar change per month+$25$0MEASURED
Expiring leases never worked26.0%33.6%MEASURED
LeasingApartment leads416637153MEASURED
After-hours share of leads24.5%26.7%25.7%MEASURED
Wait for a human — in-hours1.63 h0.15 h1.17 hMEASURED
Wait for a human — after-hours15.1 h15.2 h12.9 hMEASURED
Show rate · leads never contacted48.3% · 11.1%42.5% · 5.2%53.9% · 7.9%MEASURED
VacancyMedian days vacant (move-out → move-in)7662 — a floor99PARTIAL
Units empty more than 180 days5014PARTIAL
Median make-ready days633234PARTIAL
MaintenanceWork orders created2,3182,2771,107MEASURED
After-hours share34.0%28.8%34.5%MEASURED
Median hours create → assign19.83.022.7PARTIAL
Bot-created share of intake8.2%38.4%11.9%MEASURED
Open > 90 days · never assigned14 · 9.3%122 · 18.8%54 · 10.5%PARTIAL
Resident commsOutbound tenant texts3,36020,0952,670MEASURED
Texted tenants who ever replied37.3%49.3%20.1%MEASURED
Median wait for a human reply18.5 h13.6 h19.9 hMEASURED
Inbound never answered in 14 days16.0%17.8%18.3%MEASURED

After hours = outside Mon–Fri 08:00–17:00 America/Denver. The comms population is the union of both dumps — 1,590 unique occupancies — which is the first complete 2025 tenant record; the 2026-only dump was survivor-biased.

Detail — Sep–Dec 2025, the season 2026 has not reached

153 leads · 109 showings scheduled · 51 showings completed · 57 move-ins · 50 move-outs · 1,107 work orders (32% of the year) · 84 renewals effective · 63 applications.

Vacancy was the year's worst: a 99-day median, p75 189 days, and 14 of 49 re-let units (28.6%) empty more than 180 days. Work orders peaked in September (401) and leads bottomed out in November (29). Duplicate work-order rate 12.3%, against 10.8% in Jan–Aug 2025.

Detail — all 20 months, Jan 2025 to Aug 2026
MonthLeadsShowingsCompletedMove-insMove-outsWork ordersWOs after hoursRenewalsApplications
2025-014014643276951222
2025-025529918922072136
2025-034829171010237961539
2025-04342814714289912729
2025-05292213418333892714
2025-066753341914211873729
2025-079684402211315952123
2025-0847432322174371622526
2025-093723812123971353018
2025-1053442913182661073025
2025-11292052510238811511
2025-12342297102065599
2026-0157371912624870420
2026-0259332477212481321
2026-036152211013222651654
2026-04683818912264612019
2026-05945528913286992154
2026-069872502415279852229
2026-07118673915113431172433
2026-0882532712104231102818

Window totals, Jan–Aug 2025 → Jan–Aug 2026: leads 423 → 637 (+50.6%) · showings scheduled 302 → 407 · showings completed 156 → 226 · move-ins 106 → 98 · move-outs 96 → 87 · work orders 2,446 → 2,280 · after-hours work orders 830 → 656 · renewals effective 177 → 149 · applications 188 → 248.

Bolded months are the four 2026 has not reached. Applications come from a report with no property column that sees only applications reaching AppFolio — TurboTenant, Tenant Turner and AffordableHousing.com sit outside it.

Detail — leasing funnel by source
SourceLeads '25Show '25Move-in '25Hours → human '25Leads '26Show '26Move-in '26Hours → human '26
Facebook10176.2%18.8%19.17566.7%16.0%2.9
Zillow2429.2%4.2%0.111143.2%11.7%20.4
Website3737.8%45.9%6.87436.5%20.3%5.6
Drive-by / signage5669.6%21.4%1.54858.3%27.1%0.8
Referral3953.8%56.4%0.05547.3%45.5%0.1
AffordableHousing.com2864.3%21.4%0.35549.1%16.4%0.1
TurboTenant08035.0%7.5%3.8
Zumper437.0%0.0%15.1120.0%0.0%15.2
Rent.com1526.7%0.0%14.93218.8%0.0%16.3
Realtor.com714.3%0.0%22.51833.3%5.6%16.5
Housing Connector1910.5%31.6%0.0250.0%0.0%0.0
Shared app link (not a lead)1711.8%76.5%2.5190.0%78.9%1.4

Move-in rate by arrival, in-hours / after-hours: 25.8% / 23.8% in 2025, 19.7% / 14.1% in 2026. Answered within 1 hour rose 39.3% → 49.3%; waited over 24 hours fell 27.1% → 22.8%.

Detail — the subsidy caveat on renewal pricing

On voucher leases AppFolio prints the tenant's portion in "Previous Rent" and the full contract rent in "Rent", which fakes a $1,000–$3,000 increase. Leases with a previous rent under $600 are dropped: 16 in each window. The DU placeholder removes a further 19 rows in 2025 and 5 in 2026.

Priced leases: 110 of 177 expiring in 2025, 93 of 149 in 2026. Median rent change +1.75% → 0.00%; p25 0.0% → −2.86%. Median among increases +$50 in both years; among decreases −$150 → −$50. Total monthly lift across priced leases $7,510 → $4,640. Outcomes: renewed 66 → 60, month-to-month 72 → 55, did not renew 3 → 7, cancelled by user 36 → 27. Offers sent 188 → 170, accepted 89 → 91, countersigned 78 → 75, reminders 367 → 403.

Renewal lead time is 71 → 72 days on a symmetrical audit-log definition. The 106-day figure quoted elsewhere came from a 2026-only artefact counting any touch including texts; the two are not interchangeable.

Detail — vacancy method and censoring

AppFolio's unit-vacancy report is a snapshot of the capture day and no 2025 version exists, so vacancy is rebuilt from the calendar feed: every move-out is paired with the next move-in at the same unit across the union of both years' feeds. Cohort = move-outs in the window; move-outs with no later move-in are right-censored, excluded from the median and counted separately.

Censoring biases 2026 downward. 34 of 87 Jan–Aug 2026 move-outs have no move-in yet, against 0 of 96 in 2025 — and the censored ones are the long vacancies, so 62 days is a floor. A matched Jan–Jun pair gives 76 → 62 days on 68 and 66 move-outs, still censored at 16.

Vacant over 60 / over 90 days: 72 / 38 in 2025, 29 / 7 in 2026. Mean days 83 → 63. Commercial office, split out and never mixed in: 16 move-outs at a 181-day median in 2025, 19 at 106 days in 2026.

Make-ready is a second, independent measure from the unit-turn report, move-out date to turn end: median 63 → 32 days, p90 104 → 62, turns over 60 days 62 → 9, over the 18-day target 95.8% → 81.9%. It measures getting the unit ready, not re-letting it.

What we cannot compare
  1. Vacancy, occupancy, delinquency and unpaid balances as AppFolio reports them — all are capture-day snapshots with no 2025 version to pull.
  2. Days to complete on maintenance, cleanly. 18.7% of the 2026 cohort has no completion event yet against 7.3% in 2025, so the 2026 median is a floor.
  3. Days vacant, cleanly — 34 of 87 move-outs still censored.
  4. Renewal lead time on the earlier definition — no 2025 equivalent exists.
  5. Three reports have no CSV export in this AppFolio tenant — box score, property performance, tenant transactions summary — missing in both years.
  6. The application funnel outside AppFolio. TurboTenant, Tenant Turner and AffordableHousing.com never enter the applications report in either year.
  7. Labour hours and billed amounts parse empty on work orders in both years.
  8. Phone calls. Neither year has call records; anything that arrived by phone and never became a guest card or work order is invisible in both windows.
  9. Pre-2024 tenant history. Both dumps hold only current tenants plus 2025 and 2026 move-outs; 2025 and 2026 are complete, earlier years are survivor-biased and were not used.
  10. September 2026. 53 work orders and a partial month landed on 2026-09-01 before capture; every window stops at 2026-08-31.

Scripts: yoy_lib.py, yoy_renewals.py, yoy_renewal_process.py, yoy_leasing.py, yoy_vacancy.py, yoy_maintenance.py, yoy_tenant_comms.py, yoy_seasonality.py. 21 tables at ~/situs-data/analysis/tables/yoy_*.csv; full memo at ~/situs-data/analysis/memo-yoy.md.

Method and limits

Detail — definitions, exclusions and corrections carried

Scope. On the apartments: 2,322 work orders, 658 leads, 417 showings, 189 inspections, 61,563 resident communication events, 1,036 resident records, plus the standard reports. The whole database holds 2,588 work orders, 883 leads, 539 showings and 201 inspections; the difference is the houses, the commercial book, the placeholders and the shells. Raw and event-level, never AppFolio's rolled-up summaries, which is why some counts differ from their own reports.

Definitions. Open work order = new, assigned or scheduled as of 1 September. Duplicate candidate = same property and category within a few days, a heuristic and therefore a ceiling. Loop closed = an outbound message to the resident after the completion event. The shared assistant login is a team account used by people and counts as human; PM Assistant, System, Maintenance Performer and Tenant Portal are AppFolio bots; "Customer Service" is the outsourced call centre.

Exclusions. Everything that is not a multifamily apartment property: commercial (5 records, 191 units), single-family houses (20 records, 20 units — the Denver-University-portfolio houses, 446 Galapago, the Ski House), "DO NOT USE" and migration placeholders (3 records, 19 units, 146 work orders, 13 lease expirations), and entity shells, holdings and land (15 records, 19 units). Grand Junction is in a separate database. Three AppFolio reports carry no property column — the 248-application totals, the lead-source yields and the leasing summary — so those stay portfolio-wide and are labelled where they appear.

Do not useUseWhy
285 lease expirations228 on the apartmentsthe rest sat on the placeholder property, the houses and the commercial book
1,104 units, or "345 residential"397 apartment doors / 646 in the databasethe 1,104 count summed the report's total row twice; the 345 came from the occupancy report, which called a Galapago house an apartment and listed Alton as 1 unit of 55
Vacancy median 33 days, or 63 "residential"49 days on apartmentsthe blended figure merged offices and houses into the apartment book
"75% of vacant units unposted"9 of 35 apartmentsthe raw figure is mostly office, parking and a ski house
$3.73M delinquency$670K on the apartments (unverified)82% of it sat on commercial, houses, shells and placeholders, including a $2.81M pair of Greeley commercial rows
Text-failure rate by senderonly the overall 8.2%AppFolio strips the author from a failed message

What this analysis does not claim: that faster answering causes conversion; that any dollar estimate is a forecast; that the phone channel is sized.

Where the data lives

PropFlow Docs