Affordable housing layer for Clara

How Clara handles applications, eligibility questions and everyday conversation at an affordable or voucher-assisted home — without loosening the fair-housing floor she already runs under. Documentation and approach only; nothing here is built. Hands off to the build agent in section I.

Parked 2026-09-13 — Fede: do it later; open PRs closed on his call, only #7867 merged (dark)  ·  written 2026-09-11 · research pass 2 the same evening  ·  triggered by Western Slope's go-live next week

A · Why now

Western Slope has two confirmed affordable properties, and go-live is next week. This is the first time Clara has had to get affordable-housing questions right in production.

Two of Western Slope's properties came back flagged affordable in the AppFolio account review — property-level flag, unit-level PBV tags, and payments coming in from a housing authority rather than the tenant, all confirmed straight from AppFolio's own API (not asked of the customer, per Fede's ruling — we research the rules ourselves):

Both properties trace to one event: in May 2022, GJHA sold Courtyard and Lincoln (39 units combined) to Headwaters Housing Partners in a preservation deal financed by CHAI Debt Capital, First Bank, and CHFA's Preservation Fund (CHFA was a gap lender here, not an owner or an LIHTC partner). The deal restricts occupancy at both properties to households at or under 60% of area median income, caps rent at 30% of income, runs for ten years (roughly through 2032), and keeps 12 project-based Section 8 units in place. Source: CHAI Funds press release, May 30, 2022. No LIHTC record was found for either property in HUD's LIHTC database or the National Housing Preservation Database — this is a deed-covenant restriction, not LIHTC; unverified against CHFA's own property list (the list PDFs could not be opened). Full citation in the appendix.

Ownership is confirmed, not inferred: Western Slope's own AppFolio property directory lists the owner of both Courtyard (2910 Bunting Ave, 27 units) and Lincoln (1303 N 15th St, 12 units) as Situs Headwaters One LLC, with a Denver-area (303) phone number — a Situs Group entity is the inference there, since Situs Group is our other design partner. Western Slope is the manager on both, per the same account. Supporting, not proof: the same AppFolio data shows Courtyard's 15 non-PBV units carry the same market rent as the PBV units and are tagged by bedroom count, not "market" — consistent with all 27 units being income-restricted.

On top of that, five of Western Slope's market-rate homes already have individual tenants paying with a housing choice voucher — a different situation from a designated affordable property, and one where the wrong sentence ("we don't take Section 8") is a fair-housing violation regardless of the building's own status.

B · What the law requires, in one page

Three layers apply to Western Slope's affordable homes: federal, Colorado state, and (where it exists) local. Full citations are in the appendix; this section is the floor Clara can never cross.

Federal

Colorado

New since Jan 2026

Four more Colorado laws, confirmed directly on leg.colorado.gov (accessed Sept 11, 2026):

Local

Other Colorado cities do stack a local layer on top of state law, which matters the day this design extends past Grand Junction: Denver adds its own source-of-income ordinance with fewer landlord exemptions plus an inclusionary-housing mandate; Boulder mandates 25% of new units affordable; Vail/Eagle County runs a deed-restricted workforce-housing program (InDEED); Longmont mandates 12% affordable in new developments.L2

What Clara may / must not / hands to a human

TopicClara mayClara must notHands to a human
EligibilityExplain the program and the general processTell someone they're ineligible based on what they've saidAny actual eligibility determination
Income limitsSay a limit exists and where it comes fromConfirm someone qualifies or doesn't from a stated incomeAny income-based accept/deny
WaitlistsExplain how the GJHA waitlist works, take a name for interestPromise a spot, a date, or a unitWaitlist status disputes
Application feeState the fee (or "none," at PBV) accurately per propertyCharge or quote a PBV fee, or a higher fee for voucher holdersFee disputes
Vouchers on market-rate homesSay vouchers are accepted, same screening as everyoneSay vouchers aren't accepted, or ask income questions that treat voucher income differentlyAny voucher-specific screening question
Criminal / credit screeningSay screening is individualized, not a blanket banState a bright-line disqualifier ("any felony," "any eviction")Any actual criminal/credit adverse decision
Reasonable accommodationExplain the right exists and how to request oneGrant, deny, or evaluate a requestEvery accommodation request, no exception
VAWA disclosureExplain the protection and the self-certification formAsk for a police report or other proof; discuss it outside the required scopeEvery VAWA-related disclosure
LEP / SpanishAnswer in Spanish directly for routine leasing questionsRequire English or delay a Spanish speaker to a human for a routine questionComplex documents needing certified translation

C · What EliseAI does (and doesn't)

D · The rule model

Two things vary independently: jurisdiction (federal → state → local) and program (PBV, HCV, LIHTC, HOME, deed-restricted). Program changes the rules more than geography does — a PBV unit and an HCV tenant sitting in the same city follow different fee, screening, and rent rules.

Option: how many jurisdiction levels to store

1. Three explicit levels, nearest-wins, floor clamps lastFederal, state, local stored as versioned rule sets keyed by jurisdiction (country / state / county / city) with effective dates. A property resolves its stack by walking federal → state → its own local level; the compliance-floor class (protected classes, never writable) clamps the result regardless of what any level says. Western Slope resolves to: US → CO → Mesa County/Grand Junction = no local rules → GJHA's own program facts stored as property data, not a jurisdiction level. Handles Denver/Boulder/Vail/Longmont-style local layers without a rebuild.
2. Two levels (federal + state), local as an exception listSimpler to build, and correct for every current customer since only Grand Junction is live. Breaks the day a Denver or Boulder property is onboarded — local rules become a set of if-property-in-list patches rather than a real level, which is exactly the kind of prompt drift the fair-housing rules already had to be pulled together to fix once.
3. Per-property free-text knowledge onlyFastest to ship, cheapest to reason about for one property. No shared source of truth across properties on the same program — a PBV rule fixed at Courtyard doesn't propagate to the next PBV property, and nothing catches drift. Rejected for the same reason the fair-housing rules were consolidated into one shared list in 2026-09: four independent copies had already drifted once.

The program axis

Program is a second, independent key on the same unit or property: PBV / HCV / LIHTC / HOME / deed-restricted / none. A rule set is keyed by (jurisdiction, program), not jurisdiction alone — the PBV application-fee ban is a program rule that applies in every jurisdiction; the 2× income cap is a Colorado jurisdiction rule that applies to every program.

How Western Slope resolves

US (federal floor) → Colorado (source-of-income protection, 2× income cap, deposit/late-fee caps) → Mesa County / Grand Junction (no local layer — falls through) → GJHA program facts (Courtyard PBV terms, Lincoln's income-restriction terms, current payment standards) stored as property/unit data, resolved once the unit's program tag is known. The compliance floor (protected classes, never writable by any level) clamps last, exactly as it does for the fair-housing gate today.

Mapping onto Gera's registry classes

Registry classWhere this design uses it
Compliance floorProtected classes stay untouched — this layer is not allowed to write or soften them. Same clamp already enforced in production by the fair-housing gate.
ParameterNumeric jurisdiction rules that vary by property and inherit nearest-wins: income-cap multiple, deposit caps, late-fee cap, application-fee amount.
IdentityProgram type (PBV / HCV / LIHTC / HOME / deed-restricted) — pinned, never inherited, same shape as asset_type today.

E · Keeping rules current

Secondary concern, kept short. Each rule set carries an effective date and a change log entry (what changed, citation, who reviewed it) rather than being edited in place — the same discipline the fair-housing protected-class list already uses ("a legal decision, not an editorial one").

SourceCadenceWhat to watch
HUD PIH noticesMonthly/quarterlyPayment standards, EIV, HOTMA updates
CHFA eNews + compliance manualMonthly, plus July 1 policy effective dateIncome/rent limits, LIHTC compliance changes
GJHA administrative/annual planEffective July 1Waitlist procedure, payment standards, PBV terms
Colorado legislatureSession Jan–May, new law effective July 1Any new HB/SB touching tenant screening, deposits, fees, source of income

A lightweight quarterly check (does anything in the change log need a bump) plus an annual full review is enough — this is not a daily-monitoring problem, since none of these sources move faster than monthly.

F · Runtime: how Clara switches path

How it fits together

Source of truth (AppFolio) Our records Rule stack, resolved per unit What Clara says vacancy sync, every 5 min (shipped, dark) Unit tags (PBV) Property flag (no API column yet) Unit: program fact shipped 2026-09-11 Property knowledge: lease policy → voucher / program fact Per-property switch (one, on the property; off by default) Federal floor Colorado Local (Grand Junction: none) Program facts (PBV / income-restricted) nearest wins Compliance floor clamps last (protected classes, fair-housing gate) Text and email prompt block Voice injection (fact variable) 12-line behaviour list Fair-housing gate (unchanged floor) Caller Hand to a human accommodation · VAWA · eligibility · unsure solid = exists today dashed = designed, not built Only piece built today: the Unit program fact and its sync
Every five minutes AppFolio's unit tags sync into a program fact on our Unit record — the only piece of this actually built and running today. That fact, plus two records still on the drawing board (a property-level lease-policy fact and a per-property switch, off by default), are meant to feed a four-layer rule stack — federal, Colorado, local, and the property's own program terms, applied nearest-first — with the existing fair-housing floor clamping the result no matter what the other layers say. The resolved answer would then reach Clara the same way any fact does: through the text/email prompt and the voice call, both collapsing into the same twelve-line behaviour list, which runs through the unchanged fair-housing gate before reaching the caller — except for accommodation, VAWA, eligibility, or unsure cases, which the design routes straight to a human instead.

No new parallel system. This reuses the extension points the fair-housing gate and knowledge stack already have (full list in the appendix):

G · The compact behaviour list

This is the deliverable a prompt would actually carry — short, imperative, nothing else.

  1. Always answer "do you accept vouchers/Section 8" with yes, at every property and every market-rate home.
  2. Never state whether a specific person is eligible, qualifies, or doesn't.
  3. Never do income math live. State that a limit exists; never compute or confirm against a number the caller gives.
  4. At a PBV unit, state there is no application or screening fee. Never quote one.
  5. Never require or imply an income multiple against total rent for a voucher holder — only their own share.
  6. Describe screening as individualized review, never a bright-line rule (no "any felony," "any eviction," "must earn 3×").
  7. For a waitlisted or full unit, use waitlist language ("I can add your name to the interest list") — never invent availability or a date.
  8. On any reasonable-accommodation request (disability, service animal), explain the right and route to a human immediately — never evaluate.
  9. On any VAWA-related disclosure (domestic violence, stalking, assault), stop, explain the self-certification protection, and route to a human — never ask for proof.
  10. Answer directly in Spanish for routine leasing questions; never defer a Spanish speaker to a human for something English speakers get answered live.
  11. Never mention a caller's protected-class status, program type, or unit assignment to anyone but that caller.
  12. When unsure which of the above applies, hand to a human rather than guess.

GJHA quick facts, verified 2026-09-11. Grand Junction Housing Authority, 8 Foresight Circle, Grand Junction, CO 81505 — (970) 245-0388. The general Housing Choice Voucher waiting list is open (gjha.org/housing-programs/housing-choice-vouchers). The project-based voucher waitlist for "Capital Terrace Apartments and Courtyard Apartments, 2 and 3-Bedroom" is open with no predetermined closing date (affordablehousingonline.com listing 113909, last updated Dec 3, 2025). Payment standards by bedroom size are not published online by GJHA — any dollar figure has to come from GJHA directly, which is why Clara never states one (decision 3).

Example exchanges

"Do you take Section 8?"

"Yes — we accept housing choice vouchers here, and at Courtyard and Lincoln specifically."

"What's the income limit for a 2-bedroom?"

"There's an income limit set by the housing authority for that program — I don't have the exact number to quote live, but I can connect you with our leasing team or GJHA to check your specific household."

"How do I apply at Courtyard?"

"Courtyard has both market-rate and voucher units. For the voucher units, you'd apply through the Grand Junction Housing Authority; I can also start a market-rate application if that's a better fit — which one were you hoping for?"

"Is there a waitlist?"

"Yes — the project-based voucher waitlist for Courtyard and Capital Terrace is open through GJHA, with no set closing date. I can take your name and contact info to pass along, and give you GJHA's number, (970) 245-0388, to check your spot directly."

(Voucher holder calling about a market-rate home) "I have a voucher — will that be a problem?"

"Not at all — we accept vouchers here, and you'll go through the same screening as any other applicant."

"I got evicted two years ago, can I still apply?"

"We review each application individually rather than ruling anyone out automatically — I'd encourage you to apply. Our leasing team can walk through your specific situation."

(In Spanish) "¿Cuánto cuesta la solicitud?"

"En las unidades de Courtyard con vale de vivienda no hay costo de solicitud. Para las unidades a precio de mercado, la tarifa es [tarifa estándar]."

"I need a ground-floor unit because of my mobility — can you guarantee that?"

"That's a reasonable accommodation request, and I want to make sure it's handled properly — let me connect you with our leasing team, who can process that formally."

H · Testing and scoring

Extends the existing fair-housing gate rather than building a parallel one — exact files are in the appendix.

I · Build plan for the handoff agent

A chain of small, dark, mergeable-on-their-own PRs, each one concern, each ≤300 lines, each with its own proof. No step turns anything on for a customer — that's Fede's call, separately, after Willows testing.

#PRProof
1Data: add program/affordable fields to the Property and Unit records, wire the AppFolio mapper to actually populate them from the raw property/unit response instead of dropping them in the untyped catch-allA synced Western Slope property shows the correct program tag on Courtyard's 12 PBV units and Lincoln's 12 units; unit test on the mapper
2Rule sets + resolver: versioned rule sets keyed by (jurisdiction, program), effective dates, the nearest-wins + floor-clamp resolution logicResolver test proving Western Slope resolves to US → CO → GJHA program facts with no Grand Junction local layer
3Knowledge injection: affordable-program fact in PropertyKnowledge.leasePolicy, flowing through both existing renderersA written fact appears in both the text/email prompt block and the voice injection cache for a test property
4Prompt lines: the 12-line behaviour list, gated behind the per-property program switch, on both text/email and voiceBehaviour-list eval cases pass on a program-tagged test property, unaffected on a non-tagged one
5Gate/eval extension: affordable dimension on the fair-housing judge, evals, and harness scenarios; the topic labelRed-before/green-after on the new eval cases; harness run showing the new scenarios
6 (later phase)Human-compliance flag: post-transfer extraction check against the behaviour list, flag shape, yellow-dot/evidence-gated notification wiringA scripted non-compliant transferred-call transcript produces the flag; a compliant one doesn't

J · Decisions for Fede

1. Rule-model shape

Three explicit jurisdiction levels + program axis, floor clamps lastRecommended — see section D. Handles a future Denver/Boulder property without a rebuild; costs one more level of resolver logic than the two-level option.
Two levels (federal+state), local as an exception listCheaper now, correct for Grand Junction alone; breaks the first time a customer with a real local layer is onboarded.

2. Program-axis granularity: store the raw fact now?

Gera's model already answers the granularity question — program resolves at the unit, reserved in condition {program | ...}, row 1.12 of his design — so this is no longer "which level." It's whether to start capturing the fact before the overlay that reads it ships.

Store per-unit program on the Unit record now, darkRecommended — write the AppFolio-sourced program tag onto each Unit as plain data today, unread by anything, so it's already there the day M26's unit overlay lands. Needs Gera's confirmation that this is safe to do ahead of M26, and his timeline for M26 relative to Western Slope's go-live.
Wait for M26 before storing anythingAvoids writing to a field that might change shape before the overlay ships, but means Courtyard's unit-level PBV split isn't captured anywhere until M26 lands — a real risk if M26 slips past go-live.

3. Does Clara ever state income limits numerically?

No — always describe the limit exists, never quote a numberRecommended. Avoids Clara ever being wrong or stale on a number that changes annually (CHFA publishes new limits every year), and avoids implying a determination. Costs a small amount of caller friction — a human has to supply the number.
Yes, from a verified fact on file, refreshed on the same cadence as rent limitsMore helpful to the caller, mirrors the KB-conditional-exception pattern already used for voucher acceptance. Needs a real update process (CHFA publishes limits annually) or a stale number becomes a compliance problem, not just a UX one.

4. Does Clara take waitlist interest, or only point to GJHA?

Take a name and contact info, always also give the GJHA numberRecommended. Matches "Clara actually helps" from the scope ruling, and GJHA's own process is the system of record for waitlist position — Clara isn't promising a spot, just capturing interest.
Only point to GJHA, never capture interest ourselvesSimpler, zero risk of Clara's list drifting from GJHA's real one, but less helpful — most vendors researched do capture interest, and callers expect a leasing office to do something with their info.

5. Is the human-compliance flag (section H) in scope for phase 1?

No — design now, build laterRecommended, and how the Fede ruling framed it. Phase 1 is Clara's own behaviour; catching a human employee's non-compliant statement needs the post-transfer extraction path proven on affordable-specific cases first.
Yes — build it alongside phase 1Front-loads the compliance win, but stretches an already-tight go-live timeline across two very different pieces of work (Clara's own prompt behaviour vs. reviewing a human's transcript).

K · Appendix

Research digests, citations, and extension points (collapsed — expand to read)

Federal citations (F1–F8)

  1. F1 — Source of income not federally protected: Fair Housing Act, 42 U.S.C. §3601 et seq.; 24 CFR Part 100. Accessed Sept 2026.
  2. F2 — PBV application-fee ban: 24 CFR 983.253; HUD Non-Rent Fees Chart (Feb 2024). HCV fee rules: 24 CFR 982.
  3. F3 — Income multiple limited to tenant's own share: 24 CFR 982.301–982.310.
  4. F4 — Individualized criminal/credit screening: HUD Office of General Counsel Guidance, April 4, 2016.
  5. F5 — VAWA 2022: 24 CFR Part 5, Subpart L; HUD Form HUD-5382.
  6. F6 — Reasonable accommodation, human-only: 24 CFR 8.11; 24 CFR 100.204.
  7. F7 — LEP/language access: Fair Housing Act; Title VI, 42 U.S.C. §2000d; Executive Order 13166.
  8. F8 — HUD AI/algorithm guidance: HUD Press Release 24-098, May 2, 2024.

Colorado citations (C1–C10)

  1. C1 — Source of income protected class: HB20-1332, C.R.S. 24-34-502, effective Jan 1, 2021.
  2. C2 — Income cap 2× rent: SB23-184.
  3. C3 — Deposit caps: SB23-184 (security deposit); HB23-1068, effective Jan 2024 (pet deposit/rent).
  4. C4 — Late fee cap and 7-day rule: SB21-173, C.R.S. 38-12-105, effective Oct 1, 2021. (HB20-1141 is a related, earlier tenant-protection bill on a different topic — not to be confused with the source-of-income bill HB20-1332 above or with SB21-173's late-fee rule.)
  5. C5 — Portable screening reports: HB23-1099.
  6. C6 — LIHTC/CHFA compliance: CHFA Multifamily Program Compliance Manual 2024; IRC §42(g).
  7. C7 — Security-deposit withholding/itemized-return rules: HB25-1249, effective Jan 1, 2026. Confirmed on leg.colorado.gov, accessed Sept 11, 2026.
  8. C8 — Portable screening report acceptance; no forced credit history for subsidized-rent applicants; no forced single vendor: HB25-1236, effective Jan 1, 2026. Confirmed on leg.colorado.gov, accessed Sept 11, 2026.
  9. C9 — All-in mandatory-fee rent quoting: HB25-1090, effective Jan 1, 2026. Confirmed on leg.colorado.gov, accessed Sept 11, 2026.
  10. C10 — Pre-screening written notice (data pulled, denial criteria): HB26-1196, signed June 2, 2026, effective Jan 1, 2027 — not yet in force. Confirmed on leg.colorado.gov, accessed Sept 11, 2026.

Local citations (L1–L2)

  1. L1 — Grand Junction/Mesa County has no local mandate layer: single-pass search, not independently re-verified, cross-checked against Grand Junction Municipal Code and the "At Home in GJ" voluntary program (non-regulatory). Grand Junction's Resolution 45-25 (Aug 2025) is a voluntary fee-waiver incentive for 60–90% AMI rentals, not a mandate — https://www.gjcity.org/1459/Affordable-Housing-Incentive-Program. Accessed Sept 11, 2026.
  2. L2 — Denver source-of-income ordinance (eff. Jan 1, 2019) and Inclusionary Housing Ordinance; Boulder Inclusionary Housing Ordinance and Permanently Affordable Housing program; Vail InDEED workforce-housing program; Longmont Inclusionary Housing Ordinance. All accessed Sept 11, 2026.

GJHA contact/waitlist citations

  1. GJHA address and phone: 8 Foresight Circle, Grand Junction, CO 81505, (970) 245-0388. HCV waitlist open: gjha.org/housing-programs/housing-choice-vouchers. Accessed Sept 11, 2026.
  2. PBV waitlist for Capital Terrace and Courtyard (2- and 3-bedroom), open, no predetermined closing date: affordablehousingonline.com listing 113909, last updated Dec 3, 2025. Accessed Sept 11, 2026.

Property-history citation

  1. Preservation deal, May 2022 — GJHA sold Courtyard ("Bunting Courtyard") and Lincoln Apartments (39 units combined) to Headwaters Housing Partners; financed by CHAI Debt Capital, First Bank, and CHFA's Preservation Fund (CHFA as gap lender). Occupancy ≤60% AMI, rent ≤30% of income, 10-year term, 12 PBV units retained. CHAI Funds press release, May 30, 2022: https://chaifunds.com/2022/05/30/weave-closes-loan-to-preserve-two-properties-in-grand-junction/. Accessed Sept 11, 2026.

Research gaps and inferences (labeled)

Extension points used by this design

  1. PropertyKnowledge.leasePolicy — add an affordable-program fact beside the existing voucher-acceptance fact; flows through the same text/email and voice renderers with no new plumbing.
  2. The KB-conditional-exception pattern already used for the voucher-acceptance carve-out in the leasing prompt rules — the template for any new narrow, fact-gated affordable-housing carve-out.
  3. The outbound-safety policy's applicability gate — the seam to scope a new policy variant to affordable-housing properties, same shape as today's capability/audience gate.
  4. The per-property/per-call voice directive variable pair — the designed mechanism for injecting a scripted directive without a prompt-file merge; must be a separate fact variable, never a variable-gated sentence (renders as dead text otherwise).
  5. The Property record and the AppFolio mapper types — currently no program/affordable field exists on either side; this is where ingestion starts (build plan PR 1).
  6. Gera's key-registry IDENTITY class, and the reserved-but-unbuilt condition {program | leaseFormId | unitType | assetTypes} attribute for regulated stock — the architecturally intended home for this once the org/property model ships (see the open ruling in section D).
  7. The gate registry — where a new affordable-housing gate/alert gets registered and drift-pinned, mirroring the existing fair-housing-judge row.
  8. Topic labeling — no voucher/Section-8/affordable topic exists; a labeler bucket needs to be created from scratch, not extended.

Access dates for all vendor and legal research: September 11, 2026. Full research briefs (federal, Colorado, vendor landscape, and the fair-housing code inventory this design builds on) are held alongside this session's working notes, not republished here in full to keep this page to a single read.

PropFlow Docs