# Roadmap (proposed 2026-10-29; v1 built 2026-10-29)

## Build status (2026-10-29)
- **Built:** `pipeline/` steps 1, 2, 3 (assessor), 5 (rental registry) and 8 (`build.py`), plus `ui/index.html` v1 (map, project cards, filters, detail panel with unit evidence and permit trail, market views, notes and lookup queue). `pipeline/refresh.sh` runs everything.
- **Redfin via search pages (2026-10-30):** the per-unit `/stingray/` pass was dropped (robots.txt). Instead, about 25 search-page loads per refresh capture every 2015+ home that is for sale or sold in the last year. See `docs/redfin-search.md`. The NWMLS export is no longer needed (Ted: too painful to do regularly).
- **Not yet:** NWMLS import (waiting on the agent's export), Zillow/property-manager lookups (on demand), gross yield (needs rents).
- **Known gaps:** cottages/small lots outside Bellingham are inferred from lot size (≤ 0.08 ac); condo parcels count only when ≤ 6 per building address; "owner_occ" for county-only parcels can mean either owner-built or bought, until the sales history loads.

## Status model (per unit, rolled up per project)
`in review → issued → finaled → { for sale | sold-owner | sold-investor | rented | held-unknown }`, each with a **confidence** (confirmed / likely / guess) and the **evidence** that drove it (e.g. "assessor SWD to individual, mail=site", "Zillow: listed for rent $3,100 9/2025, removed 2/2026", "on rental registry").

Evidence priority:
1. Rental registry match: rented, confirmed.
2. Zillow or Redfin rental event after the final: rented, confirmed, and gives the rent.
3. Assessor warranty-deed sale after the final:
   - buyer's mailing address = site: sold-owner;
   - buyer's mailing address elsewhere: sold-investor, likely rented.
4. MLS listing active or pending: for sale.
5. Still owned by the builder or an affiliate with no listing:
   - more than about 6 months after the final, or a $0 quit-claim to a "…Living/Holdings" LLC: held, likely build-to-rent;
   - otherwise: held-unknown.

## Pipeline (Python, writes `data/*.js` for the file:/// app)
1. `pull_permits.py`: 2015+ middle-housing permits (from `feasibility/pull_all_mm.py`), grouped into projects. Fix the repair-permit noise.
2. `enrich_parcels.py`: APN → parcel → assessor page (cached), parsed into owner, mailing address, value, building and sales. Also handle units platted after the permit by matching on site address and subdivision.
3. `redfin.js` (run in the built-in browser): list, sale and rental history plus photos for every finaled unit, saved to `data/redfin.json`. Then `build_photos.py` (borrowed from the Housing Book index) downloads photos, shrinks them and writes them to `ui/img/`.
4. **On-demand lookup (Zillow, property managers, Redfin detail):** Ted picks projects in the app (e.g. a "queue for lookup" button that adds them to an exportable list), then asks Claude in chat. Claude visits the pages in the built-in browser at human pace and saves findings to `data/lookups/<permit-or-apn>.json` with source URL and date. `build.py` merges them. Each lookup is a dated snapshot, so rent history builds up over time. The app also shows plain links per unit (Zillow, Redfin, Google search of the address) for Ted to click himself.
5. `county_parcels.py`: county-wide parcels built 2015+ with middle-housing use codes (ZERO LL, DUPLEX/TRIPLEX/FOURPLEX, W/ ADU, condos) for Ferndale, Blaine and Lynden. In Bellingham, use them only to cross-check the permit universe.
6. `nwmls_import.py`: parse the agent's MLS CSV exports from `data/manual/nwmls/` and join them on address or APN.
7. `rental_registry.py`: pull the public layer (from `feasibility/pull_rental_registry.py`) and join it on APN.
8. `build.py`: merge everything, infer status, compute metrics, and write `ui/data/data.js`.

## UI (`ui/index.html`, file:///)
- **Map** (Leaflet), colored by status, with markers sized by unit count.
- **Project cards** with photos, like the Housing Book index.
- **Filters:** city, type (ADUs included), status, neighborhood, zoning, builder, year finaled, price.
- **Detail panel:**
  - permit trail (applied → issued → finaled, days in each step, linked to eTRAKiT);
  - each unit's sale or rent history, with photos and the listing description;
  - assessor link and evidence notes;
  - Ted's own notes.
- **Market views for Ted's decision:**
  - sale $/sf and rent $/sf by product type and year, **computed only from the tracked projects** (no outside market indices);
  - days on market and price cuts (the market is softening: see the 1716 Sunup Loop and 3503 Sussex examples);
  - share of each type sold vs. held to rent, by builder;
  - gross yield (annual rent ÷ sale price) by type, as a first answer to rent vs. sell;
  - build-cost proxies: permit JOBVALUE per sf and fees paid.
- **Precedent finder:** "show me finaled projects of type X in zone Y". This is the check that the city really approves and finals these products.

## Decisions (Ted, 2026-10-29)
- **ADUs are integrated**, not a separate tab. Under the new middle-housing rules ADUs aren't clearly a distinct category; treat them as one more product type in every view and filter.
- **Ted's agent has NWMLS access.** Plan to get MLS exports from the agent for sold/leased comps (cleaner than scraping); Redfin/Zillow become supplements and the photo source. Request spec: `docs/nwmls-request.md`.
- **Geography: Bellingham + at least Ferndale and Blaine** (Lynden is cheap to add too). Their cities publish no building-permit data, so outside Bellingham the universe comes from the **county parcel layer** (year built + property-use code); see feasibility doc §6. Those projects get no permit trail, and the app must show that coverage gap.
- **Refresh weekly or less**, run on demand. No scheduler needed.

## Immediate next steps
1. Rental registry: DONE, via the public layer (`feasibility/pull_rental_registry.py`). Next, test property-manager listing pages and RentCast for rent amounts.
2. Run the assessor enrichment on all 1,094 finaled permits, about 20 minutes at 1 request per second, cached.
3. Run the Redfin probe on all finaled units and fix the Redfin area search for comps.
4. Build UI v1: map, cards, filters and detail panel, then add the market views.
