{"slug":"nationalrealestate","total":125,"limit":100,"offset":0,"since":null,"commits":[{"hash":"f6fb527","date":"2026-07-28 11:56:31 -0700","author":"Steve Abrams","subject":"parcels: fix nyc_pluto 08P01 — provenance added 4 cols (19→23), drop chunk 3000→2500 to stay under PG 65535 bind-param cap","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"23c88a6","date":"2026-07-28 09:46:55 -0700","author":"Steve","subject":"feat: RENTV data feed over usre DB (:9796) — brokers/firms/commercial parcels/subleases/regions","body":"Read-only CORS JSON feed sharing the national CRE datasets with RENTV: /feed/brokers (~2M),\n/feed/firms (~214k), /feed/commercial (~154k parcels w/ assessed values), /feed/subleases,\n/feed/regions, /feed/summary. Tailnet-reachable, pm2-managed."},{"hash":"6ff7a81","date":"2026-07-28 08:14:42 -0700","author":"Steve Abrams","subject":"TK-50: field-level provenance across ALL remaining parcel ingesters","body":"Wire source_url + source_key + fetched_at + raw_source onto every parcel row,\nand registerSourceFieldMap(our_field -> source_attr) for each source, replicating\nthe arcgis_sales reference pattern. Now 100% of the pipeline that writes `parcel`\ncarries full field-level provenance.\n\nWired: nyc_pluto (own upsert path — provenance cols added to its bespoke\nupsertChunk), king_wa (4 EXTR extracts joined by PIN), cook_il (4 Socrata datasets\nby PIN), franklin_oh (GDAL .gdb), miami_dade, wake_nc, tarrant_tx, bexar_tx,\nfulton_ga, saltlake_ut, sandiego_ca. Each gets a per-record addressable sourceUrl\n(ArcGIS OBJECTID/id query, Socrata ?pin/?bbl, or county detail page), fetchedAt =\nrun start, rawSource = the raw feature/row attrs before normalization, and a\nsource_field_map declaring the REAL attribute each field maps from (read from the\nactual mapping, joined-file/dataset named for the multi-source counties).\n\nBehavior-preserving otherwise. tsc --noEmit clean. Verified end-to-end via bounded\nreal runs (San Diego Poway, Wake NC, Bexar TX): all four columns populate + the\nfield-map resolves a field to its source attr + raw value; test rows purged, dev\nDB left consistent. No existing-row backfill (gated prod step — see\nTK-50-field-provenance.md).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"536b408","date":"2026-07-28 07:58:27 -0700","author":"Steve Abrams","subject":"parcels: field-level data provenance — source every parcel field to (feed + attr + time + raw)","body":"Migration 012_parcel_provenance.sql (additive): parcel.source_url/source_key/\nfetched_at/raw_source + source_field_map(source_key,our_field,source_attr).\nupsert.ts: ParcelUpsertRow +optional {sourceUrl,sourceKey,fetchedAt,rawSource};\nnew registerSourceFieldMap(). arcgis_sales.ts: per-source fieldMap + raw feature,\nstamps provenance per row + registers the field map at ingest (all 14 sources).\nAdds provenance_selftest.ts (asserts persistence + \"where did field X come from\"\nresolution, self-purging). Verified vs local usre dev DB + a bounded oregon-rlis run.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"1c33393","date":"2026-07-28 07:38:14 -0700","author":"Steve Abrams","subject":"parcels: guard null/placeholder/junk owner names — shared sanitizeOwnerName() at upsert chokepoint","body":"New src/ingest/parcels/owner_guard.ts drops owner values that are not real\nnames: exact placeholder tokens (CURRENT OWNER, UNKNOWN, OWNER OF RECORD,\nTAXPAYER, N/A, NULL, ...) and non-name junk with no letter at all (leaked\nCook-IL PINs like 09364120170000, address fragments '189-191', bare years).\nWired centrally into upsertParcels() (covers all 11 ingesters that route\nthrough it) + nyc_pluto's own upsert path. Mirrors date_guard/price_guard:\n30-case tsx self-test, tsc --noEmit clean.\n\nOver-correction guard: legit 2-char initials (JS/MH/PI) and names containing\ndigits (3M CO, 7-ELEVEN) are KEPT; only zero-letter values and known\nplaceholders are dropped. ~1,785 existing corrupt rows quantified in the\nlocal mirror; the one-time backfill of those is drafted to pending-approval\n(gated persistent DB write), not run here.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"f01d750","date":"2026-07-28 07:06:11 -0700","author":"Steve Abrams","subject":"parcels: add Fulton County GA / Atlanta (13121) — dedicated rich full-universe adapter","body":"Dedicated fulton_ga.ts over the keyless Fulton County DoIT/GIS-hosted Tax_Parcels\nFeatureServer (Board of Assessors tax digest, ~373,004 parcels, TaxYear 2026).\nCoverage: owner 99.98%, property address assembled from structured components 100%,\nland-use code 100%, living units 86%, land acres. No market value / year-built /\nbuilding sqft / beds-baths / sale-or-deed feed in this open view -> parcel-detail-only\n(Bexar/Salt Lake precedent): zero parcel_event rows, never a fabricated sale.\nRegistered 'fulton' in engine.ts, documented in PARCEL-COVERAGE.md. Verified\nend-to-end vs local usre DB (bounded 2-page run, owner/addr/use 100%, geo in Atlanta\nbounds, 0 events, 0 parcel_source leak), tsc exit 0, test rows purged. Applies the\nWake/Tarrant/Bexar DTD-B precedent (dedicated *.ts, no re-panel). Full 373k backfill +\nKamatera prod deploy remain Steve-gated and NOT executed this pass.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"994fedb","date":"2026-07-28 06:58:07 -0700","author":"Steve Abrams","subject":"parcels: guard negative sale prices — shared sanitizeSalePrice() across king_wa + arcgis","body":"King County WA's EXTR_RPSale.csv carries occasional negative saleprice values\n(source data-entry artifacts, -400..-100) that king_wa's num() let through\n(it rejected only 0), landing 72 impossible negative prices in\nparcel.last_sale_price. New shared src/ingest/parcels/price_guard.ts\nsanitizeSalePrice() rejects negative/zero/non-finite amounts (strips currency,\nNO upper cap — real >$1B tower sales are legit), wired into king_wa and\narcgis anyPrice (also fixes a latent bug where anyPrice stripped the minus\nsign, turning -400 into 400). 18-case self-test passes; tsc clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"1e35d6a","date":"2026-07-28 06:51:43 -0700","author":"Steve Abrams","subject":"parcels: add Yakima County WA (53077) free priced-deed feed","body":"56,030 priced sales from the Yakima County Assessor ArcGIS MapServer\n(gis.yakimawa.gov). SQL-Server-backed layer returns fully-qualified\nDBO.Parcels.* attribute keys, so outFields/toRecords/orderBy all use the\nqualified names. Maps GROSS_SALE_PRICE + SALE_DATE (M/D/YYYY) + EXCISE_NUMBER\n+ GRANTOR_NAME + owner (ORG or FIRST/LAST) + situs + use + yrblt + sqft +\nbeds/baths + summed market land/impvt -> total_value. Verified end-to-end vs\nlocal usre DB (1921 parcels + 1938 sale events w/ doc+grantor+grantee+GIS\ndeep-links, dates 2005-2026, source registered). tsc clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"f29163c","date":"2026-07-27 21:28:23 -0700","author":"Steve Abrams","subject":"parcels: add Bexar County TX / San Antonio (48029) — dedicated rich full-universe adapter","body":"BCAD appraisal roll via City-of-San-Antonio open-data BCAD_Parcels FeatureServer\n(keyless ArcGIS, PropID>0, outSR=4326 server-side reproject). ~721k parcels:\nowner 99%, situs property address parsed to street+city+zip 99%, living-area\nsqft 87%, land sqft, state use code, legal acreage. Parcel-detail-only (no\nappraised value/year-built/beds-baths/sale feed here) so zero parcel_event rows\n- never a fabricated sale. Applies the Wake/Tarrant DTD-B precedent (rich\nfull-universe ArcGIS -> dedicated *.ts). Registered in engine.ts, documented in\nPARCEL-COVERAGE.md. Verified end-to-end vs local usre DB (2-page bounded run:\n3996 parcels, owner/city/zip/latlng 100%, sqft populated, 0 events, real SA\ncentroids, 4 stubs skipped); tsc exit 0; test rows purged. Full 721k backfill +\nKamatera deploy remain Steve-gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0e3ce56","date":"2026-07-27 21:19:30 -0700","author":"Steve Abrams","subject":"parcels: add Tarrant County TX / Fort Worth (48439) — dedicated rich full-universe adapter","body":"715k parcels via City-of-Fort-Worth hosted TAD Parcels_Public_Vview FeatureServer\n(keyless ArcGIS, COUNTYNAME='Tarrant' filter). Owner 100%, TRUE market value 99%,\nsqft 89%, year-built 90%, deed date 98%. No beds/baths or sale price in the feed —\ndeed events recorded as event_type='deed' with amount NULL (honest, no fabricated\nprice). Drops the 12-31-1900 'no deed on record' sentinel (~18k rows). Applies the\nWake/Miami DTD-B precedent (rich full-universe ArcGIS → dedicated *.ts adapter).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0bae506","date":"2026-07-27 21:08:42 -0700","author":"Steve Abrams","subject":"parcels: extend deed-date sanity guard to franklin_oh, king_wa, nyc_acris","body":"Prior pass centralized sanitizeEventDate() into the 4 parcel_event deed\ningesters (arcgis_sales, miami_dade, wake_nc, sandiego_ca). But three more\nparcel ingesters — franklin_oh, king_wa, nyc_acris — also emit a bare\nYYYY-MM-DD sale date into parcel.last_sale_date (and the sales JSON detail)\nwith no future/absurd-date guard. Route each ingester's single date-parse\nhelper (toIsoDate/isoDate) through the shared sanitizeEventDate() so a\nfuture/typo/sub-1900 date is dropped before it lands on the parcel row.\nSame defect class the arcgis guard was added to stop, closed on the\nparcel table for the last three date-bearing ingesters.\n\ncook_il + saltlake_ut set last_sale_date:null (no dates) — safe, untouched.\nDB verified clean (0 future, 0 ancient) for these counties: preventive.\ntsc --noEmit clean; date_guard 19-case self-test passes. $0 (local).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"8934410","date":"2026-07-27 21:04:37 -0700","author":"Steve Abrams","subject":"parcels: centralize deed-date sanity guard across all 4 deed ingesters","body":"The future-date guard was a one-off inline check in arcgis_sales.ts; wake_nc\nhad only a 1971 lower bound and miami_dade/sandiego had no future/absurd-date\nguard at all — so a bad-data run against those feeds could re-introduce\nimpossible parcel_event dates. Add a shared, self-tested sanitizeEventDate()\n(rejects future dates, sub-1900, and non-calendar dates like Feb 30) and wire\nit into all four deed ingesters at the date-normalization point. Ships a\n19-case tsx self-test (no test framework in repo).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"de29c39","date":"2026-07-27 20:59:52 -0700","author":"Steve Abrams","subject":"parcels: add Marion County OR / Salem (41047) free priced-deed feed","body":"96,115 priced sales from the Marion County official ArcGIS org\n(TaxParcel_Assessment/0): SALEPRICE + INSTDATE deed date + INSTNUM/INSTTYPE\ndoc metadata + OWNERNAME + SITUS + LIVINGAREA + YEARBUILT + RMVTOTAL.\nConfig in arcgis_sales.ts, adapter in engine.ts (appended), hourly-loop\njob deeds-marion, docs in SOURCES.md. Verified end-to-end against local\nusre DB (2000 parcels + 2000 sale events + source registration for 41047);\ntsc clean. Local only; prod deploy + full backfill to Kamatera are Steve-gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"180998f","date":"2026-07-27 20:52:46 -0700","author":"Steve Abrams","subject":"parcels: add Klamath County OR (41035) free priced-deed feed","body":"New ArcGIS priced-deed source in arcgis_sales.ts + engine.ts adapter +\nhourly-loop job (deeds-klam). KC_ParcelSales FeatureServer, 38,796 priced\nsales with owner/situs/sqft/beds/baths/yrblt/total-appraised/doc. Verified\nend-to-end against local usre DB (1k parcels + 1k sale events + links +\nsource registration). SOURCES.md documents the feed + the arcgis_sales\nconfig family. TK-16.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"1499f0f","date":"2026-07-26 22:08:43 -0700","author":"Steve","subject":"USRE Map: export matching counties to CSV (parity w/ grid) + fix on-map bar z-collision with geo-search pill (v0.16.0)","body":""},{"hash":"9ab361e","date":"2026-07-26 21:58:35 -0700","author":"Steve","subject":"USRE geo-search: recent searches (localStorage) shown on empty focus + clear (v0.15.0)","body":""},{"hash":"7c0710f","date":"2026-07-26 21:25:46 -0700","author":"Steve","subject":"USRE: searched address in a parcel-covered county deep-links to the property page (prefill+auto-search); graceful fallback to county market (v0.14.0)","body":""},{"hash":"e08091b","date":"2026-07-26 21:09:05 -0700","author":"Steve","subject":"USRE: geo-search now resolves ZIP (zip_county crosswalk) + street address (Census geocoder); rolled site-wide (pill on map/content, inline in grid top-bar) (v0.13.0)","body":""},{"hash":"0a3f34d","date":"2026-07-26 20:59:34 -0700","author":"Steve","subject":"USRE: top location search (county/city/state) — /api/geo-search + typeahead pill on the Map, jumps to market page (v0.12.0)","body":""},{"hash":"c5b668f","date":"2026-07-26 20:42:29 -0700","author":"Steve","subject":"USRE Map: URL-shareable county filters + on-map Copy link (parity with grid) (v0.11.0)","body":""},{"hash":"c246a3b","date":"2026-07-26 20:37:24 -0700","author":"Steve","subject":"USRE grid: URL-shareable filters — sync filters/search/sort to query string + Copy link button (bookmarkable views) (v0.10.0)","body":""},{"hash":"b9110d8","date":"2026-07-26 20:27:16 -0700","author":"Steve","subject":"USRE Map: on-map active-filter indicator (count + reset) so filtered state is legible with the drawer closed (v0.9.1)","body":""},{"hash":"bb39923","date":"2026-07-26 20:21:09 -0700","author":"Steve","subject":"USRE Map: persist county filters to localStorage + active-filter chips (harmonize w/ grid) (v0.9.0)","body":""},{"hash":"eed29a4","date":"2026-07-26 20:20:59 -0700","author":"Steve Abrams","subject":"saltlake: contrarian polish — drop dead EFFBUILT_YR fallback + filter attribute-less ROW ghost parcels","body":"Contrarian gate = SHIP IT (5/5, no data bug). Two latent-risk fixes: (1) year_built now strictly BUILT_YR (eff year stays in extra.eff_year_built) — the ?? EFFBUILT fallback was dead code that would silently mislabel renovation year as built year if it ever fired; (2) skip the ~3,542 attribute-less ROW/easement ghost features (null value+addr+sqft+use) + purged the prior run's ghosts. Rejected the suggested shared upsert.ts value-guard (would break legit value-decrease re-runs). TK-00026.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"afd616a","date":"2026-07-26 20:15:39 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T20:15:38 (1 files) — _vpmf.mjs","body":""},{"hash":"b761f11","date":"2026-07-26 20:11:36 -0700","author":"Steve Abrams","subject":"parcels: add Salt Lake County UT (49035) — 393k parcels, market value+sqft+year (DTD-B fresh state)","body":"DTD verdict B (broaden hunt after NC/FL dead-ends) -> Utah LIR standardized FeatureServer. 393,521 parcels: 99% MARKET total+land value, 88% sqft, 88% year-built, use/floors/acres/material, 99% address, 100% in-bbox. No owner/sale (UT withholds owner from public LIR). Per-page dedup by source_id (PARCEL_ID non-unique across multi-part polygons). Ticket TK-00026.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"27ca207","date":"2026-07-26 20:11:15 -0700","author":"Steve","subject":"USRE Map: left-rail county data-point filters in the drawer — dim counties by metric ranges + live match count (v0.8.0)","body":""},{"hash":"46b0b58","date":"2026-07-26 20:03:32 -0700","author":"Steve","subject":"USRE grid: polished empty state — icon + message + one-click Clear all filters CTA (v0.7.1)","body":""},{"hash":"966b628","date":"2026-07-26 19:57:46 -0700","author":"Steve","subject":"USRE grid: CSV export honors active filters — export filtered+sorted rows client-side (was dumping ALL rows) (v0.7.0)","body":""},{"hash":"6e08a2b","date":"2026-07-26 17:14:47 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T17:14:46 (2 files) — src/ingest/parcels/engine.ts src/ingest/parcels/saltlake_ut.ts","body":""},{"hash":"d9054bf","date":"2026-07-26 16:46:25 -0700","author":"Steve","subject":"USRE grid: mobile filter access — rail opens as off-canvas drawer via a Filters button <820px (was display:none); reuses existing facets (v0.6.0)","body":""},{"hash":"02bd28c","date":"2026-07-26 16:44:37 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T16:44:36 (2 files) — public/crcp-grid.css public/crcp-grid.js","body":""},{"hash":"6924dcd","date":"2026-07-26 16:39:43 -0700","author":"Steve","subject":"USRE nav: render one canonical nav across all pages via nav-drawer.js (fixes drift; active-by-URL) v0.5.1","body":""},{"hash":"9ca6907","date":"2026-07-26 16:39:02 -0700","author":"Steve Abrams","subject":"Refine: add situs addresses to Sonoma/Maricopa/Thurston deed feeds + global future-date guard (dropped 39 bad-entry future sales)","body":""},{"hash":"55b0bc6","date":"2026-07-26 16:37:50 -0700","author":"Steve","subject":"USRE grid: active-filter summary bar + one-click clear-all; rail now renders from filter state (v0.5.0)","body":""},{"hash":"5f9ea95","date":"2026-07-26 16:27:41 -0700","author":"Steve","subject":"chore: v0.3.0 → v0.4.0 (session close — all-data-point filters + hamburger nav)","body":""},{"hash":"45f04ac","date":"2026-07-26 16:23:49 -0700","author":"Steve Abrams","subject":"Add Palm Beach FL deed adapter (complements parallel session's Miami-Dade); FL scout findings logged","body":""},{"hash":"896ac96","date":"2026-07-26 16:16:43 -0700","author":"Steve","subject":"USRE: collapse topbar into an upper-left hamburger drawer site-wide (shared nav-drawer.{css,js}) + clearance for grid/content pages","body":""},{"hash":"3d80035","date":"2026-07-26 16:14:27 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T16:14:26 (17 files) — public/admin.html public/brokers.html public/commercial-brokers.html public/commercial-feed.html public/commercial-property.html","body":""},{"hash":"4d66223","date":"2026-07-26 16:10:39 -0700","author":"Steve","subject":"USRE Markets: left-rail filters now cover ALL data points (derived from FIELDS)","body":""},{"hash":"d32c870","date":"2026-07-26 15:40:57 -0700","author":"Steve Abrams","subject":"wake: optimize bulk-flag UPDATE to pkey join (was 53min JSONB-expr seq-scan on 5M-row prod table)","body":"The bulk-flag UPDATE joined on extra->>'latest_deed' (JSONB, unindexable) — fine locally, but seq-scanned for ~53min on the remote 5M-row parcel table. Now: materialized CTE resolves bulk parcels to source_id, UPDATE joins on the PKEY (county_fips,source_id). Same pattern in miami/franklin adapters is a latent perf risk (deployed OK when table was smaller). TK-00026."},{"hash":"9a14bfd","date":"2026-07-26 15:10:50 -0700","author":"Steve Abrams","subject":"Scout round 2: add Crook OR (w/ names), Sonoma CA, Colorado composite (6+ counties), Maricopa AZ, Thurston WA deed adapters + robust price/date parsers; loop jobs","body":""},{"hash":"467ca96","date":"2026-07-26 14:57:33 -0700","author":"Steve Abrams","subject":"Add King County WA (2.4M full-history deeds) to loop on weekly cadence","body":""},{"hash":"d39bdf3","date":"2026-07-26 14:38:11 -0700","author":"Steve Abrams","subject":"wake: contrarian gate fixes — all-zero deed sentinel + pre-1971 epoch date","body":"(1) '000000-00000' null-deed sentinel (govt/ROW parcels, no deed on record) was bulk-flagging 429 parcels + creating 37 junk parcel_event doc_numbers — the in-memory guard caught '-' but not the all-zero form (same class as Miami's placeholder). Both deed guards now use ^[-0]*$ (memory + SQL + event doc_number). (2) epochToISO now rejects sub-1971 near-epoch artifacts. Verified: sentinel 0, junk events 0, bulk 62147->61718. Ticket TK-5.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"8699785","date":"2026-07-26 14:28:38 -0700","author":"Steve Abrams","subject":"parcels: add Wake County NC (37183) — 437k parcels, richest layer (owner+assessed value+sqft+year+sale)","body":"Authoritative Wake Assessor ArcGIS MapServer (the www data page 404s but the REST service is live+paginated). Dedicated streaming adapter (Miami DTD-B precedent). 437,112 parcels: 100% owner, 96% assessed LAND+BLDG+TOTAL value, 86% sqft, 87% year-built, 78% sale price -> 355k parcel_event rows current to 2024+. First county with assessed value+sqft+year populated. Deed-based in-DB bulk guard: 62,147 assemblage sales flagged. Ticket TK-5.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4118d04","date":"2026-07-26 11:09:44 -0700","author":"Steve Abrams","subject":"parcel coverage: record Broward (WAF) + Palm Beach (cached-only) FL dead-ends for next pass","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"ffad429","date":"2026-07-26 10:46:23 -0700","author":"Steve Abrams","subject":"brokers: add CT broker-side REB roster (fwpc-pgqj) — 16.8k brokers + 4.9k firms","body":"Completes the CT broker thread: ct_dcp had salespersons only (RES). New ct_dcp_reb adapter ingests the Real Estate Broker Licenses roster (21,754 REB credentials) — 16,833 individual brokers + 4,920 brokerage firms (type INDIVIDUAL vs LLC/CORP/PARTNERSHIP split), all with status+city. Separate source so REB.# never collides with RES.#; same canonical-code normalization. $0 SODA CSV.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"d409f98","date":"2026-07-26 10:09:35 -0700","author":"Steve Abrams","subject":"miami: contrarian gate fixes — placeholder-deed bulk false-positive + ghost sale events","body":"(1) The PA's all-zero '00000-00000' 'no deed on record' placeholder was grouping 12,285 un-recorded parcels into a fake assemblage and bulk-flagging them. Now excluded from latest_deed + bulk SQL (regex ^0+-0+$). Bulk flags 62,745->50,447 (all now real multi-folio deeds). (2) $0 non-arms-length transfers set last_sale_date but were filtered out of parcel_event -> 70,594 parcels with a last_sale_date pointing to a missing event. Now every dated transfer gets an event with doc_type Qualified/Unqualified/Non-Arms-Length (+297,491 events). Ghost rows 70,594->0. (3) Deterministic same-date sort tiebreak by slot. Verified.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"7dfbf4f","date":"2026-07-26 09:50:48 -0700","author":"Steve Abrams","subject":"parcels: add Miami-Dade FL (12086) via keyless ArcGIS PaGis — 937k parcels + 2.06M sales","body":"DTD verdict B (unanimous 5/5): dedicated full-universe adapter over extending the generic sale-cursor one. Streams the Property Appraiser MDC.PaGis layer (memory-safe batch upsert after a first attempt OOM'd holding 943k in RAM). 937,182 parcels: current owner (99.9%), address (95%), zoning (100%), use; up to 3 recorded sales each -> 2,064,976 parcel_event rows w/ price+grantor+grantee+deed+qualified flag, dates current to 2025. Bulk guard: 62,745 multi-folio-deed assemblages detected in-DB -> price nulled + flagged (no ParcelCount field, so deed-spans-multiple-folios is the signal). Top prices verified as real landmark commercial sales (Ponte Gadea, Brickell towers). No assessed value/beds/baths/sqft/year in the public layer.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9305f09","date":"2026-07-26 09:42:35 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T09:42:34 (2 files) — src/ingest/parcels/engine.ts src/ingest/parcels/miami_dade.ts","body":""},{"hash":"aa4b31c","date":"2026-07-26 08:57:29 -0700","author":"Steve Abrams","subject":"franklin: contrarian gate fixes — full-timestamp dedupe + bulk-sale price nulling","body":"(1) Same-date sales: date-only dedupe let a $0 grantor-side transfer (recorded at HH:00:00) beat the real arms-length sale one second later (HH:00:01), yielding wrong owner + null price on ~1289 parcels. Now rank by FULL timestamp, price-desc as secondary tiebreak. Verified 010-001903: FOX/null -> WILLIAMS/$206k. (2) Bulk sales (ParcelCount>1) stamped the full portfolio total on each parcel (1100 impossible >$10M, max $120M). Now null the unallocatable price + flag bulk_sale/bulk_parcel_count in extra (24,116 flagged); 72 legit large-commercial singles retained.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4c2251e","date":"2026-07-26 08:48:46 -0700","author":"Steve Abrams","subject":"parcels: add Franklin County OH (39049) via .gdb + GDAL — 122k parcels w/ owner/address/sqft/sale","body":"DTD verdict B: rich CAMA lives only in the auditor's 603MB monthly FileGeoDatabase (GDAL-only); polygon shapefile is geometry-only, www data pages WAF-walled. Adapter extracts the TaxParcelSale point layer (dedupe to latest sale/parcel) -> 122,047 parcels: site address (98%), owner=latest grantee (100%), use class, res sqft (85%), last sale date+price (66% arms-length), lat/lng (100% in-county). Honest sale-window label 2020-01..2023-05 in parcel_source. Documented GDAL exception + deploy path in FRANKLIN-RUNBOOK.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"32c8646","date":"2026-07-26 08:40:16 -0700","author":"Steve Abrams","subject":"Deschutes pageSize=1000 (server page cap) so pagination continues","body":""},{"hash":"9a64e4e","date":"2026-07-26 08:39:45 -0700","author":"Steve Abrams","subject":"Add Deschutes County OR deed adapter (real grantor/grantee NAMES + price, two sales/parcel)","body":""},{"hash":"90f2a67","date":"2026-07-26 08:33:06 -0700","author":"Steve Abrams","subject":"Spokane: per-source pageSize=500 (slow MapServer); all 3 deed adapters working","body":""},{"hash":"a3e4169","date":"2026-07-26 08:28:27 -0700","author":"Steve Abrams","subject":"Free priced-deed adapters (Oregon RLIS tri-county, Spokane WA, Alameda CA): config-driven ArcGIS sales ingest -> parcel_event(sale) w/ price+parties+links; wired to loop","body":""},{"hash":"c452e2e","date":"2026-07-26 08:20:24 -0700","author":"Steve Abrams","subject":"ct_dcp: normalize credential code to canonical RES.# source_id (contrarian gate fix)","body":"218 rows carried a legacy Socrata suffix (RES.#.INACTIVE) + 1 digitless RES stub — malformed upsert keys that would silently duplicate if upstream cleaned the field. Strip the suffix at parse, require a digit, delete+reingest. Verified: 96,988 CT rows now 100% canonical shape, 0 collisions with distinct persons.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"a74ceb3","date":"2026-07-26 08:13:32 -0700","author":"Steve Abrams","subject":"brokers: license_status filter (?status=active) on /api/brokers + Active-only UI toggle on directory","body":"Leverages the CT full-roster upgrade (status now populated on 97k CT + FL/DE/IL brokers) so the directory can show active licensees only. localStorage-persisted, matches existing srvbar controls.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4b82a3d","date":"2026-07-26 08:11:41 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T08:11:40 (1 files) — src/server/index.ts","body":""},{"hash":"9c0ce40","date":"2026-07-26 08:10:46 -0700","author":"Steve Abrams","subject":"Parcel coverage: 2026-07-26 re-probe intel (Franklin OH shp-dep, Wake drift, Miami off-Socrata)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"61b8b5c","date":"2026-07-26 08:08:30 -0700","author":"Steve Abrams","subject":"CT broker upgrade: full DCP salesperson roster (eqtn-rppv), 18k->97k w/ status+city+firm linkage","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9e65b77","date":"2026-07-26 07:52:43 -0700","author":"Steve Abrams","subject":"Self-correct: gate silent-break detection behind stableVolume flag (paging/rotating jobs have variable counts, don't false-degrade)","body":""},{"hash":"854bc7a","date":"2026-07-26 07:50:03 -0700","author":"Steve Abrams","subject":"Generalize SD adapter Poway->county-wide sweep (1.09M parcels, per-scope cursor, per-parcel city); loop sweeps county","body":""},{"hash":"f195028","date":"2026-07-26 07:42:44 -0700","author":"Steve Abrams","subject":"Property page: render deed events + public-record links (deep vs search-portal)","body":""},{"hash":"bb6c7e8","date":"2026-07-26 07:38:18 -0700","author":"Steve Abrams","subject":"Contrarian fixes: honest public-record links (deep vs search), no future years, baths/beds guards, forward-cursor resumability, history completeness flags","body":""},{"hash":"a2c4ea6","date":"2026-07-26 07:28:57 -0700","author":"Steve Abrams","subject":"Poway property-history pilot: SanGIS parcels + deed events + public-record links + property-page surfacing","body":""},{"hash":"aa800ba","date":"2026-07-26 07:18:44 -0700","author":"Steve Abrams","subject":"Per-state broker health + West-Coast-first geographic Places sweep + coverage board","body":""},{"hash":"33b1468","date":"2026-07-26 07:12:29 -0700","author":"Steve Abrams","subject":"Add /health engine status board + /api/ingest-health route","body":""},{"hash":"7ced2c2","date":"2026-07-25 13:38:51 -0700","author":"Steve Abrams","subject":"Self-correcting engine: health-aware loop (backoff, quarantine+probe, silent-break detection, per-source baseline)","body":""},{"hash":"2b38f61","date":"2026-07-25 13:36:35 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-25T13:36:34 (2 files) — db/migrations/009_source_health.sql src/jobs/self_correct.ts","body":""},{"hash":"8b31083","date":"2026-07-25 13:27:30 -0700","author":"Steve Abrams","subject":"Add hourly self-balancing ingest loop + Google Places discovery seed (free-tier capped)","body":""},{"hash":"289894d","date":"2026-07-24 08:20:59 -0700","author":"Steve Abrams","subject":"fix(sublease): reject non-finite numerics + malformed dates in admin insert","body":"Bad numeric input reached Postgres verbatim: Number('abc')=NaN → term_months (integer) 500s\n('invalid input syntax for type integer: NaN'), and sqft/asking_rate/lat/lng (numeric/double)\nsilently stored literal NaN, poisoning sorts + the map. available_date took any string → date\ncolumn 500 on a bad value. Now coerced to null (num/int/isoDate helpers) so bad input degrades\nto unset instead of a 500 or a NaN row.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"d7819af","date":"2026-07-23 14:55:34 -0700","author":"Steve Abrams","subject":"auth: add Scott login","body":""},{"hash":"8f27ada","date":"2026-07-23 14:51:19 -0700","author":"Steve Abrams","subject":"auth: add Boomer login (rentfree911)","body":""},{"hash":"2d8dfbe","date":"2026-07-23 14:42:17 -0700","author":"Steve Abrams","subject":"auth: support multiple Basic-Auth users (add Daniel), keep admin + env override","body":""},{"hash":"dc6baf0","date":"2026-07-22 20:24:42 -0700","author":"Steve","subject":"chore: harden sublease.ts (enum allowlists on status/lease_type/rate_period, status-aware total count), v0.2.0 (session close)","body":""},{"hash":"aa180e3","date":"2026-07-22 19:29:37 -0700","author":"Steve","subject":"add sublease inventory: table + /api/sublease GET + gated admin POST/DELETE","body":""},{"hash":"253038d","date":"2026-07-22 11:03:18 -0700","author":"Steve","subject":"Add /api/commercial/digest — one-shot marquee+briefs/recent/firms payload for RENTV syndication","body":""},{"hash":"17cdf50","date":"2026-07-22 10:35:42 -0700","author":"Steve","subject":"refresh-commercial: gate briefs on explicit REFRESH_BRIEFS=1 (deterministic; prod cron skips)","body":""},{"hash":"701cb10","date":"2026-07-22 10:34:32 -0700","author":"Steve","subject":"refresh-commercial: gate briefs on actual model name (prod has empty ollama, must skip)","body":""},{"hash":"f5468f1","date":"2026-07-22 10:33:15 -0700","author":"Steve","subject":"Fix refresh-commercial Ollama check: curl -sf + grep models (prod :11434 404 no longer triggers briefs)","body":""},{"hash":"2bfd4ff","date":"2026-07-22 10:28:10 -0700","author":"Steve","subject":"Add refresh-commercial.sh — daily refresh of CA DRE registry + LA commercial data","body":""},{"hash":"948bf60","date":"2026-07-22 09:47:18 -0700","author":"Steve","subject":"Deepen LA: commercial property-detail page unifying facts + brief + comps + firms","body":"- public/commercial-property.html: click any commercial asset -> full detail page with\n  the generated news brief as lede, assessed value breakdown (total/land/improvements),\n  building details, last-recorded date, comparable same-type assets in the same city,\n  and local LA real-estate firms (from the CA DRE registry). Ties together every layer\n  built this session (parcels + briefs + comps + broker intel) into one 'property page'.\n- Wired card/marquee/feed/story clicks across the explorer + feed to open it.\n- Verified headless: Beverly Center detail renders lede + 6 stats + 12 comps/firms, 0 errors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"45be23a","date":"2026-07-22 08:08:52 -0700","author":"Steve","subject":"Phase 5: CA DRE broker registry (FREE) + LA broker/firm intel surface","body":"- CA DRE turned out to be FREE (secure.dre.ca.gov/datafile/CurrList.zip, refreshed\n  daily) — no purchase needed. New src/ingest/brokers/ca_dre.ts adapter (unzip + CSV,\n  Corporation->firm, Broker/Salesperson->broker w/ employing-firm linkage).\n  Loaded 382,944 brokers + 34,727 firms in 17s.\n- index.ts: added city filter to /api/brokers + /api/firms (LA scoping).\n- public/commercial-brokers.html: LA firms ranked by agent count (surfaces CBRE 1,213,\n  Newmark, etc. — the major commercial houses), click-to-expand roster, broker search.\n  Wired into commercial nav. Verified headless: 200 firms + roster + broker tab, 0 errors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"04a19e4","date":"2026-07-22 07:18:52 -0700","author":"Steve","subject":"Phase 4: generated commercial news briefs (local Ollama, $0)","body":"- 006_commercial_briefs.sql + src/ingest/commercial/briefs.ts: local-LLM (qwen2.5)\n  generates one factual news-wire sentence per top/recent asset from assessor facts\n  only — strict guardrails against invented prices/owners/tenants ('assessed value'\n  never called a sale). 220 briefs generated, 0 failed.\n- commercial.ts: LEFT JOIN briefs into /marquee + /feed; new /api/commercial/brief/:ain.\n- Feed page gains a Featured-Assets story grid + inline briefs on activity items;\n  explorer marquee tiles show briefs. Verified headless: 9 stories + 79 item-briefs, 0 errors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"5de9ab3","date":"2026-07-22 07:12:11 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-22T07:12:00 (1 files) — db/migrations/006_commercial_briefs.sql","body":""},{"hash":"0b1ee1d","date":"2026-07-22 07:09:05 -0700","author":"Steve","subject":"Wire Commercial into main site nav across all pages (discoverability)","body":""},{"hash":"613b106","date":"2026-07-22 07:02:26 -0700","author":"Steve","subject":"LA commercial RE layer: taxonomy + materialized 153.9k parcels + explorer & news feed","body":"Repositions the platform toward local commercial real estate news, LA first.\n- src/lib/commercial_types.ts: use_desc2 -> canonical taxonomy (office/retail/\n  industrial/hospitality/studio/parking/other); Studio broken out for LA media assets.\n- 005_commercial.sql + src/ingest/commercial/la_assessor.ts: materialize the LA\n  assessor sqlite's 153,923 commercial+industrial parcels into pg commercial_parcel\n  (classified, city/zip parsed, indexed; multi-county-ready). LA has assessed value +\n  recording date, NO sale price/owner (roll limit) — never fabricated.\n- src/server/commercial.ts: /api/commercial/{types,cities,search,feed,marquee,property}.\n- public/commercial.html (explorer: marquee + filters + sort + density) and\n  public/commercial-feed.html (recent recorded activity, the local news feed).\n- Verified headless: 120 cards + 6 marquee + 8 filters / 80 feed items, 0 console errors.\n  Marquee surfaces real trophy assets (Beverly Center $995M, Bunker Hill towers).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e3663e8","date":"2026-07-21 19:24:08 -0700","author":"Steve","subject":"NYC ACRIS recorded sales -> PLUTO parcels (188k lots, 5 boroughs, $0 open data)","body":"Extends King-depth recorded sale prices to NYC, the platform's #1 metro — the\n'Sale/deed chain from ACRIS pending' gap on all five boroughs is now filled.\n\n- Keyset-streams ACRIS Master (priced deed-family + RPTT transfer docs) and Legals\n  (->BBL), joins in memory, single set-based UPDATE onto existing PLUTO lots.\n- Single-lot price attribution: document_amt is per-DOCUMENT, so multi-lot/portfolio\n  deeds are dropped (killed the $1.5B-on-a-house artifacts); trophy single-lot sales\n  (245 Park $1.77B, 424 5th/Amazon $978M) verified real.\n- Broad sale doc_type set (DEED family + RPTT&RET/RPTT) fixed Staten Island 1 -> 35,725.\n- Idempotent clear-then-apply (no residue across re-runs); retry-hardened SODA client\n  (429/5xx + network-timeout backoff, bounded per-request).\n- Result: 188,046 lots with recorded sales to 2026-06, 95% clean sale history.\n  Condo-unit deeds + buyer/seller (ACRIS Parties) noted as follow-up.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"14c95a8","date":"2026-07-21 19:09:21 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-21T19:09:20 (2 files) — src/ingest/parcels/nyc_acris.ts src/server/property.ts","body":""},{"hash":"4ade9ca","date":"2026-07-21 18:39:13 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-21T18:39:12 (3 files) — src/ingest/parcels/engine.ts src/server/property.ts src/ingest/parcels/nyc_acris.ts","body":""},{"hash":"5a71ca7","date":"2026-07-21 17:53:37 -0700","author":"Steve","subject":"M-B3 firm↔listing pilot: facts-only JSON-LD ingest of coldwellbanker + realtytexas (72 listings, 100% tied to holding firm), /api/listings + /api/firm/:id/listings, listings.html directory, robots-honored, blanket ingest gated","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"6b55694","date":"2026-07-21 17:38:45 -0700","author":"Steve Abrams","subject":"README: real coverage (5.78M parcels/8 counties, 1.5M brokers/7 states, firm crawl, King deed sales, /sources.html)","body":""},{"hash":"9acf65d","date":"2026-07-21 17:27:43 -0700","author":"Steve Abrams","subject":"M-B2: firm website discovery + front-page crawl — 002 firm_site/firm_contacts, Brave-search discovery (200/200 top firms; DDG anomaly-flagged), Playwright crawl (190 ok, 103 IDX, 348 contacts, robots honored), /api/firm/:id + site-coverage stats, inline firm detail in brokers.html, M-B3 pilot candidates in BROKER-COVERAGE.md","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"7b17d35","date":"2026-07-21 17:26:45 -0700","author":"Steve Abrams","subject":"M-P2 Cook County IL (17031): 1,863,530 parcels from Assessor Socrata open data — owner/taxpayer + mailing (2026 addresses), 2025 certified ASSESSED values (labeled 10%/25% basis), beds/baths/sqft/yr for 1.09M residential pins, parcel lat/lng; PARCEL-COVERAGE.md probe matrix (Maricopa GATED, LA owner/zoning ABSENT by policy, NYC DCP zip URL drift)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"841ad6f","date":"2026-07-21 17:25:40 -0700","author":"Steve Abrams","subject":"Public Records Sources page (/sources.html) — every open-data source the platform draws on, cited + coverage counts; 'use all public records' made visible; Sources nav across pages","body":""},{"hash":"a808341","date":"2026-07-21 17:23:43 -0700","author":"Steve Abrams","subject":"Consolidate agent M-P2/wave-2 work: Cook IL parcel adapter, parcel + broker coverage matrices","body":""},{"hash":"93eff11","date":"2026-07-21 17:20:10 -0700","author":"Steve Abrams","subject":"Broker wave-2: DE DPR adapter ingested (29,895 brokers + 997 firms via data.delaware.gov SODA), IL IDFPR adapter added","body":""},{"hash":"1c7f851","date":"2026-07-21 17:08:43 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-21T17:08:42 (8 files) — package.json public/property.html src/enrich/firm_website_discovery.ts src/server/property.ts data/screenshots/","body":""},{"hash":"2d46b43","date":"2026-07-21 17:03:47 -0700","author":"Steve Abrams","subject":"NYC search hardening: ordinal-stripping address normalization + nearest-house-number fallback ('350 5th Ave' now resolves the Empire State lot at 338 5 AVENUE); streaming CSV parser for the King/Cook adapters","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"}]}