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
MEASURED = counted directly. PARTIAL = a subset, stated. INFERRED = an estimate with its method.
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 class | Records | Units | In scope? |
|---|---|---|---|
| Multifamily apartments | 16 | 397 | Yes — everything on this page |
| Commercial | 5 | 191 | No |
| Single-family houses | 20 | 20 | No |
| "DO NOT USE" / migration placeholders | 3 | 19 | No |
| Company shells, holdings and land | 15 | 19 | No |
| Everything in the database | 59 | 646 |
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.
| Property | Doors | Occupied | % | Vacant-rented | Vacant-unrented | Notice |
|---|---|---|---|---|---|---|
| Alton Apartments | 55 | — | — | — | — | — |
| Barcelona Apartments | 48 | 42 | 87.5 | 6 | 0 | 6 |
| Lampliter | 41 | 36 | 87.8 | 4 | 1 | 5 |
| Carr Street Flats | 34 | 27 | 79.4 | 7 | 0 | 2 |
| Bryant Gardens | 33 | 33 | 100.0 | 0 | 0 | 0 |
| Lowry Flats | 26 | 22 | 84.6 | 4 | 0 | 3 |
| Aspen Leaf | 24 | 21 | 87.5 | 3 | 0 | 5 |
| Mckenzie | 24 | 19 | 79.2 | 5 | 0 | 3 |
| Zephyr | 24 | 19 | 86.4 | 3 | 0 | 4 |
| Cottonwoods | 22 | 21 | 95.5 | 1 | 0 | 1 |
| Olde Town Terrace | 20 | 20 | 100.0 | 0 | 0 | 2 |
| Dahlia Apartments | 12 | 12 | 100.0 | 0 | 0 | 1 |
| Mayor Apartments | 12 | 11 | 91.7 | 1 | 0 | 2 |
| Dexter Apartments | 11 | 10 | 90.9 | 1 | 0 | 0 |
| 6908 Lowell | 6 | 6 | 100.0 | 0 | 0 | 0 |
| Arizona | 5 | 4 | 80.0 | 1 | 0 | 1 |
| Total | 397 | 304 of 341 covered | 89.1% | 35 | 1 | 35 |
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.
Priority was set on 0 of 401 call-centre and 0 of 307 resident-portal tickets, and 100% of staff tickets. MEASURED
| 2026 work orders | Call centre | Portal | Staff | Bots |
|---|---|---|---|---|
| Tickets opened | 401 | 307 | 694 | 917 |
| Arrived after hours or weekend | 36.2% | 46.6% | 14.1% | 33.8% |
| Priority set | 0.0% | 0.0% | 100% | 98.5% |
| Emergency wording, priority blank | 22.9% (92) | 22.6% (80) | 0.0% | 0.3% |
| Linked to a unit | 97.5% | 100% | 78.4% | 45.0% |
| Entry permission answered | 85.8% | 87.0% | 62.5% | 5.1% |
| Description length, median characters | 977 | 641 | 219 | 197 |
| Repeat on same unit within 7 days | 30.4% | 21.2% | 24.4% | 34.0% |
| Re-assigned more than once | 29.9% | 31.6% | 14.7% | 10.7% |
| Edited after creation | 19.2% | 11.0% | 5.9% | 5.2% |
| Median hours to an assignee | 1.0 | 1.0 | 14.2 | 17.9 |
| Median days to finish | 2.6 | 3.4 | 7.2 | 8.1 |
| Still open | 2.2% | 5.4% | 9.1% | 28.1% |
| Open, untouched 30+ days | 0.0% | 1.0% | 8.5% | 15.6% |
| Resident updated the ticket online | 2.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.
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 | Size | Method |
|---|---|---|
| Emergency-worded tickets that are genuine life-safety | ~17/yr | INFERRED — a tenth of the measured 172; the share is an assumption |
| Avoidable rework | 408 duplicate pairs + 48 re-files ≈ 7% of the book | MEASURED, upper bound — heuristic pairing |
| After-hours maintenance a 24/7 agent absorbs | 615 a year ≈ 1.7/day | MEASURED |
| Cost of the AppFolio add-on | ~$7.1K/yr on the apartments | INFERRED — $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
"…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.
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 lands | Leads | Got a human | Median wait | Toured | Moved in |
|---|---|---|---|---|---|
| All | 658 | 623 (95%) | 1.2 h | 43.2% | 18.4% |
| Office hours | 484 | 462 | 33 min | 47.1% | 19.8% |
| After hours | 174 | 161 | 15.5 h | 32.2% | 14.4% |
| Weekends only | 55 | 50 | 29.4 h | 30.9% | 14.5% |
All MEASURED. After hours = outside Mon–Fri 08:00–17:00 Mountain, weekends included.
| Topic | Messages | Share | Never answered by a human |
|---|---|---|---|
| Scheduling a tour (specific times) | 100 | 6.4% | 1 (1.0%) |
| Deposit / fees / payment | 89 | 5.7% | 3 (3.4%) |
| Arrival / en route | 76 | 4.9% | 4 (5.3%) |
| Application status / next steps | 49 | 3.2% | 3 (6.1%) |
| Price / rent amount | 38 | 2.4% | 0 (0.0%) |
| Tour / showing request | 37 | 2.4% | 1 (2.7%) |
| Address / location / area | 30 | 1.9% | 2 (6.7%) |
| Showing confirm / cancel reply | 30 | 1.9% | 2 (6.7%) |
| Income / credit / screening | 19 | 1.2% | 1 (5.3%) |
| Availability / still available | 18 | 1.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.
| Measure | Value | Label |
|---|---|---|
| Prospect messages answered by a human | 95.3%, median 48 min | MEASURED |
| Weekend prospect messages | median 2.1 h | MEASURED |
| Complaint messages with no human reply | 7 of 10 | MEASURED |
| Live threads ending in an unanswered message | 35, of which 1 contains an explicit question | MEASURED — pleasantries filtered from a raw 52; the explicit-question count is the most fragile number on this page |
| Showings, all in-person, none self-guided | 417 | MEASURED |
| Booked ahead / confirmed before the slot | median 28.9 h / 1.9 h | MEASURED |
| Cancelled within two hours of the slot | 47 | MEASURED |
| Confirmation texts sent / one-word replies | 351 / 180 | MEASURED |
| Applications | 1 decided inside 24 h; 6 still pending, oldest opened 30 Jan | PARTIAL — timings from the 67 apartment applications captured in detail |
| Screening completed inside AppFolio | 12 of 248 (4.8%) | PARTIAL — the application report carries no property, so this covers the whole portfolio |
| Zillow / TurboTenant / Zumper / Rent.com → tenants | 239→13 · 115→3 · 20→0 · 40→0 | PARTIAL — the source report carries no property, so this covers the whole portfolio |
| Referrals / drive-bys → tenants | 37.3% / 20.8% | MEASURED |
| Leads that never sent a message back | 295 of 658 (44.8%) | MEASURED |
| Same phone number, different name across leads | 13 cases (22 phones on 44 cards) | MEASURED |
| Median market rent | $1,650 | MEASURED — 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.
| Gap | Volume | Per year | Method |
|---|---|---|---|
| After-hours leads answered in minutes | +16.6 move-ins | $27,390 | after-hours cohort converting like the fast business-hours cohort × one month's rent |
| Leads with no human contact | 35 | $9,933 | 35 × the business-hours move-in rate × one month's rent |
| Unanswered live prospect threads | 35 | $9,933 | same method |
| Rent-ready homes not listed | 7 units / 331 idle days | $17,965 | 331 ÷ 30.4 × $1,650 |
| Total | $65,221 | INFERRED 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.
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.
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 leases | Leases | Share |
|---|---|---|
| Below current rent | 41 | 36.9% |
| Flat | 60 | 54.1% |
| 0–3% increase | 5 | 4.5% |
| 3–6% increase | 5 | 4.5% |
| Above 6% | 0 | 0% |
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."
| Measure | Value | Label |
|---|---|---|
| Expiring Sep 2026 – Mar 2027 with no renewal contact since 1 May | 43 of 107 (40%) | PARTIAL |
| 2026 leases rolling to month-to-month | 64 of 214 (29.9%) | MEASURED |
| Renewed / cancelled by user / did not renew | 77 / 35 / 7 | MEASURED |
| Tenants with no lease end date | 25, $33,160/mo; 13 month-to-month since 2022 or earlier | MEASURED |
| Terms offered across the year | 12-month 219, month-to-month 215, one 6-month | MEASURED |
| Touches per renewal | median 9, max 63; 2,293 across 250 leases | MEASURED |
| Median days from first renewal touch to lease end | 106 (p25 71, p75 120) | MEASURED |
| Offers sent / accepted / countersigned / cancelled | 355 / 204 (57%) / 163 / 91 | MEASURED |
| Automated reminder emails | 827 = 2.3 per offer | MEASURED |
| Individually written discount offers | 82 across 54 tenants: $250 ×14, $500 ×13, $1,000 ×9 | MEASURED |
| Their authors | Deiby 29, Lee 17, shared VA login 16 — no principal writes one | MEASURED |
"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.
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.
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 order | Work orders with real content | Showing AppFolio's empty placeholder |
|---|---|---|
| Technician labour | 949 | 1,373 |
| Purchase orders | 0 | 2,322 |
| Invoices | 17 ($2,510.13) | 2,305 |
| Tenant-billback charge lines | 370, all $0.00 | — |
| Vendor bills | 153 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.
| Category | Work orders | From recategorization |
|---|---|---|
| Plumbing / Drain | 496 | 48 |
| Turn / Make-ready | 400 | 5 |
| Appliance | 263 | 11 |
| HVAC | 211 | 21 |
| Common area / Laundry | 167 | 93 |
| Exterior / Grounds | 166 | 66 |
| Pest | 162 | 38 |
| Doors / Locks / Keys | 156 | 7 |
| Electrical | 141 | 24 |
| Other / Uncategorized | 70 | 70 |
| Windows | 42 | 0 |
| Inspection — new category | 35 | 35 |
| Safety / Compliance | 10 | 9 |
| Filters / Recurring PM | 3 | 1 |
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.
| Category | Staff | Call centre | Portal | Bots | Other | Total |
|---|---|---|---|---|---|---|
| Plumbing / Drain | 132 | 174 | 116 | 73 | 1 | 496 |
| Turn / Make-ready | 155 | 8 | 8 | 229 | 0 | 400 |
| Appliance | 109 | 76 | 35 | 43 | 0 | 263 |
| HVAC | 53 | 42 | 42 | 73 | 1 | 211 |
| Common area / Laundry | 22 | 4 | 4 | 137 | 0 | 167 |
| Exterior / Grounds | 24 | 10 | 6 | 126 | 0 | 166 |
| Pest | 26 | 11 | 21 | 104 | 0 | 162 |
| Doors / Locks / Keys | 62 | 33 | 30 | 31 | 0 | 156 |
| Electrical | 62 | 22 | 22 | 35 | 0 | 141 |
| Other / Uncategorized | 19 | 11 | 13 | 27 | 0 | 70 |
| Windows | 8 | 7 | 8 | 19 | 0 | 42 |
| Inspection | 21 | 1 | 0 | 13 | 0 | 35 |
| Safety / Compliance | 1 | 0 | 2 | 6 | 1 | 10 |
| Filters / Recurring PM | 0 | 2 | 0 | 1 | 0 | 3 |
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).
| Measure | Value |
|---|---|
| Open · median age · p90 | 346 · 26 days · 160 days |
| Open past 30 / 60 / 90 / 180 days | 145 / 102 / 72 / 19 |
| Completed jobs with a message to the resident afterwards | 3 of 1,884 |
| Monthly volume Jan → Aug | 248 → 423, up 71% across the eight months |
| Median days to finish: Urgent / Normal / blank priority | 3.7 / 9.3 / 2.8 |
| Median days to finish: in-house vs outside vendors | 4.0 vs 20–39 |
| Open tickets with no vendor assigned | 186 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.
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.
123 of 189 inspections are still marked in progress, and the 310 work orders they generated carry $0.00 invoiced. MEASURED
| 2026 inspections | Value |
|---|---|
| Captured | 189 |
| In progress / done / new / blank | 123 / 17 / 5 / 44 |
| Occupied checks / move-out scopes / other | 100 / 80 / 9 |
| Work orders generated · still open | 310 · 168 (54%) |
| Invoiced · labour logged against them | $0.00 · 6.0 h |
| Concentrated in Feb–Mar | 50 + 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.
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.
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
| Cut | Vacant | Median days | p90 | Not rent-ready | Not advertised |
|---|---|---|---|---|---|
| Multifamily apartments — in scope | 35 | 49 | 195 | 19 | 9 |
| Single-family houses — excluded | 5 | 64 | 782 | 3 | 3 |
| Commercial and shells — excluded | 66 | 124 | 1,386 | 34 | 66 |
| Placeholders — excluded | 19 | 1,527 | 1,890 | 11 | 19 |
| Blended — do not quote | 125 | 91 | 1,539 | 67 | 97 |
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.
| Cut | Forgone to date | Per 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.
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
59 of 92 turnovers (64%) missed their own target date; the median takes 32 days. MEASURED
| Days to complete | Turnovers |
|---|---|
| 0–14 | 7 |
| 15–30 | 26 |
| 31–60 | 30 |
| 61–90 | 6 |
| 90+ | 3 |
| No end date | 20 |
All MEASURED. 123 rows, 92 of them multifamily; median and p90 (62, max 151) computed over the 72 rows carrying a completed duration.
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.
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.
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
| Measure | Value |
|---|---|
| Captured resident events in the window | 61,563 — email 28,356 · texts 21,785 · lease and audit 10,632 · notes 790 |
| Residents who texted back at least once | 422 of 1,036 (40.7%) |
| Residents who sent an email in | 11.2%; 151 have no captured contact at all |
| Inbound texts arriving outside Mon–Fri 8–5 | 459 (18.9%) |
| Worst day of the week | Wednesday, median 19.4 h (Thursday 19.1 h, Sunday 19.0 h) |
| p90 wait for a reply | 6.2 days |
| Outbound texts containing Spanish | 8,357 (43.2%), reaching 698 residents — 67% of them |
| Of those, bilingual blasts | 76% |
| Inbound texts in Spanish | 212 of 2,429 |
| Reply to a Spanish message: Spanish / English / none | 58% / 25% / 17% |
| Resident records carrying any language tag | 191 of 729 (26%) — 101 English, 90 Spanish |
| Spanish-flagged outbound emails | 9,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.
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
Residents and corporate accounts at the apartments owe $670,223 across 305 accounts. MEASURED
| Who owes it | Accounts | Amount | Share |
|---|---|---|---|
| Residents | 222 | $441,466 | 65.9% |
| Company-named accounts | 83 | $228,757 | 34.1% |
| Total, apartments | 305 | $670,223 | 100% |
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).
| Last payment | Accounts | Amount |
|---|---|---|
| Within 1 month | 267 | $492,133 |
| Never recorded | 14 | $62,970 |
| 3–12 months ago | 4 | $62,111 |
| 1–3 months ago | 20 | $53,009 |
| Over 12 months ago | 0 | $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.
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 Tags | 521 | 71.5% |
| Phone numbers | 249 | 34.2% |
| Emails | 265 | 36.4% |
| Lease end date | 50 | 6.9% |
| Unit / tenant / status / type / move-in / rent / deposit | 1 each | 0.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.
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
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.
"~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.
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.
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*.
| Topic | Variants | People affected | Who | Note |
|---|---|---|---|---|
| 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.
| # | Fact | Evidence (2026) | Scope |
|---|---|---|---|
| 1 | Late 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. |
| 2 | Returned-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. |
| 3 | No 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. |
| 4 | Key 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. |
| 5 | A 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. |
| 6 | Pets: $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. |
| 7 | Month-to-month costs $150 a month on top of rent. | 89 messages to 60 residents, 4 staff, 8 properties. | Portfolio-wide. |
| 8 | Notice to vacate is 30 days, in writing. | 7 messages to 7 residents; one value only. | Portfolio-wide. |
| 9 | Entry 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. |
| 10 | Rent 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. |
| 11 | No response to a renewal offer rolls the lease to month-to-month at the $150 premium. | 92 messages to 62 residents. | Portfolio-wide. |
| 12 | Vehicles 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. |
| 13 | No 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. |
| 14 | After 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. |
| 15 | Maintenance requests are submitted through the resident portal. | 1,457 messages to 288 residents; one message offers text or email instead. | Portfolio-wide. |
| 16 | Pest 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. |
| 17 | Showings are confirmed by replying CONFIRM or DENY before a stated cut-off. | 719 messages to 399 prospects. | Portfolio-wide. |
| 18 | Offices 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. |
| 19 | Residents 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. |
| 20 | When staff get something wrong they send a plain correction. | 304 self-corrections to 220 residents. | Portfolio-wide. |
| 21 | Quiet 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. |
| Topic | Variant | Msgs | People | Who | Verdict |
|---|---|---|---|---|---|
| Resident referral credit | $500 | 1,088 | 581 | Deiby Magana (1,078); unnamed (10) | Genuine inconsistency — residents received both figures. No captured document names a referral credit |
| Resident referral credit | $250 | 884 | 477 | Deiby Magana (871); unnamed (12); Lee McKibbin (1) | Genuine inconsistency — same person, 12 shared properties, overlapping weeks |
| NSF fee — spoken vs system | AppFolio: $0.00 (413), $50.00 (49), blank (574) | — | 462 | AppFolio lease settings | System contradicts staff — the lease says $50, so staff match the lease and the config is the outlier |
| NSF fee — spoken vs system | Staff quote $50 | 22 | 18 | Assistant Lead, Miriam Gallegos, unnamed | System has $0.00 on 413 leases, $50.00 on 49; the lease says $50 |
| Late fee — spoken vs system | Five schemes side by side in AppFolio | — | 379 | AppFolio lease settings, effective 02/2021 to 11/2025 | 259 of 379 apartment leases are not on the $50 scheme; many also accrue $5.00/day with no cap |
| Late fee — spoken vs system | Staff quote a flat $50 to everyone | 168 | 77 | Assistant Lead, Miriam Gallegos, Courtney Tolentino, unnamed | Biggest 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 only | After 5 days (158), 4 days (192), 10 days (29) | — | 379 | AppFolio lease settings | Three grace periods side by side; staff state none of them. Every lease says a 7-day grace, rent due the 3rd |
| Free-rent concession | 6 weeks | 141 | 88 | Assistant Lead (69); Deiby Magana (44); Miriam Gallegos (10); Lee McKibbin (10) | Genuine inconsistency |
| Free-rent concession | 4 weeks | 51 | 41 | Deiby Magana (20); Assistant Lead (10); Lee McKibbin (9); Miriam Gallegos (5) | Genuine inconsistency |
| Free-rent concession | 8 weeks | 13 | 8 | Assistant Lead (9); Deiby Magana (4) | Genuine inconsistency |
| Free-rent concession | 2 weeks | 3 | 2 | Courtney Tolentino (3) | Genuine inconsistency — 3 residents quoted two lengths |
| Utility bill-backs — spoken vs system | Staff bill utilities back in 26 messages | 26 | 11 | Miriam Gallegos, Assistant Lead | RUBS billing is set to No on all 1,036 apartment resident records — computed outside the system of record |
| Month-to-month premium | $150 | 84 | 56 | Courtney Tolentino (63); Miriam Gallegos (9); unnamed | $150 is the rule |
| Month-to-month premium | $1 | 1 | 1 | Deiby Magana (1) | Not a second policy — a per-unit rent figure caught by the pattern |
| Application processing time | No timeframe given | 22 | 16 | Courtney Tolentino (19); Deiby Magana (3) | Genuine inconsistency — the most common answer is no timeframe at all |
| Application processing time | 48–72 hours | 6 | 4 | Courtney Tolentino (4); Deiby Magana (2) | Genuine inconsistency |
| Application processing time | 3–5 days | 4 | 3 | Deiby Magana (4) | Genuine inconsistency |
| Application processing time | 2–3 days | 3 | 2 | Lee McKibbin (3) | Genuine inconsistency |
| Application processing time | 24 hours / next day | 2 | 2 | Miriam Gallegos (2) | Four different answers from four agents in the same months |
| Renewal bonus | $1,000 | 8 | 5 | Assistant Lead (4); Miriam Gallegos (2); Deiby Magana (2) | The Renewal Notice Letter states $1,000 paid as 2 × $500 — the written answer |
| Renewal bonus | $500 | 2 | 2 | Lee McKibbin (1); Deiby Magana (1) | Written amount is $1,000 as 2 × $500 |
| Renewal bonus | $250 | 2 | 2 | Deiby Magana (2) | Written amount is $1,000 as 2 × $500 |
| Pet fee | $35 | 5 | 4 | Deiby Magana (3); Lee McKibbin (2) | Not a conflict — $35 is monthly pet rent |
| Pet fee | $300 | 6 | 4 | Lee McKibbin (3); Courtney Tolentino (3) | Not a conflict — $300 is the refundable deposit |
| Certified funds — spoken vs system | Staff demand certified funds in 2 messages | 2 | 2 | Deiby Magana | Certified Funds Only is set to No on all 1,036 apartment resident records |
| Application fee | Staff: none / $0 | 2 | 1 | one author, Carr Street Flats | Four published answers. One staff message says "we do not collect or receive those fees directly" — likely the application platform's own fee |
| Application fee | Public listings: $45.00 per adult | — | 29 listing pages | Marketing | The advertised figure |
| Application fee | Arizona AppFolio listing text: $31.00 | — | 1 property | Marketing | A third figure on their own listing |
| Application fee | Leases: silent | — | 195 documents | Lease documents | No lease names an application fee at all |
| Balance blocks renewal | Staff: account must be current first | 4 | 4 | — | No lease and no renewal letter states this condition — a renewal withheld on a rule nothing in writing supports |
| Topic | Rule as observed | Volume | Label |
|---|---|---|---|
| Late fee | A 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 people | MEASURED |
| Rent grace period / due date | Staff 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 people | PARTIAL |
| NSF / returned-payment fee | A returned payment costs $50, applied to the account, with a request to bring the balance current. | 47 msgs · 34 people | MEASURED |
| Renter's insurance / landlord-liability charge | A 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 people | MEASURED |
| Lockout / lost-key / key-replacement charge | A 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 people | MEASURED |
| Pest-prep / failure-to-prepare / denied-access fee | A 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 people | MEASURED |
| Pet fee / pet deposit / pet rent | A pet costs a $300 refundable deposit plus $35 a month in pet rent, added to the monthly total. | 2,208 msgs · 662 people | MEASURED |
| Application fee | There is no application fee. | 18 msgs · 10 people | PARTIAL |
| Month-to-month premium | Staying past the lease end on a month-to-month basis costs $150 a month on top of rent. | 214 msgs · 142 people | MEASURED |
| Resident referral credit | Residents 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 people | MEASURED |
| Renewal bonus / renewal credit | Some 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 people | PARTIAL |
| Free-rent concession on a new lease | New 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 people | MEASURED |
| Security deposit amount | The 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 people | MEASURED |
| Security-deposit return timeline | No 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 evidence | PARTIAL |
| Notice to vacate | A written 30-day notice is required, listing every leaseholder and the move-out date, submitted through the portal. | 17 msgs · 12 people | MEASURED |
| Entry notice before maintenance | 24 hours' notice before entering, and staff state the entry is happening rather than asking. | 27 msgs · 23 people | PARTIAL |
| Payment method allowed | Pay 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 people | MEASURED |
| Partial payments & payment plans | Two 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 people | MEASURED |
| Balance blocks renewal | A resident must bring their account current before a renewal will be offered. | 4 msgs · 4 people | PARTIAL |
| Eviction / legal escalation threshold | Delinquency 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 people | MEASURED |
| Collections / delinquency outreach steps | The sequence is a balance reminder first, a late-fee notice second, and demand or eviction language last. | 609 msgs · 275 people | MEASURED |
| Parking & towing enforcement | Vehicles 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 people | MEASURED |
| Trash / bulk item / dumpster rules | Household trash goes in the dumpster, bagged; furniture, mattresses and other bulk items must not be left there. | 3,722 msgs · 862 people | MEASURED |
| Smoking | Smoking indoors is prohibited and is handled as a lease violation; marijuana is called out by name. | 59 msgs · 48 people | MEASURED |
| Guests & unauthorized occupants | An unauthorised occupant is a lease violation; anyone living in the unit must apply and be screened. | 35 msgs · 28 people | MEASURED |
| Unit transfer | Moving to another unit requires a new lease or a new application; a cost is mentioned once. | 16 msgs · 15 people | PARTIAL |
| Lease break / early termination | A 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 people | PARTIAL |
| Emergency definition & after-hours handling | Emergencies 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 people | MEASURED |
| Maintenance request intake channel | Requests go through the resident portal. | 1,750 msgs · 421 people | MEASURED |
| Work-order timing promise | There 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 people | MEASURED |
| Permission to enter when resident is absent | Staff 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 people | PARTIAL |
| Pest treatment compliance | The 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 people | MEASURED |
| Inspections | Annual or routine inspections are announced in advance; move-in, move-out and housing-authority inspections are handled separately. | 2,123 msgs · 742 people | MEASURED |
| Housing vouchers / Section 8 / DHA | Vouchers 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 people | MEASURED |
| Application screening criteria | Applications 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 people | PARTIAL |
| Co-signer / guarantor | An approval can be made conditional on adding a co-signer; the co-signer applies and is screened separately. | 15 msgs · 6 people | PARTIAL |
| Holding deposit / holding a unit | A deposit is required to hold a unit off the market. | 20 msgs · 11 people | PARTIAL |
| Tours & showings | Showings 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 people | MEASURED |
| Move-in requirements | Move-in funds must be paid before keys, and utilities must be transferred into the resident's name. | 34 msgs · 25 people | PARTIAL |
| Move-out & turn charges | The unit is expected back clean, with all keys returned, and cleaning, carpet and damage costs come out of the deposit. | 4 msgs · 3 people | PARTIAL |
| Utilities & RUBS billing | Commercial 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 people | MEASURED |
| Renewal offer mechanics | An 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 people | MEASURED |
| Rent increase at renewal | A 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 people | MEASURED |
| Office hours & closures | Weekday business hours are published; offices close for public holidays and reopen the next business day; emergency maintenance stays available throughout. | 5,475 msgs · 792 people | MEASURED |
| 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 people | MEASURED |
| Application processing time promised | Prospects 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 people | MEASURED |
| Noise, conduct & quiet enjoyment | Quiet 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 people | MEASURED |
| Self-correction after a wrong statement | When staff send something wrong, they follow it with a plain correction asking residents to disregard the previous message. | 95 msgs · 83 people | MEASURED |
| Off-book personal commitment by staff | Staff make personal commitments outside any system - dropping off a gift card, delivering a TV, reversing a late fee, applying a credit. | 83 msgs · 57 people | MEASURED |
| Topic looked for | What was found |
|---|---|
| Subletting / short-term rental | Zero messages in 2026. |
| How long a guest may stay before joining the lease | Zero messages state a number of days. Staff say only that anyone staying must be added and screened. |
| Income requirement | One application denial cites a "2x rent income requirement". Nothing else states a multiple. |
| Minimum credit score | Six messages mention credit; none states a threshold. |
| Minimum renter's-insurance coverage | Zero messages state a coverage limit, only the $10.50 charge when no policy is on file. |
| Daily late-fee accrual | AppFolio 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 date | Zero 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-out | 68 messages contain prorated figures; none states the rule used. |
| Work-order service-level promise | No standing SLA is ever stated. Timing is promised case by case. |
| Renewal notice period | Six messages mention 60 or 90 days, all about applications or rent increases. |
| Security-deposit deduction schedule | Five move-out messages in all of 2026. No price list, no standard turn charges. |
| Pool, fitness or clubhouse rules | Zero messages. These amenities do not appear in the record. |
| Alterations, painting, satellite dishes | Six messages, none stating a rule. |
| Snow and ice removal responsibility | 11 messages, none stating who is responsible. |
| Eviction threshold | 910 messages use eviction or attorney language; none states the trigger. Three mention a 10-day demand. |
| Written lease, addendum or house rules | None 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 properties | 10:00 PM to 8:00 AM appears in 123 messages, but only inside two portfolio blasts. |
~/situs-data/analysis/POLICY-LEDGER.md. Tables under ~/situs-data/analysis/tables/policy_*.csv.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
| Rule | What the lease says | What staff say | What 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 everyone | Five 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 fee | Blank — 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 August | Renters-insurance module off at company level |
| Renewal credit | Renewal Notice Letter: $1,000 paid as 2 × $500, 60-day notice | $1,000 / $500 / $250 | — |
| Month-to-month premium | $150/month | $150/month | — |
| Deposit disposition | Returned within 60 days, itemised | "30 to 60 days"; one agent splits 30 to process, 60 to issue | — |
| Holdover | 2× daily rent | Never 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.
| Document | Properties | Documents | Key values it states |
|---|---|---|---|
| Residential lease (four live forms) | 15 of 16 executed | 195 / 171 complete | Late 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 rules | 15 | 157 (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 addendum | 15 | 157 | Criminal activity by tenant, household, guest or anyone under their control is grounds for eviction |
| Pest Control addendum | 15 | 157 | Treatment 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 addendum | 15 | 157 | Tenant duty to ventilate and report; landlord remediation process |
| Colorado Radon Disclosure | 15 | 156 | Statutory disclosure |
| Lead-Based Paint · Asbestos disclosures | 14 | 148 each | Statutory disclosures |
| Parking addendum | 13 | 131 | Numbered spaces · fee $0 in most leases · towing at owner's expense without notice · no repairs, no RV or boat |
| Tobacco & Marijuana Smoking addendum | 13 | 129 | No smoking inside or within 10 feet of an entrance · no cultivation |
| Move-in / Move-out Inspection Checklist | 15 | 87 (45%) | Checklist returned within 72 hours; silence is binding acceptance of the unit's condition |
| Jury Trial Waiver & Attorney Fee Cap | 10 | 42 | Jury-trial waiver; attorney-fee cap |
| Insurance addendum | 7 | 23 | Proof due within 30 days of move-in; failure triggers auto-enrolment in a landlord-liability policy |
| Pet addendum · ESA / Assistance Animal | 7 · 3 | 16 · 5 | No animal without prior written consent · landlord may prohibit breeds · $300 deposit + $35/mo (listings) |
| Storage Unit · Appliance · Exterior Yard | 3 · 1 · 1 | 4 · 2 · 2 | Unit-specific terms |
| Property Documents tab | 10 of 16 have any file | 83 | No policy content: 68 police incident reports, 5 parking or unit maps, 2 insurance certificates, 1 trash-day sheet, 2 photos |
| Public listings | — | 29 pages | Application 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 settings | 106 property records | 10 captures | Online 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.
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.
| Property | Doors | Occupancies with an executed lease | Lease documents | Property-tab files |
|---|---|---|---|---|
| Alton Apartments | 55 | 0 | 0 | 4 |
| Barcelona Apartments | 48 | 8 | 9 | 1 |
| Lampliter | 41 | 10 | 12 | 10 |
| Carr Street Flats | 34 | 8 | 8 | 7 |
| Bryant Gardens | 33 | 5 | 5 | 0 |
| Lowry Flats Apartments | 26 | 8 | 9 | 1 |
| Aspen Leaf | 24 | 7 | 11 | 0 |
| Mckenzie | 24 | 5 | 5 | 6 |
| Zephyr | 23 | 11 | 20 | 51 |
| Cottonwoods | 22 | 14 | 33 | 0 |
| Olde Town Terrace | 20 | 8 | 22 | 0 |
| Dahlia Apartments | 12 | 7 | 18 | 1 |
| Mayor Apartments | 12 | 6 | 12 | 1 |
| Dexter Apartments | 11 | 6 | 15 | 1 |
| 6908 Lowell LLC | 6 | 4 | 4 | 0 |
| Arizona | 5 | 2 | 6 | 0 |
| Total | 397 | 109 | 195 | 83 |
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.
1,999 real inbound turns carry an individual human reply. Our only existing real-conversation eval holds 42 rows. MEASURED
| Channel | Inbound turns | After co-tenant dedup | With an individual human reply |
|---|---|---|---|
| Resident texts | 2,341 | 1,288 | 1,007 (78%) |
| Prospect turns | 1,071 | 1,071 | 945 (88%) |
| Resident emails | 182 | 182 | 47 (26%) |
| Total | 3,594 | 2,541 | 1,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.
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.
| Real situation | Volume | Suite | Verdict |
|---|---|---|---|
| Rent / balance / payment question | 148 texts (11.5%) | collections-legal.yaml (32), collections-legal-gate.jsonl (90) | Covered |
| Bare confirmation or acknowledgement | 285 + 410 turns | mass-comms-confirm-reply.jsonl (217), end-conversation-sms.yaml (9) | Covered |
| Prospect asks for a tour | 129 turns (9.8%) | leasing-tours.yaml (73) + 5 tour suites | Covered |
| Prospect asks availability or price | 52 turns (3.9%) | leasing-specials.yaml, leasing-tools.yaml | Covered |
| Application status | 45 turns (3.4%) | application-status.ts, post-approval.ts | Covered |
| Renewal / move-out / month-to-month | 79 texts (5.2%) | renewals.yaml (88), renewals-sms.yaml (55) | Covered |
| Maintenance — plumbing, leak, water | 524 WOs (30.5%) | maintenance.yaml (43), maintenance-tools.yaml | Covered |
| Maintenance — doors, windows, locks, keys | 217 WOs (12.6%) | words appear; no case turns on it | Thin |
| Maintenance — heat, AC, furnace | 142 WOs (8.3%) | "heat" in 14 files; "furnace" in 0 | Thin |
| Permission to enter, and rescheduling a no-access visit | a recurring work-order theme | 0 hits | Missing |
| Renter's insurance / $10.50 liability charge | 31 staff messages | 0 hits | Missing |
| Pest-prep non-compliance and the $50 fee | 78 messages, 57 WOs | "pest" in 15 files; nothing on the fee | Missing |
| A question answered only by a blast | 34 of 205 (17%) | broadcast-leak-gate.jsonl (83) tests the opposite bug | Missing |
| Parking, towing, plate call-outs | 22 texts (1.5%) | 36 files, all as an amenity | Thin |
| Housing-voucher tenancy work | 4 texts, pervasive in notes | 17 files, leasing / fair-housing framing | Thin |
| Spanish-language inbound | 258 texts (20%) | 21 files; no dedicated lane or pass mark | Thin |
| Neighbour, noise or conduct complaint | 11 texts; 45% answer rate | tenant-resident-services.yaml (8) | Thin |
| Utility outage or shut-off | 6 texts + the largest email threads | 3 files | Thin |
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.
| Rule | Values staff stated | Counts | Consistent? |
|---|---|---|---|
| Resident referral credit | $250 / $500 | 10 / 3 | No |
| Renewal bonus | $1,000 / $500 / $500 paid twice | 3 / 2 | No |
| Free-rent promotion | 6 / 8 / 4 / 2 weeks | 21 / 4 / 2 / 1 | No |
| Lockout / lost-key charge | $75 / $50 / $150 | all three in one standing notice | No |
| Pet fee | 7 distinct amounts | across 14 messages | No |
| Partial payment | ask what they can pay / a signed plan | both occur | No |
| Late fee | $50 flat | 79 of 80 | Yes |
| Renter's-insurance substitute | $10.50/month | 29 of 31 | Yes |
| Month-to-month fee | $150/month | 12 of 13 | Yes |
| Pest-prep non-compliance fee | $50, not reversible | 78 messages | Yes |
| Renewal while a balance is owed | account must be current first | one clear statement | Yes |
| Notice to vacate | 30 days | 9 of 10 | Yes |
| Entry notice | 24 hours | quoted from the lease | Yes |
| Deposit turnaround | not stated in any apartment message | no evidence | Unknown |
| Off-book personal commitments | gift cards, a TV, hand-carried leases | 11 promises | design question |
| Self-correction after an error | a plain "please disregard" message | 17 messages | Yes |
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.
| Measure | Situs staff, 2026 |
|---|---|
| Resident texts getting an individual answer | 78% (1,007 of 1,288) |
| Never individually answered | 22%; 6% got no next staff message at all |
| Reply speed, business hours / after hours | median 62 min / 11.6 h |
| Answered within 15 min / 1 h / 4 h / 24 h | 34% / 48% / 61% / 77% |
| Questions left unanswered | 17% (34 of 205) |
| Residents chasing an unanswered ask | 3.2% (49 of 1,514) |
| Prospect turns answered | 88%, median 13 min |
| Inbound emails answered | 30% (95 of 317) |
| Work order created → assigned / → completed | median 0.6 d / 16.5 d |
| Promise-keeping | not 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.
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.
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 | % acceptable | Dominant failure |
|---|---|---|---|
| Prospect: access, codes, directions | 32 | 47% | missing-fact |
| Access, keys, entry permission | 30 | 53% | missing-fact |
| Prospect: unit features, parking, utilities | 25 | 44% | missing-fact |
| Prospect: deposit, fees, specials | 48 | 56% | missing-fact |
| Rent, balance, payment | 142 | 51% | missing-fact |
| Facts Clara does not have | Rows blocked |
|---|---|
| Live unit availability list with rents and sizes | 71 |
| Application status and the screening timeline | 62 |
| Fee schedule: application, admin, deposit, pet, parking | 58 |
| Tour and office scheduling calendar | 45 |
| Access: gate and door codes, key pickup, directions | 29 |
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
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.
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.
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.
| Topic | Rows | % acceptable | Dominant failure |
|---|---|---|---|
| Package / mail thin n | 6 | 33% | missing-fact |
| Prospect: pets thin n | 12 | 42% | missing-fact |
| Prospect: access / code / directions | 37 | 43% | missing-fact |
| Access / keys / entry permission | 72 | 44% | missing-fact |
| Prospect: unit features / parking / utilities | 32 | 44% | missing-fact |
| Prospect: deposit / fees / specials | 57 | 49% | missing-fact |
| Rent / balance / payment | 169 | 50% | missing-fact |
| Prospect: availability / price | 76 | 50% | missing-fact |
| Prospect: application / status | 40 | 55% | missing-fact |
| Prospect: qualification / criteria thin n | 29 | 55% | missing-fact |
| Prospect: not interested / opt-out thin n | 11 | 55% | missing-fact |
| Renewal / move-out | 75 | 56% | missing-fact |
| Leasing / apply / tour | 43 | 56% | missing-fact |
| Maintenance / repair | 32 | 56% | missing-fact |
| Parking / tow | 32 | 56% | missing-fact |
| Appointment / scheduling thin n | 7 | 57% | missing-fact |
| Other / mid-conversation continuation | 450 | 58% | missing-fact |
| Prospect: other / mid-conversation continuation | 781 | 59% | missing-fact |
| Prospect: tour / showing | 92 | 59% | missing-fact |
| Prospect: move-in date / lease term thin n | 16 | 62% | missing-fact |
| Utilities thin n | 8 | 75% | wrong-action |
| Insurance / liability charge thin n | 8 | 75% | missing-fact |
| Pest thin n | 14 | 79% | missing-fact |
| Neighbour / noise / conduct thin n | 7 | 100% | — |
| Documents / verification thin n | 3 | 100% | — |
| Voucher / housing authority thin n | 3 | 100% | — |
| Data Clara needs | Rows it blocked |
|---|---|
| Other one-off facts (long tail) | 225 |
| Live unit availability list with rents and sizes | 102 |
| Application status and the screening timeline | 84 |
| Fee schedule: application, admin, deposit, pet, parking | 70 |
| Tour and office scheduling calendar (staff availability) | 57 |
| Access: gate and door codes, key pickup, directions | 46 |
| Sendable links: application, portal, listing | 22 |
| Vendor, pest and inspection schedules | 21 |
| Resident ledger line items and charge breakdown | 17 |
| Current specials and concessions | 17 |
| Utilities setup and billing detail | 14 |
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).
| Topic | Human-wrong rows |
|---|---|
| Prospect: other / mid-conversation continuation | 194 |
| Other / mid-conversation continuation | 134 |
| Rent / balance / payment | 39 |
| Prospect: tour / showing | 24 |
| Access / keys / entry permission | 17 |
| Parking / tow | 16 |
| Prospect: deposit / fees / specials | 15 |
| Prospect: availability / price | 14 |
| Renewal / move-out | 12 |
| Prospect: access / code / directions | 11 |
| Prospect: application / status | 11 |
| Maintenance / repair | 10 |
| Pest | 10 |
| Prospect: unit features / parking / utilities | 7 |
| Leasing / apply / tour | 4 |
| Neighbour / noise / conduct | 4 |
| Prospect: qualification / criteria | 3 |
| Prospect: pets | 3 |
| Package / mail · Documents / verification · Appointment / scheduling · Prospect: move-in date / lease term · Insurance / liability charge | 2 each |
| Voucher / housing authority | 1 |
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.
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.evals/promptfooconfig-leasing-response.yaml; the persona block is swapped for a resident persona on resident rows.chooseCredential refuses a metered runtime.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
| Measure | Before | A · conflicts left out | B · conflicts resolved | B − before |
|---|---|---|---|---|
| Acceptable | 56% | 54% | 56% | +1 |
| Missing fact | 33% | 32% | 30% | −3 |
| Wrong fact | 4% | 7% | 7% | +3 |
| Hallucinated policy | 2% | 1% | 1% | −1 |
| Wrong action | 5% | 5% | 4% | 0 |
| Wrong tone or language | 1% | 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 base | Rows before | Rows after B | Closed |
|---|---|---|---|
| Live unit availability with rents and sizes | 68 | 52 | +16 |
| Application status and screening decision for this applicant | 61 | 48 | +13 |
| Fee schedule: application, admin, deposit, pet, parking | 58 | 50 | +8 |
| The leasing team's live calendar | 45 | 31 | +14 |
| Access: gate and door codes, key pickup, meeting point | 35 | 34 | +1 |
| Sendable links: application, portal, listing | 20 | 14 | +6 |
| Vendor, pest and inspection schedules | 17 | 18 | −1 |
| This resident's ledger line items and charge breakdown | 16 | 25 | −9 |
| Current specials and concessions | 11 | 6 | +5 |
| Utilities setup and billing detail | 12 | 13 | −1 |
| Voucher / housing-authority case state | 10 | 7 | +3 |
| This resident's parking space assignment | 13 | 14 | −1 |
| This resident's lease document terms | 4 | 5 | −1 |
| Uncategorised | 167 | 174 | −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.
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.
| Topic | n | Before | A | B | B − before | Missing-fact before → B | Wrong-fact before → B |
|---|---|---|---|---|---|---|---|
| Appointment / scheduling thin n | 6 | 50% | 50% | 83% | +33 | 33% → 0% | 0% → 0% |
| Package / mail thin n | 6 | 33% | 67% | 50% | +17 | 33% → 17% | 0% → 0% |
| Maintenance / repair thin n | 24 | 58% | 67% | 71% | +12 | 25% → 17% | 0% → 4% |
| Prospect: unit features / parking / utilities thin n | 25 | 44% | 60% | 52% | +8 | 36% → 28% | 0% → 0% |
| Prospect: access / code / directions | 32 | 47% | 47% | 53% | +6 | 44% → 31% | 3% → 6% |
| Other / mid-conversation continuation | 338 | 57% | 61% | 62% | +5 | 30% → 28% | 3% → 3% |
| Rent / balance / payment | 142 | 51% | 50% | 56% | +5 | 42% → 35% | 5% → 6% |
| Prospect: not interested / opt-out thin n | 5 | 40% | 40% | 40% | 0 | 60% → 60% | 0% → 0% |
| Prospect: availability / price | 63 | 51% | 44% | 51% | 0 | 38% → 27% | 10% → 21% |
| Prospect: application / status | 35 | 57% | 49% | 57% | 0 | 37% → 37% | 0% → 6% |
| Prospect: qualification / criteria thin n | 13 | 38% | 46% | 38% | 0 | 62% → 54% | 0% → 0% |
| Neighbour / noise / conduct thin n | 6 | 100% | 100% | 100% | 0 | 0% → 0% | 0% → 0% |
| Parking / tow thin n | 26 | 50% | 65% | 50% | 0 | 50% → 42% | 0% → 4% |
| Voucher / housing authority thin n | 2 | 100% | 50% | 100% | 0 | 0% → 0% | 0% → 0% |
| Prospect: other / mid-conversation continuation | 642 | 58% | 54% | 57% | −1 | 31% → 29% | 3% → 9% |
| Renewal / move-out | 47 | 51% | 57% | 49% | −2 | 38% → 40% | 6% → 6% |
| Prospect: tour / showing | 68 | 57% | 53% | 54% | −3 | 22% → 21% | 10% → 15% |
| Access / keys / entry permission thin n | 29 | 55% | 48% | 52% | −3 | 28% → 17% | 3% → 7% |
| Prospect: move-in date / lease term thin n | 14 | 57% | 50% | 50% | −7 | 36% → 36% | 7% → 7% |
| Prospect: pets thin n | 10 | 50% | 60% | 40% | −10 | 40% → 40% | 0% → 0% |
| Leasing / apply / tour thin n | 20 | 50% | 45% | 40% | −10 | 30% → 35% | 10% → 15% |
| Prospect: deposit / fees / specials | 48 | 56% | 38% | 46% | −10 | 42% → 48% | 0% → 4% |
| Insurance / liability charge thin n | 7 | 71% | 57% | 57% | −14 | 29% → 14% | 0% → 0% |
| Pest thin n | 12 | 75% | 67% | 58% | −17 | 25% → 25% | 0% → 8% |
| Utilities thin n | 4 | 50% | 25% | 25% | −25 | 25% → 75% | 0% → 0% |
| Documents / verification thin n | 1 | 100% | 0% | 0% | −100 | 0% → 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%.
| Fixed (unacceptable → acceptable) | Broken (acceptable → unacceptable) | Net | |
|---|---|---|---|
| A vs before | 158 | 184 | −26 |
| B vs before | 167 | 158 | +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 failure | Rows | Topic | Rows |
|---|---|---|---|
| Missing fact | 66 | Prospect: other / mid-conversation continuation | 72 |
| Wrong fact | 46 | Other / mid-conversation continuation | 20 |
| Wrong action | 28 | Rent / balance / payment | 12 |
| Wrong tone or language | 10 | Prospect: availability / price | 9 |
| Hallucinated policy | 8 | Prospect: deposit / fees / specials | 8 |
| Prospect: tour / showing | 6 | ||
| Prospect: application / status | 5 | ||
| Everything else | 26 |
One example of each failure type, with the judge's own words:
The full 158-row list for B and the 184-row list for A are in ~/situs-data/analysis/replay/RESULTS-KB.md.
| Topic | What B tells Clara | The 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 period | Late 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 concession | The 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 bonus | The 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 time | An 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 plans | Staff 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.
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.| Run | Rows | Wall clock | Input tokens | Output tokens | Cache read | Cache write |
|---|---|---|---|---|---|---|
| Run 1 (before) | 2,118 | 0.68 h | 14,346,910 | 1,176,898 | 0 | 0 |
| Run 2 · A | 1,633 | 0.47 h | 13,482,199 | 698,776 | 4,950,343 | 43,703 |
| Run 2 · B | 1,627 | 0.49 h | 13,741,138 | 706,020 | 5,355,628 | 47,648 |
| Run 2 · control (no knowledge base) | 499 | 0.22 h | 3,369,863 | 287,724 | 0 | 0 |
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.
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 assumes | What happens at Situs | file:line | Sev | Fix 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 |
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 claim | Live 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 field | types.ts:3308 — timezone?: string, read at every date call site |
| A JP founder's email is hardcoded in the auto-reply exemption list | auto-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.
| Finding | Where | Effect at Situs |
|---|---|---|
| New-lease sends are structurally impossible | lib/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 backend | multiTenantConfig.ts — InMemoryAccountConfigRepo only | The fix the lease-template finding depends on has no persistence and no Situs record. |
| Concession scraping covers zero Situs properties | scrapers/registry.ts:10-13 | A static two-element array; the nightly concession watcher walks only Camellia and Yale, so Clara quotes no specials at Situs. |
| Quiet hours default to Central | property-local-date.ts:57-63 | 8: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 collide | fuzzy-match.ts:68,76 — thresholds 0.4 / 0.15 | Situs 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 spend | load-cost-data-core.ts:48 | The "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 Junction | quotes/web-search-vendors.ts | ~28 Denver-branded vendors with +1303 numbers fill maintenance quote gaps. |
| Every Situs vendor write needs an override flag | vendorPhoneSet.ts:88 — Set([1120]) | Vendor 1120 is JP's test handyman; the guard becomes routine to bypass. |
| One shared voice fleet with Camellia as default | specialists/fleets.ts:48-53 | Any Situs-specific voice prompt change alters Camellia's live behaviour unless 55 fleets are cloned. |
| Per-property Slack channels are compiled in | observability/notify.ts:41 | resolveChannel throws on an unknown key, so any Situs notification needs a code edit. |
~30 hardcoded America/Denver literals | clara-personality.ts:11-19 (todayDenver()) and others | Clara'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 prompt | vendor-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. |
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.
| Gap | Where | Effect |
|---|---|---|
| 13 resident-facing sends forced to English | application links, renewal offers and recaps, work-order confirmations, maintenance ratings, tour emails | The majority path at Situs, and exempted from the drift alarm |
| Prompt says Spanish, config does not | maintenance-handyman, turnover-intake, unknown-caller | A 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 construction | renewal-outbound, escalation-callback, emergency-relay, vendor-outbound, after-hours-message-desk | escalation-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 literals | after-hours-message-desk.ts:56,62,68 | The trigger list carries only English phrasings, so "¿puedo dejar un mensaje?" matches nothing. This is the Situs MVP lane. |
| Knowledge base is English-only | i18n/translate.ts | Translation is wired at one call site (tour reminders); every other knowledge fragment reaches a Spanish-preferring resident in English. |
| No eval covers it | whole eval suite | Coverage 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. |
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.
| Area | Evidence |
|---|---|
| Fees, deposits, pet policy, office hours, holidays | PropertyKnowledge carries typed per-property fields: 17 fee fields, structured pet policy, per-day hours, holiday calendar. No fleet default. |
| Anti-fabrication guards | clara-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 recipients | Resolved per property with no hardcoded or env fallback; Clara is separately forbidden from naming a person or address. |
| Inbound email and phone routing | Data-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 variables | Templated 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 nothing | No DEFAULT_KNOWLEDGE constant exists; the clone script requires an explicit source. |
| The multi-tenancy fence | customer-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. |
clara-turnover.ts and clara-delivery.ts — checked for Camellia, JP and Denver literals, none found, but not read end to end.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.
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
| Area | Measure | Jan–Aug 2025 | Jan–Aug 2026 | Sep–Dec 2025 | Label |
|---|---|---|---|---|---|
| Renewals | Offers above / flat / below current rent | 71.8% / 25.5% / 2.7% | 16.3% / 51.1% / 32.6% | — | MEASURED |
| Median dollar change per month | +$25 | $0 | — | MEASURED | |
| Expiring leases never worked | 26.0% | 33.6% | — | MEASURED | |
| Leasing | Apartment leads | 416 | 637 | 153 | MEASURED |
| After-hours share of leads | 24.5% | 26.7% | 25.7% | MEASURED | |
| Wait for a human — in-hours | 1.63 h | 0.15 h | 1.17 h | MEASURED | |
| Wait for a human — after-hours | 15.1 h | 15.2 h | 12.9 h | MEASURED | |
| Show rate · leads never contacted | 48.3% · 11.1% | 42.5% · 5.2% | 53.9% · 7.9% | MEASURED | |
| Vacancy | Median days vacant (move-out → move-in) | 76 | 62 — a floor | 99 | PARTIAL |
| Units empty more than 180 days | 5 | 0 | 14 | PARTIAL | |
| Median make-ready days | 63 | 32 | 34 | PARTIAL | |
| Maintenance | Work orders created | 2,318 | 2,277 | 1,107 | MEASURED |
| After-hours share | 34.0% | 28.8% | 34.5% | MEASURED | |
| Median hours create → assign | 19.8 | 3.0 | 22.7 | PARTIAL | |
| Bot-created share of intake | 8.2% | 38.4% | 11.9% | MEASURED | |
| Open > 90 days · never assigned | 14 · 9.3% | 122 · 18.8% | 54 · 10.5% | PARTIAL | |
| Resident comms | Outbound tenant texts | 3,360 | 20,095 | 2,670 | MEASURED |
| Texted tenants who ever replied | 37.3% | 49.3% | 20.1% | MEASURED | |
| Median wait for a human reply | 18.5 h | 13.6 h | 19.9 h | MEASURED | |
| Inbound never answered in 14 days | 16.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.
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.
| Month | Leads | Showings | Completed | Move-ins | Move-outs | Work orders | WOs after hours | Renewals | Applications |
|---|---|---|---|---|---|---|---|---|---|
| 2025-01 | 40 | 14 | 6 | 4 | 3 | 276 | 95 | 12 | 22 |
| 2025-02 | 55 | 29 | 9 | 18 | 9 | 220 | 72 | 13 | 6 |
| 2025-03 | 48 | 29 | 17 | 10 | 10 | 237 | 96 | 15 | 39 |
| 2025-04 | 34 | 28 | 14 | 7 | 14 | 289 | 91 | 27 | 29 |
| 2025-05 | 29 | 22 | 13 | 4 | 18 | 333 | 89 | 27 | 14 |
| 2025-06 | 67 | 53 | 34 | 19 | 14 | 211 | 87 | 37 | 29 |
| 2025-07 | 96 | 84 | 40 | 22 | 11 | 315 | 95 | 21 | 23 |
| 2025-08 | 47 | 43 | 23 | 22 | 17 | 437 | 162 | 25 | 26 |
| 2025-09 | 37 | 23 | 8 | 12 | 12 | 397 | 135 | 30 | 18 |
| 2025-10 | 53 | 44 | 29 | 13 | 18 | 266 | 107 | 30 | 25 |
| 2025-11 | 29 | 20 | 5 | 25 | 10 | 238 | 81 | 15 | 11 |
| 2025-12 | 34 | 22 | 9 | 7 | 10 | 206 | 55 | 9 | 9 |
| 2026-01 | 57 | 37 | 19 | 12 | 6 | 248 | 70 | 4 | 20 |
| 2026-02 | 59 | 33 | 24 | 7 | 7 | 212 | 48 | 13 | 21 |
| 2026-03 | 61 | 52 | 21 | 10 | 13 | 222 | 65 | 16 | 54 |
| 2026-04 | 68 | 38 | 18 | 9 | 12 | 264 | 61 | 20 | 19 |
| 2026-05 | 94 | 55 | 28 | 9 | 13 | 286 | 99 | 21 | 54 |
| 2026-06 | 98 | 72 | 50 | 24 | 15 | 279 | 85 | 22 | 29 |
| 2026-07 | 118 | 67 | 39 | 15 | 11 | 343 | 117 | 24 | 33 |
| 2026-08 | 82 | 53 | 27 | 12 | 10 | 423 | 110 | 28 | 18 |
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.
| Source | Leads '25 | Show '25 | Move-in '25 | Hours → human '25 | Leads '26 | Show '26 | Move-in '26 | Hours → human '26 |
|---|---|---|---|---|---|---|---|---|
| 101 | 76.2% | 18.8% | 19.1 | 75 | 66.7% | 16.0% | 2.9 | |
| Zillow | 24 | 29.2% | 4.2% | 0.1 | 111 | 43.2% | 11.7% | 20.4 |
| Website | 37 | 37.8% | 45.9% | 6.8 | 74 | 36.5% | 20.3% | 5.6 |
| Drive-by / signage | 56 | 69.6% | 21.4% | 1.5 | 48 | 58.3% | 27.1% | 0.8 |
| Referral | 39 | 53.8% | 56.4% | 0.0 | 55 | 47.3% | 45.5% | 0.1 |
| AffordableHousing.com | 28 | 64.3% | 21.4% | 0.3 | 55 | 49.1% | 16.4% | 0.1 |
| TurboTenant | 0 | — | — | — | 80 | 35.0% | 7.5% | 3.8 |
| Zumper | 43 | 7.0% | 0.0% | 15.1 | 12 | 0.0% | 0.0% | 15.2 |
| Rent.com | 15 | 26.7% | 0.0% | 14.9 | 32 | 18.8% | 0.0% | 16.3 |
| Realtor.com | 7 | 14.3% | 0.0% | 22.5 | 18 | 33.3% | 5.6% | 16.5 |
| Housing Connector | 19 | 10.5% | 31.6% | 0.0 | 2 | 50.0% | 0.0% | 0.0 |
| Shared app link (not a lead) | 17 | 11.8% | 76.5% | 2.5 | 19 | 0.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%.
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.
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.
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.
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 use | Use | Why |
|---|---|---|
| 285 lease expirations | 228 on the apartments | the rest sat on the placeholder property, the houses and the commercial book |
| 1,104 units, or "345 residential" | 397 apartment doors / 646 in the database | the 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 apartments | the blended figure merged offices and houses into the apartment book |
| "75% of vacant units unposted" | 9 of 35 apartments | the 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 sender | only 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.
~/situs-data/situs-dump-2025/, 142 MB — zip in the Workspace Drive folder above.~/situs-data/analysis/tables/. Scripts: ~/situs-data/analysis/scripts/.~/situs-data/analysis/. The stat-by-stat record of this multifamily re-scope is ~/situs-data/analysis/SCOPE-AUDIT.md.