{"slug":"nationalrealestate","total":336,"limit":100,"offset":0,"since":null,"commits":[{"hash":"d7eb08c","date":"2026-09-25 03:37:12 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-25T03:37:11 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"e5593f0","date":"2026-09-24 16:55:41 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-24T16:55:40 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"111bd3c","date":"2026-09-24 04:59:34 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-24T04:59:33 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"cfe5095","date":"2026-09-23 16:56:07 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-23T16:56:06 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"1bbf0dc","date":"2026-09-23 04:47:28 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-23T04:47:26 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"7504ccc","date":"2026-09-22 16:42:29 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-22T16:42:26 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"bbefb9b","date":"2026-09-20 03:20:18 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-20T03:19:32 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"40b0f9a","date":"2026-09-19 15:17:36 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-19T15:17:08 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"d439ad5","date":"2026-09-19 03:37:23 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-19T03:36:55 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"f03419d","date":"2026-09-18 16:30:40 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-18T16:30:11 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"70739fd","date":"2026-09-18 03:34:31 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-18T03:33:53 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"3f8f294","date":"2026-09-17 15:49:01 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-17T15:48:34 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"53f1bbc","date":"2026-09-17 03:59:05 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-17T03:58:38 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"b8dd1f7","date":"2026-09-16 15:44:07 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-16T15:43:40 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"86ffed0","date":"2026-09-16 04:08:13 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-16T04:07:45 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"72f804e","date":"2026-09-15 15:49:26 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-15T15:48:53 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"f411de8","date":"2026-09-15 03:56:33 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-15T03:56:10 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"f721e7f","date":"2026-09-14 15:42:08 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-14T15:41:36 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"47bd9ea","date":"2026-09-14 03:34:51 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-14T03:34:24 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"7cd663d","date":"2026-09-13 15:25:51 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-13T15:25:19 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"84ec1d4","date":"2026-09-13 03:42:52 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-13T03:42:21 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"fa65e36","date":"2026-09-12 15:36:11 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-12T15:35:41 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"3164d96","date":"2026-09-12 03:54:23 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-12T03:53:49 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"798d97c","date":"2026-09-11 16:23:53 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-11T16:23:14 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"c66a86f","date":"2026-09-11 03:51:42 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-11T03:51:39 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"ff9c32c","date":"2026-09-10 15:54:41 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-10T15:54:39 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"644425d","date":"2026-09-10 03:43:19 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-10T03:43:17 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"bc29ad5","date":"2026-09-09 15:36:07 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-09T15:36:04 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"f6c0c02","date":"2026-09-09 03:37:22 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-09T03:37:19 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"97d4b54","date":"2026-09-08 15:35:06 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-08T15:35:04 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"b3669a8","date":"2026-09-08 05:12:17 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-08T05:12:15 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"852add6","date":"2026-09-06 03:18:10 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-06T03:18:08 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"602b2c7","date":"2026-09-05 15:48:23 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-05T15:48:21 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"e7a2223","date":"2026-09-05 03:39:30 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-05T03:39:28 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"a94d5ce","date":"2026-09-04 15:31:53 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-04T15:31:50 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"53bc05a","date":"2026-09-04 03:55:14 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-04T03:52:16 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"b6424c8","date":"2026-09-03 15:07:44 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T15:07:41 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"611a2ae","date":"2026-09-03 03:29:46 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T03:29:44 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"0aa41a0","date":"2026-09-02 15:21:09 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-02T15:21:07 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"091b8ca","date":"2026-09-02 03:24:06 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-02T03:24:05 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"d4a54dd","date":"2026-09-01 15:29:46 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-01T15:29:45 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"80c020f","date":"2026-09-01 03:29:11 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-01T03:29:10 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"2eba198","date":"2026-08-31 15:44:49 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T15:44:48 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"8e929e2","date":"2026-08-31 11:32:40 -0700","author":"Steve Abrams","subject":"record TK-10155 production lifecycle proof","body":""},{"hash":"f8df3cd","date":"2026-08-31 10:06:09 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T10:06:07 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"130e6b0","date":"2026-08-30 03:31:24 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-30T03:31:23 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"d66d851","date":"2026-08-29 15:15:53 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-29T15:15:52 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"5aa5440","date":"2026-08-29 03:31:36 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-29T03:31:35 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"23dd8ae","date":"2026-08-28 15:49:00 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-28T15:48:59 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"cd5b8b3","date":"2026-08-28 03:24:49 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-28T03:24:48 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"d14f65e","date":"2026-08-27 15:43:17 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-27T15:43:16 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"789aa2f","date":"2026-08-27 03:25:20 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-27T03:25:19 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"357d200","date":"2026-08-26 15:16:04 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-26T15:16:03 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"28f9c56","date":"2026-08-26 03:25:34 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-26T03:25:32 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"8f5e0da","date":"2026-08-25 15:49:33 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-25T15:49:32 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"b408a56","date":"2026-08-25 03:23:01 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-25T03:23:00 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"ae4eb11","date":"2026-08-24 19:55:22 -0700","author":"Steve Abrams","subject":"TK-10155 (Cody FIX-FIRST): guarantee every listing has >=1 preserved snapshot","body":"Cody's contrarian panel returned FIX FIRST on the top surviving hole: a listing whose\nfirst-see snapshot hook FAILED (caught+logged) and that then derives straight to 'active'\n(first_seen already > NEW_DAYS, so it skips 'new') sits in the table with NO snapshot at all.\n'active' is deliberately not a SNAPSHOT_STATE, so recordLifecycle never captures one. The\n'data survives after the listing vanishes' promise then rested on 'nothing ever deletes a\nlisting' (true today — no DELETE FROM listing exists in the pipeline) rather than on the design.\nThe day a prune job lands, that listing's data would be lost (ON DELETE SET NULL just nulls an\nevent row pointing at nothing).\n\nFix — make preservation a design property:\n- export ensureBaselineSnapshot(db, listing): cheap NOT-EXISTS guard that captures ONE 'baseline'\n  snapshot iff the listing has zero snapshots; idempotent, append-only, no-op otherwise.\n- sweep calls it for every listing → every listing is guaranteed >=1 snapshot before it can ever\n  leave the table; reports 'baseline snapshots backfilled' count.\n- dbtest: reproduce the exact gap (active listing, event but no snapshot) and assert\n  ensureBaselineSnapshot rescues it + is idempotent.\n\nVerified on live local usre: 796 listings / 796 distinct snapshotted / 0 without a snapshot;\nsweep backfilled 0 (steady-state no-op). tsc clean, both self-tests PASS.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"83c8fb2","date":"2026-08-24 19:51:14 -0700","author":"Steve Abrams","subject":"TK-10155: lifecycle self-tests + fix withdrawal-snapshot FK to survive listing deletion","body":"- add src/server/listing-lifecycle.selftest.ts: pure DB-free unit test of classifyState\n  (every state branch, the fix-1 false-withdrawal guard, status-string precedence) +\n  recordLifecycle transitions/snapshot logic driven by an in-memory fake db. npm run test:lifecycle.\n- add src/server/listing-lifecycle.dbtest.ts: end-to-end withdrawal-snapshot self-test on the\n  real schema (house provenance-selftest pattern: synthetic source, assert, purge). Proves a\n  withdrawn listing preserves a full snapshot AND that the snapshot still reconstructs the\n  listing after the listing row is DELETED. npm run test:lifecycle:db.\n- migration 023: change listing_lifecycle_event/listing_snapshot listing_id FKs from the\n  shipped NO ACTION to ON DELETE SET NULL. Migration 014 called these columns 'nullable: a\n  listing may vanish/be deleted' but the FKs BLOCKED that delete (error 23503) — so the\n  'data survives after the listing vanishes' promise could not hold. SET NULL keeps every\n  event/snapshot (source/source_id/address_key/snapshot JSONB intact), only nulling listing_id.\n- applied 023 to the LOCAL usre dev DB (reversible: re-add FK as NO ACTION). Kamatera-canonical\n  prod apply is drafted to pending-approval, NOT run here.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"958bcb3","date":"2026-08-24 15:30:56 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-24T15:30:55 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"4572db9","date":"2026-08-24 12:26:41 -0700","author":"Steve Abrams","subject":"chore: v0.22.1 — Snohomish WA (53061) priced-deed feed (session close)","body":"Author: steve@designerwallcoverings.com"},{"hash":"b4a6245","date":"2026-08-24 11:12:31 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-24T11:12:29 (1 data files) — package-lock.json","body":""},{"hash":"122ebb1","date":"2026-08-24 10:56:41 -0700","author":"Steve","subject":"chore: v0.22.0 (session close — 3 west-coast priced-deed feeds: josephine 41033, whatcom 53073, snohomish 53061)","body":""},{"hash":"86cb190","date":"2026-08-24 09:31:18 -0700","author":"steve@designerwallcoverings.com","subject":"Snohomish County WA (53061): add free priced-deed feed (arcgis_sales) — TK-16","body":"ArcGIS Online Recent_Property_Sales FeatureServer (keyless). 17,171 priced\nsales of 21,734. Mon-YYYY date parse via local snoDate() (shared anyDate\nuntouched); comma-string SALE_PRICE via anyPrice; polygon->centroid latlng.\nOBJECTID in outFields for stable resultOffset paging (contrarian-flagged).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"d7d2c15","date":"2026-08-24 09:28:39 -0700","author":"Steve","subject":"TK-16: add Josephine County OR (41033) free priced-deed feed","body":"Rich clean-key ArcGIS Assessor_Taxlots feed: 30,140 priced sales w/ SALE_PRICE\n+SALE_DATE+DEED_TYPE+INST_NO(doc)+situs+owner+RMV value+YR_BLT/SQ_FT/BEDRMS+\nexplicit Latitude/Longitude (no geometry download). Config in arcgis_sales.ts,\nadapter appended in engine.ts, deeds-josephine loop job (3h), SOURCES.md.\nVerified local usre: 5,997 parcels/5,993 events (all doc#, 19 deed types,\n1970-2026, $1.5k-$46.9M). tsc 0 errors. Prod deploy + backfill Steve-gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"1326a54","date":"2026-08-24 04:27:02 -0700","author":"steve@designerwallcoverings.com","subject":"Whatcom WA: add situs/owner join + SWDSales2020/2021 history layers (TK-10777)","body":"- scripts/enrich-whatcom-situs.mjs: batch POSTs to WhatcomCo_Property (geo_id join),\n  fills address/city/owner_name/use_desc for all 5157 Whatcom parcels (4480 enriched)\n- src/ingest/parcels/arcgis_sales.ts: add whatcom-2021 (layer /1) + whatcom-2020 (layer /0)\n  history source configs with history:true flag; add upsertParcelHistory import\n- src/ingest/parcels/upsert.ts: add upsertParcelHistory() — COALESCE fill + date-guard\n  on last_sale_date/price (never regresses a newer sale with an older history record)\n- src/ingest/parcels/engine.ts: route whatcom-2020 / whatcom-2021 adapters\n- src/jobs/hourly_loop.ts: schedule deeds-whatcom-2021/2020 at 168h (weekly, historical)\n\nCost: $0 (ArcGIS REST is free)"},{"hash":"17bb441","date":"2026-08-24 03:41:18 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-24T03:41:17 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"0195411","date":"2026-08-23 15:28:59 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-23T15:28:58 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"f794458","date":"2026-08-23 04:19:32 -0700","author":"Steve Abrams","subject":"TK-10687: add DRE enrichment strategy memo","body":"Documents current state (385k CA DRE licensees, 0.09% phone coverage), what DRE\npublic data actually provides (address but NOT phone/email), and the 3-tier $0\nenrichment path: DRE address lookup → address-qualified SERP → DBA name search.\nIdentifies 5 large high-value firms (19k+ brokers between them) with found-but-unwritten\nphones as the fastest quick win. Recommends resorting enrichment by active_broker_count\nDESC rather than firm ID to maximize early yield.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"05583db","date":"2026-08-23 04:18:18 -0700","author":"Steve Abrams","subject":"TK-10681: add enrich-firms-serp.js — SERP-only residential firm enrichment (no Ollama, JSONL output)","body":"Lighter SERP enrichment path alongside the existing enrich-firm-contacts.mjs (which requires\nOllama). This variant uses pure regex phone/email extraction from Bing + DDG HTML search results,\noutputs a JSONL file instead of writing to the DB, and caps at 200 firms/run with 1 req/2s\nrate limiting. 20-firm pilot: 0/20 actionable finds on the oldest license-number cohort\n(likely defunct firms); false-positive rate on that cohort is high without Ollama validation.\nComplement the existing enrichment run rather than replace it.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"cd32cb6","date":"2026-08-23 03:15:27 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-23T03:15:26 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"8c9721a","date":"2026-08-22 15:34:48 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-22T15:34:47 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"9a3b0b1","date":"2026-08-22 03:19:30 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-22T03:19:29 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"b77e37b","date":"2026-08-21 15:40:22 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-21T15:40:21 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"7e7a803","date":"2026-08-21 08:01:31 -0700","author":"Steve Abrams","subject":"chore: v0.21.0 (session close — Whatcom feed + tsc fix)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"db793c9","date":"2026-08-21 06:35:14 -0700","author":"Steve Abrams","subject":"fix(tsc): broker_website_discovery — verifyAgentSite param license_state (unbreaks repo-wide tsc)","body":"Pre-existing TS2345 at lines 183/259: BrokerRow has license_state but verifyAgentSite\nrequired 'state'. Renamed the param + prompt usage to license_state. Repo-wide tsc now 0 errors.\nFound + fixed under /yoloforever cycle 2 (Cody hole #3). Local only, no push.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"58652bd","date":"2026-08-21 03:25:41 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-21T03:25:40 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"6c891d0","date":"2026-08-20 19:59:21 -0700","author":"Steve Abrams","subject":"TK-16 pass4: add Whatcom County WA (53073) priced-deed ArcGIS feed (5189 sales)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e41fdd7","date":"2026-08-20 15:11:43 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-20T15:11:42 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"438160a","date":"2026-08-20 08:14:34 -0700","author":"Steve Abrams","subject":"nav-agent: sync v1.3 (host left-sidebar collapse on load)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"912ab65","date":"2026-08-20 03:38:47 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-20T03:38:46 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"fd80fc1","date":"2026-08-19 15:40:40 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-19T15:40:38 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"2f184d3","date":"2026-08-19 14:31:01 -0700","author":"Steve","subject":"nav-agent: List data full-width tight columns (grid) — layout fix","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"ab4fd59","date":"2026-08-19 14:05:22 -0700","author":"Steve","subject":"Refresh nav-agent to v1.2 (adds kv-list compact List view, default-off)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"b4ad42f","date":"2026-08-19 13:48:40 -0700","author":"Steve Abrams","subject":"chore: v0.20.1 (session close — watchlist toFixed crash fix; lint ✓)","body":""},{"hash":"63d794e","date":"2026-08-19 13:23:12 -0700","author":"Steve","subject":"Fix watchlist.html crash: v.toFixed on string values","body":"The API returns score/pct/usd as strings, but the fmt formatters called\nv.toFixed()/Math.round(v) directly — 'v.toFixed is not a function' broke the\npage render. Coerce with +v and NaN-guard all three. Found via the RE-fleet\ncrash smoke.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"95e9e65","date":"2026-08-19 03:46:08 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-19T03:46:07 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"3f59bcb","date":"2026-08-18 15:36:48 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-18T15:36:46 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"36ef14f","date":"2026-08-18 14:00:31 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-18T14:00:27 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"4855043","date":"2026-08-18 13:58:18 -0700","author":"Steve Abrams","subject":"usre: CA-area-code guard on firm-phone enrichment (TK-10687)","body":"Domain-token matching alone still false-matched shared surnames onto wrong\nbusinesses (payneglasses.com, douglascuddletoy.com TOYS, jacuzzi.com hot-tubs,\nbaileyhats.com, grandviewhealth.com). Since every firm in scope is CA-licensed, the\noffice line is a CA area code — require one. Kills the out-of-state wrong-business\nmatches at ~zero cost. Cleaned 16 non-CA false writes. Precision-first: better no\nnumber than a wrong one for a directory Frank calls.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"88312fc","date":"2026-08-18 13:47:11 -0700","author":"Steve Abrams","subject":"usre: Tier-1 accurate firm-phone backfill from cre office lines (TK-10687)","body":"Promotes the SHARED office switchboard (a canonical phone 2+ brokers at a firm use,\nper the vetted cre.broker/Crexi data) into usre.firm — no web, instant, high accuracy.\nGuards: canonicalize phones before counting (format variants fragmented the share\ncount), skip toll-free + mega-brokerages (their corporate line must come from their\nown site, not one agent's record). 16 verified LA office lines matched (Major\nProperties 8-broker line, Lee & Associates 5, Oppenheim Group 3). COALESCE-only,\nprovenance 'cre-backfill'. $0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e72841d","date":"2026-08-18 13:43:23 -0700","author":"Steve Abrams","subject":"usre: harden firm-phone enrichment for accuracy (name-match gate, Bing, dedup) (TK-10687)","body":"A call directory must not guess — a wrong number wastes Frank's time. Hardening:\n- NAME-MATCH GATE: trust a discovered phone ONLY from the firm's own known site or a\n  DOMAIN carrying the firm's distinctive name token (serhant.com, colliers.com,\n  axencareers.com). Kills the Bing false matches (baseball-reference / cabq.gov /\n  southpointcasino / visitpasadena) that common-word firm names pulled in.\n- Expanded stop-list (geo/directional/generic words) + NONBIZ blocklist (tourism/gov/\n  wiki/social) so place-named firms don't match a city tourism site.\n- Prefer OWN domain over aggregators; drop aggregator TOLL-FREE lead-lines; confidence\n  tag in phone_source (web-own / web-agg).\n- DEDUP: never stamp a phone already assigned to a different firm (shared switchboard).\n- Bing primary discovery (DuckDuckGo rate-limited the IP) + DDG fallback; plausible-\n  area-code filter. Precision-first: generic-named firms stay 'unverified' (honest)\n  rather than get a wrong number. $0 (local model + local fetch + free search).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"b3eef68","date":"2026-08-18 13:28:18 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-18T13:28:17 (1 data files) — data/firm-phone-coverage.json","body":""},{"hash":"a05bd0f","date":"2026-08-18 13:28:14 -0700","author":"Steve Abrams","subject":"usre: firm-phone coverage canary + incremental enrichment cron (TK-10687)","body":"firm-phone-coverage.mjs (READ-ONLY): tracks 'every firm has a phone / every broker\ncallable' — % of CA active-broker firms with a phone + % of active brokers with a\nresolvable phone (own/firm/firm_contacts fallback); emits PASS/WARN/FAIL + writes\ndata/firm-phone-coverage.json. Baseline: brokers 20.1% callable, 21,720 firms\nphoneless. Cron (com.steve.firm-phone-enrich, 02:30/14:30, limit 400/run, $0 local,\nskips if Ollama down) chips the queue highest-leverage-first + logs coverage each run.\nLocal usre writes only; Kamatera sync stays gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4cd353f","date":"2026-08-18 13:26:16 -0700","author":"Steve Abrams","subject":"usre: firm-phone-first contact enrichment driver (agents+local model, $0) (TK-10687)","body":"Steve: 'every firm business must have a phone' + 'every broker callable'. Resumable,\nidempotent, cron-friendly driver over the ~21.7k CA firms that have an active broker\nbut no phone (ordered by active-broker count desc = biggest leverage first). Per firm:\nTier A known website + /contact + /about, Tier B free DuckDuckGo discovery; fetch =\nplain HTTP -> local headless Chrome fallback for anti-bot; extraction = regex\ncandidates + LOCAL Ollama qwen3:14b picking the business's main phone/email/address\n(never trusts a phone outside the candidate list). Writes firm.phone/email/\nstreet_address + *_source + firm_contacts + phone_status (COALESCE-only, provenance\ntagged, --apply gated; dry-run default). $0 (local model + local fetch + free search).\nProven: top-3 firms (eXp 4971, Real 4955, Compass 3683 active brokers) all got phones\n-> ~13.6k broker cards callable via the firm fallback.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"7d88094","date":"2026-08-18 12:55:52 -0700","author":"Steve Abrams","subject":"usre: resolved broker phone + firm-fallback tier + email/address on the desk (TK-10687)","body":"Every broker must be callable (Steve). /api/brokers now returns a single resolved\nphone = broker.phone || firm.phone || firm_contacts.phone, plus phone_tier\n(direct|firm) so the UI can badge the firm fallback; also resolved email + address.\nbroker-desk.js renders a contact row (tel:/mailto: + tier badge + 'phone pending'\nwhen none). Migration 022 adds firm contact-enrichment columns (phone_source, email,\nemail_source, contact_enriched_at, contact_attempts, phone_status) + a missing-phone\nwork-queue index. Verified live: a direct-line-less broker now shows the firm phone\ntagged 'firm'. Local only; Kamatera migration + deploy stay gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"2492689","date":"2026-08-18 11:07:27 -0700","author":"Steve Abrams","subject":"chore: v0.20.0 (session close — DRE firm contact card shipped live; refactor deferred, enrich files in-flight)","body":""},{"hash":"65cab77","date":"2026-08-18 10:38:35 -0700","author":"Steve Abrams","subject":"residential enrichment: --asset scoping on free SERP discovery + email crawl reads firm_site.url (chains discovery→email); order both by agent_count DESC for max broker-card leverage (TK-10669)","body":""},{"hash":"de5e83f","date":"2026-08-18 10:04:54 -0700","author":"Steve Abrams","subject":"firm email crawl: survive stray HTTP/2 session errors (uncaughtException guard) so one remote GOAWAY can't kill the background run (TK-10669)","body":""},{"hash":"5a7ce2a","date":"2026-08-18 10:03:40 -0700","author":"Steve Abrams","subject":"firm email collection: crawl public contact emails off firm sites into firm_contacts (collect-only, no sending); surface primary email on the card + /api/firms; guard malformed-mailto crash (TK-10669)","body":""},{"hash":"d1ab982","date":"2026-08-18 09:23:22 -0700","author":"Steve Abrams","subject":"firm API: surface phone/website/street_address in /api/brokers + /api/firms + /api/firm/:id so RENTV/CRCP proxies render the full contact card (TK-10669)","body":""}]}