Homesonspec
Search the build
-
ed938c0f2026-09-13 Publish a fleet-health heartbeat: this poller was invisible to the rollup -
471d15682026-09-13 Poller: notify() must never be able to fail its caller -
043c09b72026-09-13 Apple review poller: stop disarming itself while awaiting Apple -
fb984ed62026-09-11 eas: pin production ios.image=latest (ITMS-90725 guard) -
42bd99352026-09-11 Record verified production ValidationEvent partitioning -
df934fe22026-09-11 auto-data-snapshot: 2026-09-11T08:57:34 (9 data files) — ops/TK-11364-validationevent-approval.md ops/o3-partition-PROVEN-runbook.md verification/TK-11364/app-after.jsonl verification/TK-11364/independent-after.txt verification/TK-11364/previous-e2e-proof.json -
90b58b812026-09-11 Rehearse and harden ValidationEvent partition conversion -
360338112026-09-10 Reconcile TK-11364 partition state and document remaining approval gate -
0200179c2026-09-10 TK-11303: retire stale v1 apple-review launchd plist (superseded by v2 wrapper) -
31581ff82026-09-10 TK-11364: version + golden-lock the TK-11125 guard's canonicalization contract -
3e4d499f2026-09-10 O3b: ValidationEvent partition conversion script (corrected pattern) -
0f94115d2026-09-10 O3: add grant script so future partitions inherit the app-role ACL -
cc0a05162026-09-10 O3: fix the two bugs the live run exposed (FK-before-attach stall, missing GRANTs) -
a15775f62026-09-10 O3: add prod apply script for the partition conversion -
d6400d4d2026-09-10 O3: prove SourceEvidence partitioning is feasible with no rewrite and no data-model change -
82fadf192026-09-10 ops: preflight now VALIDATES the rollback dump instead of suggesting it (TK-11364) -
616032a62026-09-10 ops: fix preflight rollback check reporting a false "no backup" (TK-11364) -
14ed19042026-09-10 ops: make Phase-2 preflight actually enforce the disk gate (TK-11364) -
88e393b72026-09-10 docs: correct stale/false facts in O3 partition plan (TK-11364) -
324163912026-09-10 Require configured slots for manual AdSense units -
6c9cd93d2026-09-09 TK-11341: add AdSense Auto-Ads loader + ads.txt (revert to remove ads) -
aaf2c4872026-09-04 snapshot before restart: preserve in-flight work -
ba37b54c2026-09-04 mobile: make the tracker-drift canary baseline-aware (was firing on steady state) -
693125b22026-09-04 mobile: add tracker-drift canary guarding the 'Data Not Collected' privacy label -
90ca06fc2026-09-04 auto-data-snapshot: 2026-09-04T11:31:34 (65 data files) — apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Assets.car apps/mobile/_recovered/hx/Payload/HomesonSpec.app/EXConstants.bundle/Info.plist apps/mobile/_recovered/hx/Payload/HomesonSpec.app/EXConstants.bundle/app.config apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Expo.plist apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoApplication_privacy.bundle/Info.plist -
7cf4bed82026-09-04 verify Apple review poller lifecycle -
672b96892026-09-04 add App Store review completion poller -
a656c9b92026-09-04 auto-data-snapshot: 2026-09-04T10:10:38 (1 data files) — apps/mobile/_recovered/homesonspec-build2.ipa -
307603c22026-09-04 record successful iOS review resubmission -
29dc18712026-09-04 mobile: repair App Store Connect key path -
d8531bc32026-09-04 TK-10337: preserve final iOS device proof -
46e6b2192026-09-04 auto-data-snapshot: 2026-09-04T08:26:29 (1 data files) — apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-mapfixed-2026-09-04T15-31-01Z.mov.privacy-reviewed.sha256 -
4df903f12026-09-04 mobile: cap rendered map markers (120, densest-first) + lower grid density — fix react-native-maps on-device OOM crash on the Map tab (TK-11155) -
f2de197d2026-09-04 Homes on Spec: actually test the tracker-blocking script (TK-10387) -
16d8e5af2026-09-04 auto-data-snapshot: 2026-09-04T06:32:13 (1 data files) — apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-BUILD3-2026-09-04T13-10-12Z.mov.privacy-reviewed.sha256 -
2726cf352026-09-04 Homes on Spec: correct stale README claims that misled a downstream review (TK-10387) -
d98894aa2026-09-03 Homes on Spec: route every WebView through one hardened TrackedWebView (TK-10387, DTD verdict A) -
92f06c152026-09-03 mobile: make Alerts an inert coming-soon state — disable the toggle + stop it requesting notification permission until push is wired (App Store 2.1/5.1.1v hardening, TK-11155) -
754ecba22026-09-03 auto-data-snapshot: 2026-09-03T15:45:08 (1 data files) — apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-2026-09-03T22-28-13Z.mov.privacy-reviewed.sha256 -
edbd43882026-09-03 web: large mobile-only brand logo leading the homepage hero (TK-11155) -
b233a41e2026-09-03 web: disable the site-wide InstallPrompt PWA banner (TK-11155) -
e387ffba2026-09-03 web+mobile: stable data-hos-install-prompt hook + hide banner in app WebView (TK-11155) -
9b533a902026-09-03 mobile: regenerate splash.png as a large full-screen brand logo (TK-11155) -
13331cf62026-09-03 snapshot before TK-11155 logo/PWA-banner sweep (pre-existing: tracker-policy extraction, debug-log cleanup, device capture evidence) -
febf413e2026-09-03 auto-data-snapshot: 2026-09-03T14:29:24 (1 data files) — apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-2026-09-03T21-10-10Z.mov.privacy-reviewed.sha256 -
e44f3a5f2026-09-03 fix(homesonspec-mobile): add missing app/index.tsx to fix infinite splash hang on real device (TK-11155) -
3a5453462026-09-03 auto-data-snapshot: 2026-09-03T13:47:49 (2 data files) — apps/mobile/package.json pnpm-lock.yaml -
6f64cefe2026-09-03 snapshot before TK-10337 rejection debugging -
9e884ed12026-09-03 HoS mobile: block GTM/GA4/Facebook trackers in Browse WebView (Guideline 2.1 Path B) -
6a1800df2026-09-02 TK-11125: e2e-proof evidence bundle for the payload guard (R3, scratch DB) -
319168ad2026-09-02 TK-11125: forward-only spurious-generation guard in extractStage -
671fbb262026-09-02 TK-11125: add stableStringify + payloadHash canonical hash helper (shared) -
c97856c62026-09-01 defer SourceEvidence reindex pending bloat evidence -
b9a448312026-08-31 TK-10878: monthly SourceEvidence VACUUM/REINDEX maintenance (ready+gated) + plan PHASE 3 delivered -
ddb43e672026-08-31 TK-10878 Phase 2 drafts: fix 3 fatal + 2 hardening review findings -
21b9aad62026-08-31 docs(homesonspec): TK-10878 Phase 2 drafts — pg_partman SourceEvidence conversion + provenance-safe retention (not applied) -
7114f6a32026-08-31 fix(homesonspec): summit planName cuts at first '<' — no raw markup on fresh crawls (TK-10487) -
8ffc69512026-08-30 fix(homesonspec): correct 2 more dead CPG seed termsUrls (brohn/summit /terms-of-use 404 -> claytonhomes.com/legal) (TK-10487) -
a03350752026-08-30 test(homesonspec): backfill committed selftests for brohn/oakwood/summit — all 13 CPG collectors now fixture-verified (TK-10487) -
3a4b583a2026-08-30 auto-data-snapshot: 2026-08-30T23:23:51 (5 data files) — collectors/brohn-homes/.gitignore collectors/brohn-homes/fixtures/homes/_urls.tsv collectors/oakwood-homes/.gitignore collectors/oakwood-homes/fixtures/homes/_urls.tsv collectors/summit-homes-kc/fixtures/homes/_urls.tsv -
57212c912026-08-30 fix(homesonspec): correct dead Oakwood seed domain oakwoodhomesnc.com(000) -> live oakwoodhomesco.com (TK-10487) -
7fd3d9fe2026-08-30 docs(homesonspec): wire offload-preflight as mandatory step-0 GO/NO-GO in the runbook — toolkit now turnkey (TK-10809) -
c3626f012026-08-30 docs(homesonspec): record completed 13-brand CPG roster + corrected authoritative list (TK-10487) -
bab4fd972026-08-30 ops(homesonspec): read-only offload PREFLIGHT GO/NO-GO — dest capacity + live-crawl + DB checks before the gated 155G rsync (TK-10809) -
235736eb2026-08-30 fix(homesonspec): berkeley-building — real self-card isolation test + status docs (TK-10487 Cody gate) -
6343338a2026-08-30 test(homesonspec): wire ops/*.test.mjs into npm test — snapshot-offload safety suite now runs in regression (TK-10809) -
c57211a82026-08-30 auto-data-snapshot: 2026-08-30T20:54:26 (1 data files) — pnpm-lock.yaml -
669907fb2026-08-30 add collision-safe Florida Highland collector -
78e4b4f12026-08-30 add Berkeley Building CPG collector -
189933f62026-08-30 auto-data-snapshot: 2026-08-30T13:27:48 (5 data files) — collectors/berkeley-building/.gitignore collectors/berkeley-building/fixtures/homes/_urls.tsv collectors/berkeley-building/package.json collectors/berkeley-building/tsconfig.json pnpm-lock.yaml -
9eb0f3212026-08-30 wire(homesonspec): register Elite Homes (Louisville KY CPG) collector (TK-10487) -
d575caa22026-08-30 feat(homesonspec): Elite Homes (Louisville KY CPG) collector (TK-10487) -
c233bfe92026-08-30 wire(homesonspec): register Silverthorne Homes (Indianapolis CPG) collector (TK-10487) -
f0d509ba2026-08-30 feat(homesonspec): Silverthorne Homes (Indianapolis CPG) collector (TK-10487) -
86d5d2492026-08-30 wire(homesonspec): register Arbor Homes (Indianapolis CPG) collector (TK-10487) -
9e1cea832026-08-30 feat(homesonspec): Arbor Homes (Indianapolis CPG) collector — yourarborhome.com (TK-10487) -
99a991d92026-08-30 add Legacy Alabama CPG collector -
ea4d4aee2026-08-30 auto-data-snapshot: 2026-08-30T10:57:58 (3 data files) — collectors/arbor/fixtures/homes/_urls.tsv collectors/arbor/package.json collectors/arbor/tsconfig.json -
ab1b4f742026-08-30 fix(homesonspec): harris-doyle uses authoritative dataLayer, not fragile DOM (TK-10487 Cody gate) -
473713d52026-08-30 Build and register Harris Doyle collector -
73a0e94f2026-08-30 TK-10809: snapshot-verify catches DEST symlink false-green before gated delete -
915bd9c22026-08-30 TK-10809: add ops/OFFLOAD-RUNBOOK.md (SAFE prod offload ordering, deletion hard-blocked until legacy-abs rewrite) -
66e0038c2026-08-30 TK-10809: extract classifyForDest pure fn + hermetic verify test; offload VERIFY loop calls it (no behavior change) -
a7904b1e2026-08-30 fix(homesonspec): correct fabricated CPG termsUrls in seed (TK-10487) -
ef2532252026-08-30 Record TK-10809 post-commit proof -
cece23b92026-08-30 Harden snapshot offload verification boundaries (TK-10809) -
ca3c67b32026-08-30 Add Mungo and Chafin CPG collectors -
aff879072026-08-30 TK-10809: offload VERIFY — no false PASS on a sample, tally wrong --src -
d461d39d2026-08-30 TK-10809: single shared snapshot-path resolver (ops/lib), kill 3-way drift -
58cad18e2026-08-30 ops: non-destructive snapshot offload+verify script + read-only integrity canary (TK-10809) -
0a7e6b342026-08-30 snapshot store: store storagePath relative + resolver for volume-move safety (TK-10809) -
7d5c17e62026-08-27 pm2(homesonspec): node-direct next start so pm2 owns the port-holder PID (TK-10499) -
7312ce4b2026-08-26 docs(homesonspec): STEP 1 APPLIED on prod — record actual method + 2 gotchas (owner-role DDL, deploy over-applies add_inventory_specs) + flag 24-day pending migration (TK-10878) -
019ab4e82026-08-26 docs(homesonspec): O3 partition + add-disk plan (Steve-chosen path) — disk-first ordering, pg_partman raw-SQL migration, size canary (TK-10878) -
26657d752026-08-26 docs(homesonspec): runbook reflects measured reality — index-drop is real STEP 1, corrected apply/verify/rollback (TK-10878) -
63fa11852026-08-26 db(homesonspec): guard TK-10878 index-drop with lock_timeout=3s; document CONCURRENTLY-vs-Prisma-txn tradeoff + concurrent-rebuild rollback (codex review) -
bd19db5f2026-08-26 db(homesonspec): drop unused ValidationEvent(ruleId,passed) index — 0 scans, ~508MB reclaim (TK-10878) -
5f8d356c2026-08-26 ops: DB reclaim runbook (TK-10878) — O1 dedup + O3 partition + revised-O2 truncate; O2-null rejected (public page renders the columns); Cody disk-abort gate -
67563c202026-08-24 auto-data-snapshot: 2026-08-24T04:45:01 (6 data files) — collectors/chafin-communities/package.json collectors/chafin-communities/selftest-live.mts collectors/chafin-communities/tsconfig.json collectors/mungo-homes/package.json collectors/mungo-homes/tsconfig.json -
e1d685cb2026-08-17 Add Summit Homes KC collector adapter (TK-10487 batch 2) -
d55131532026-08-13 HomesOnSpec search: make Table columns bidirectionally sortable (TK-10526) -
1ee4dcd72026-08-13 HomesOnSpec search: add Grid/List/Table view modes + broadened server-side sort -
db6c10ce2026-08-12 chore: HomesOnSpec safe full-web deploy runbook (build-gated + git-rollback) + v0.3.2 (TK-10488); drop superseded piecemeal script -
a2a0172b2026-08-12 homesonspec: send scoped Basic auth to usre contractor API (TK-10488) -
552d6aa22026-08-12 HomesOnSpec: date-stamp nearby-subs — per-row CSLB issue/expire dates + data-as-of provenance + status=CLEAR -
86f64f402026-08-12 HomesOnSpec: 'Find subs near this home' — nearby licensed CA trades on the home detail page -
d89b21a72026-08-12 chore: sync pnpm-lock.yaml for new collector workspace deps (session close) -
ecee95ff2026-08-12 chore(workers): v0.1.0 → v0.2.0 (session close — 5 new builder adapters integrated: mi-homes, smith-douglas, goodall, brohn, oakwood) -
1b56601e2026-08-12 auto-data-snapshot: 2026-08-12T09:25:42 (2 data files) — collectors/summit-homes-kc/package.json collectors/summit-homes-kc/tsconfig.json -
4c9e0afc2026-08-12 TK-10487: oakwood constructionStatus prefers authoritative KOVA Status (contrarian fix) with deterministic date fallback -
d3c30ea12026-08-12 TK-10487: build Goodall + Brohn + Oakwood CPG per-brand adapters (batch 1); register all 3, typecheck green -
e10bc5b72026-08-12 oakwood-homes: facts-only inventory adapter (Nuxt SSR + KOVA ERP payload) -
019131952026-08-12 collectors/goodall-homes: facts-only inventory adapter (Clayton Properties Group brand) -
cfab6b8f2026-08-12 auto-data-snapshot: 2026-08-12T08:54:38 (2 data files) — collectors/brohn-homes/package.json collectors/brohn-homes/tsconfig.json -
62b2c3cb2026-08-12 homesonspec search: drill() merges active rail filters (union multi-value st/builder/status) so a card drill narrows context instead of clobbering other selected states (TK-10482 contrarian SHOULD-FIX) -
4d9cd0412026-08-12 HomesOnSpec: property detail parcel/public-records block + href-drill atoms on listings grid (TK-10482) -
be9e4af22026-08-12 TK-10001: deploy-kamatera.sh frees :9975/:9976 from orphaned next-servers before pm2 start (fixes EADDRINUSE crash-loop that hung homesonspec.com web tier) -
303b860f2026-08-11 TK-10001 go-live: activate+ingest mi-homes(25)+smith-douglas(25) to local DB; document MI_STATE=texas footgun + deploy hardening -
4ee4bf922026-08-11 TK-10001: pipeline/verify scripts load root .env via tsx --env-file (fixes 'DATABASE_URL not found' on manual pipeline runs) -
66c7ded32026-08-11 TK-10001: harden deploy-kamatera.sh — pre-drop pg_dump backup (recoverable full-mirror) + WORKER_HEALTH_PORT=9966 in remote .env (worker was defaulting to 9976, colliding with admin) -
d4ac2fbd2026-08-10 TK-10001: build M/I Homes + Smith Douglas adapters (national 30 fully accounted for); register mi-homes+smith-douglas, stanley-martin+clayton-properties documented-deferred; sanitize third-party public keys from mi-homes fixtures -
ef74e6c52026-08-10 stanley-martin: DEFERRED — Vite/React SPA, facts via runtime-resolved XHR only (RECON.md) -
8d0fbaf12026-08-10 clayton-properties: DEFER recon — scope mismatch (manufactured-only + federated site-built brands) -
ec4d72cf2026-08-10 collectors: add Smith Douglas Homes inventory adapter (facts-only) -
03e750602026-08-10 auto-data-snapshot: 2026-08-10T21:49:05 (6 data files) — collectors/mi-homes/fixtures/homes/_urls.tsv collectors/mi-homes/package.json collectors/mi-homes/tsconfig.json collectors/smith-douglas/package.json collectors/smith-douglas/tsconfig.json -
f1fb64b62026-08-10 HomesOnSpec: 6.7in + 13in-iPad screenshot sets; submitted v1.0 (build 2) to App Review (Waiting for Review 2026-08-10) -
ecb8061c2026-08-10 auto-data-snapshot: 2026-08-10T10:27:30 (6 data files) — apps/mobile/screenshots/ipad13/01-map.png apps/mobile/screenshots/ipad13/02-detail.png apps/mobile/screenshots/ipad13/03-browse.png apps/mobile/screenshots/ipad13/04-saved.png apps/mobile/screenshots/ipad13/05-alerts.png -
b4f48f592026-08-10 auto-data-snapshot: 2026-08-10T09:56:34 (6 data files) — apps/mobile/screenshots/final67/01-map.png apps/mobile/screenshots/final67/02-detail.png apps/mobile/screenshots/final67/03-browse.png apps/mobile/screenshots/final67/04-saved.png apps/mobile/screenshots/final67/05-alerts.png -
787e39c12026-08-10 HomesOnSpec: generate 6 faithful App Store screenshots (1320x2868) from native screen source + real listing data -
4d13307a2026-08-10 auto-data-snapshot: 2026-08-10T08:23:29 (1 data files) — apps/mobile/scripts/vshots/raw/01-map.png -
e8c1a10f2026-08-10 HomesOnSpec ASC docs: lock 17+ ship decision, © 2026 Steve Abrams, correct simulator→TestFlight screenshot note -
ac1caf5d2026-08-10 chore(workers): pin WORKER_HEALTH_PORT=9966 (9976 taken on Kamatera) -
7ff28c2d2026-08-09 fix(workers): health-probe bind failure must not crash the worker (TK-10240 prod incident) -
813a5a192026-08-09 fix: scope Ashton Woods Widen sweep to LD blocks only, fix stale test (TK-10382) -
2831eee72026-08-08 test(workers): real-Postgres integration test for TK-10240 pg-boss resilience -
44bdb1682026-08-08 TK-10240: homesonspec worker resilience — pg-boss error-ride-out + graceful SIGINT/SIGTERM + health canary -
ccf602c52026-08-08 Add 5 web-rendered 1320x2868 device-spec App Store screenshots (map/search/home/builders/saved) for iOS submit (TK-10363) -
e79924d82026-08-07 auto-data-snapshot: 2026-08-07T11:47:33 (1 data files) — apps/mobile/DEVICE-CAPTURE.md -
b09e3a6e2026-08-07 Homes on Spec: enlarge splash logo + wordmark (full-page prominence) -
3a8b1ce12026-08-07 auto-data-snapshot: 2026-08-07T10:41:58 (1 data files) — apps/mobile/ASC-PASTE-KIT.md -
9857d3db2026-08-07 mobile: paste-ready ASC metadata (categories/keywords/URLs/review-info/privacy) — resolved App Privacy=Data-Not-Collected + age-rating finding from code -
f9131bf92026-08-07 auto-data-snapshot: 2026-08-07T09:37:33 (3 data files) — apps/mobile/screenshots/00-current-state.png apps/mobile/screenshots/01-landing.png apps/mobile/tsconfig.json -
170271c82026-08-07 mobile: App Store screenshot shot-list (6 shots, map-led, captions mirror listing copy) -
c052b3e22026-08-07 auto-data-snapshot: 2026-08-07T09:05:06 (1 data files) — apps/mobile/scripts/build-ios-prod.exp -
cc61d3cf2026-08-07 mobile(eas): capture ASC App ID 6798873898 — future eas submit now fully non-interactive -
ae36501c2026-08-07 mobile(eas): link EAS project @agentabrams/homesonspec (projectId 9d110d60…) -
7b3801dd2026-08-07 mobile(eas): wire ios submit to reuse account-level ASC key 72Y2TZT54R (IDs only, .p8 referenced by path — matches nineoh-guide committed pattern) -
a1eab94c2026-08-07 chore(web): v0.1.0 → v0.2.0 (PWA install + conversion tracking, session close) -
ac2896892026-08-07 web(pwa): instrument install-conversion funnel — provider-agnostic track() (gtag+dataLayer+first-party /api/pwa-event sink) wired into InstallPrompt (shown/dismissed/result/installed) -
ae8f049d2026-08-06 web(pwa): add smart install prompt (iOS hint + Chromium button, engagement-gated); harden SW (gated skipWaiting, cache caps); honest offline copy — Cody-reviewed -
d4c4e1c22026-08-06 deploy-web: also ship apps/web/public (PWA icons/sw/offline) + verify PWA endpoints on live https -
85d968842026-08-06 web: make HomesOnSpec an installable PWA (manifest + service worker + icons + offline fallback) -
23315d372026-08-06 auto-data-snapshot: 2026-08-06T16:03:07 (1 data files) — apps/web/public/icon.svg -
57f4a18d2026-08-06 homesonspec/mobile: Cycle 3 Cody fixes — enrich gates on staleness alone + always-stamps attempt (fixes never-refresh + 8MB-per-open fetch-storm for homes not in /api/map); adaptive-icon transparent bg (Android mask-safe) -
24cb9a132026-08-06 homesonspec/mobile: Cycle 3 — enrich Saved by id from /api/map (shared cache + getHomeById, best-effort, lastEnrichedAt-guarded), status pill, close glyph X->✕, branded icon/splash (functional mark, replace with final art) -
6abe8f2e2026-08-06 homesonspec/mobile: Cycle 2 Cody fixes — homeDetailUrl /home->/homes (was 404), drop wrong-price DOM scrape (blank > confidently-wrong; Cycle 3 enriches from /api/map by id) -
f8ba090b2026-08-06 DEPLOY.md: document deploy-web.sh as the sanctioned safe web-deploy path (generic deploy.sh --delete would wipe the 85G crawl cache) -
572ac8f72026-08-06 homesonspec: Cycle 2 — map viewport-cull+grid-cluster (no 70k freeze), fix save-bridge /home->/homes URL + robust price/loc capture, add /privacy page (local; prod deploy gated) -
d67c56fa2026-08-06 homesonspec/mobile: make Alerts tab honest (no fake delivery claims) + fix 4.2 defense to not cite unbuilt push (Cycle 1 Cody gate) -
f6ad8bc62026-08-06 scaffold apps/mobile Expo SDK 57 iOS app for App Store onboarding (TK-10305) -
adcc23182026-08-06 homesonspec: home detail contact ties to builder-as-firm — 📞 phone (salesPhone→builder fallback) · 🏢 builder site · 🔗 listing; outside-agent layer drafted as gated migration -
af17a4152026-08-05 auto-save: 2026-08-05T15:43:31 (1 files) — ops/drain-dr-horton-night.sh -
b7da7ff92026-08-05 auto-save: 2026-08-05T14:42:56 (1 files) — ops/drain-dr-horton-night.sh -
033d4dbb2026-08-05 workers: exp_backoff_restart_delay to cap PG-outage restart storms (DTD verdict A + contrarian guardrails) — TK-10239 -
53ff55422026-08-05 prune: fail-open per-builder (|| true vs pipefail abort) + SNAP_DIR anchor guard + 30d manifest retention (verifier findings) — TK-10236 -
5c1b5c472026-08-05 ops: minute-precision retention (find -mtime +N truncates to >=N+1 days) — TK-10236 -
eb45f0f32026-08-05 ops: age-based retention prune for snapshot page-cache (7d, live-crawl guard, dry-run default) — TK-10236 -
059c26882026-08-03 fix(workers): health classifier — DEGRADED on error RATE (>25%), not any nonzero errorCount -
d858b3962026-08-03 feat(toll): raise recurring QMI crawl cap 400->2500 (Steve-approved) so nightly runs pull more of the ~11k inventory; contentHash dedup keeps re-runs cheap -
576365d92026-08-03 feat(web): HomesOnSpec attribution on builder contact — 'mention you saw it on HomesOnSpec.com' -
1f01a75d2026-08-03 feat(toll): wave-2 QMI home ingestion (adapter v2.0.0) — plain-fetch sitemap /Quick-Move-In pages -
acd6564e2026-08-03 docs(toll): wave-2 SOLVED — QMI homes are plain-fetch via sitemap /Quick-Move-In/<id> pages (JSON-LD + __NEXT_DATA__), no browser needed -
f98e35a72026-08-03 docs(toll): wave-2 recon — ~298 per-community fetches not 11k pages; homes load via amplify SPA XHR (browser-trace = fresh-session task) -
d67415292026-08-03 docs(specs): 6-builder batch outcome — 4 capture rich per-home specs, 3 deferred (verified thin/bot-walled) -
674ccf862026-08-03 feat(specs): perry specs capture — discounted price, promotion, description, elevation, market -
413357722026-08-03 feat(specs): meritage specs capture — monthly payment, was-price, move-in, floorplan, incentive, tour, MLS -
1fd7b60a2026-08-03 feat(specs): pulte specs capture — discount-off-list, monthly payment, basement, active-adult, tour -
7c3609cc2026-08-02 feat(specs): dr-horton capture proving slice — extract->validate->publish->render -
26f915602026-08-02 feat(specs): InventoryHome.specs Json foundation — schema + migration + publisher wiring -
dad730032026-08-02 docs(specs): audit pass-2 — 14 zeros are unparsed blob shapes, fold into per-builder fan-out; capture is prod-gated -
d46a0ce92026-08-02 feat(specs): offline field auditor + fleet pass-1 results (all 28 builders) -
3c8b733c2026-08-02 auto-save: 2026-08-02T17:46:59 (1 files) — scripts/audit-fields.mjs -
478e1c732026-08-02 docs(specs): all-specs capture audit — method + dr-horton reference (55 fields, ~10 captured) -
498007402026-08-02 feat(web): gated Google AdSense banner slots (top + footer) -
844071452026-08-02 fix: import-sweep PATH — add postgresql@14+homebrew bin so psql/npx resolve under launchd (silent no-op 7/31–8/2) -
79ed5aa42026-08-02 fix: lennar-mac-refresh PATH — add /opt/homebrew/bin so npx resolves under nohup/launchd (silent all-state no-op otherwise) -
4ad391252026-07-30 ops: nightly builder-import sweep (launchd com.steve.homesonspec-imports) -
891f79802026-07-30 auto-save: 2026-07-30T08:46:20 (1 files) — pnpm-lock.yaml -
fdacc4262026-07-30 feat(search): Amazon-style collapsed facet rail — 11 data points with live counts -
41e2509b2026-07-29 workers: register K. Hovnanian adapter (khovnanian-site) -
b61d70732026-07-29 auto-save: 2026-07-29T21:12:19 (1 files) — apps/workers/package.json -
04b557042026-07-29 collectors: add K. Hovnanian adapter (khov.com RSC, 30th builder) -
9c5e67192026-07-29 lennar refresh runner: source DB pw from gitignored .env (was hardcoded) + re-establish tunnel per-state -
63d56d742026-07-29 auto-save: 2026-07-29T09:37:47 (1 files) — collectors/richmond-american/ -
5c09c6902026-07-29 collectors: add Mattamy Homes — cracked the 'bucket-D' national via Sitecore JSS feed -
718fc16b2026-07-29 auto-save: 2026-07-29T09:07:36 (1 files) — collectors/mattamy/ -
e70a69b52026-07-29 lennar: durable Mac-side refresh runner (keepalive tunnel + state-by-state pipeline) -
0fbdefeb2026-07-29 build-loop: add Dream Finders to the throttled sweep rotation + reactivation roster (recovered adapter) -
6a68cd772026-07-29 lennar: Mac-side fetch->Kamatera image apply (routes around Lennar 403 IP-block) -
0b79470c2026-07-29 auto-save: 2026-07-29T07:06:42 (3 files) — collectors/dream-finders/src/index.ts apps/workers/apply-lennar-images.sh apps/workers/src/_lennar-mac-fetch.mts -
de09b3512026-07-29 david-weekley: capture city-gated community MapPoint coord (yolo iter-6) -
11a5e5fa2026-07-29 pipeline: make evidence delete+create atomic (contrarian fix) — kills concurrent-reextract race -
ee8b7a7c2026-07-29 geocode: shea per-home coord backfill from detail pages (yolo iter-5 prong 2) -
c806053d2026-07-29 auto-save: 2026-07-29T01:34:44 (1 files) — scripts/backfill-drh-geo-refetch.sh -
122205142026-07-29 publisher: promote lat/lon on the UPDATE branch too (contrarian critical fix) -
fa040b5f2026-07-29 geocode: one-time dr-horton coord backfill from CACHED snapshots (yolo iter-4) -
d99677fd2026-07-29 dr-horton: capture community coords from in-feed ld+json (yolo iter-4) — fixes 22.5k no-geo -
13b178872026-07-28 geocode: 2k-address chunks (was 10k) so bulk backfill fits inside the timeout -
0086b3462026-07-28 geocode: contrarian FIX-FIRST — city+state gate, full provenance, fail-fast timeout -
139ce3392026-07-28 geocode: Census-batch enrichment for no-geo homes (yolo iter-3, DTD verdict B) -
e3c33f7b2026-07-28 fulton: parse bed/bath RANGES correctly (contrarian fix) — recovers 36 dropped homes -
d9a0af8c2026-07-28 ashton-woods: tighten image blocklist + purge residual pollution -
840c359e2026-07-28 collectors: add Fischer, Fulton, GL Homes adapters (+3 builders, yolo iter-2) -
3cf382662026-07-28 cody-gate fixes: AW gallery pollution, DW community-photo hero, mediaRights split-brain -
955307e62026-07-28 brookfield: drop shouldcountasquickmovein filter (contrarian fix) — recovers +101 homes -
33db50312026-07-28 collectors: add Perry, Brookfield, Holt adapters (+3 builders, yolo iter-1) -
590c93932026-07-28 auto-save: 2026-07-28T20:33:03 (1 files) — collectors/ashton-woods/src/index.ts -
8e6635cb2026-07-28 tri-pointe: capture per-home Cloudinary photos (h.image.raw) -
7f27ee912026-07-28 david-weekley: capture per-home ElevationRendering photos from list cards -
cb83a5222026-07-28 kb-home: capture listing photos (ThumbnailImage/GalleryPhotos are objects, not strings) -
d92416822026-07-28 collectors: add LGI, Shea, Century, Beazer, Drees adapters (+5 builders) + loop wiring; gitignore var/snapshots -
a867626b2026-07-28 Add Century Communities scraper adapter (two-layer: findcommunities API + sitemap -> per-home QMI cards) -
9b6223942026-07-28 auto-save: 2026-07-28T17:01:56 (130 files) — apps/workers/var/snapshots/dr-horton-site/05beb3a14d3b6f3c4063e3ba5b1b171b55ebf2f4b2861da7c46315aa6137a2b4.html apps/workers/var/snapshots/dr-horton-site/1150ce3e873e463a3319027b8253b6f91ab854029e415293eda666ec46b110ea.html apps/workers/var/snapshots/dr-horton-site/18f9d8c17cb43d43975b3e1dc65aaddc4553724dfaaed459865532d8bcbe53fc.html apps/workers/var/snapshots/dr-horton-site/1b4991a8b58b4e688ab28e6035e0c4168cca4e22f37d9623c2cdcca526202a35.html apps/workers/var/snapshots/dr-horton-site/2428b450791da0b294f3a9485d8aed626e20f6c1b94afdc01bd0553d57352e60.html -
20b71fae2026-07-28 pulte: capture listing photos (feed stores image URL under 'path', not url/src) -
c28b10e82026-07-28 collectors: add Ryan Homes, Highland Homes, Landsea/Risewell adapters + wire into loop -
0c5a39682026-07-28 Add Ryan Homes (NVR) collector adapter -
c3bf5d1d2026-07-28 storefront: render home photos on the search grid (+ absolutize Taylor Morrison image URLs) -
6515c4d42026-07-28 build-loop: add Meritage (national Sitecore-Discover feed) to the sweep rotation + reactivation roster -
aa57e14f2026-07-28 collectors: add Meritage Homes adapter (Sitecore Discover national JSON feed) -
c4b894e72026-07-28 storefront: enable home images (BUILDER_IMAGES_ENABLED=1) — display the 33k builder photos (DRH/Lennar/TM); hotlink verified 200, Steve-approved -
9d820bfe2026-07-28 build-loop: add Discovery (Seeno-family single feed, run once/sweep) — 127 homes, 100% priced; last unfed adapter -
74b6e7552026-07-28 build-loop: fully uncapped (DRH/Lennar -> $CAP=100000) + 1h sweeps / 40 max (Steve: download ALL homes) -
15ce87172026-07-28 admin/business: link data points to REAL homes — Real-home-listings table (rows → /homes/[id]), KPIs → /search + /builders -
775ea10a2026-07-28 build-loop: uncap CAP (download ALL homes per state) + 40 sweeps, 1h cadence — max-it -
6d7e38022026-07-28 admin: Live site toggle (/live) — embeds the customer storefront with desktop/mobile preview + open-full -
f90ea4b62026-07-28 build-loop: Lennar + DR Horton page limit 120->300 (Cody: CAP=120 truncated big states alphabetically; adapters default to 300 for exactly this — DRH CA has ~226 communities, Lennar CA ~126) -
f00da2b42026-07-28 web/search: national-site card upgrades — urgency status badges, est. monthly payment, favorite/save heart (localStorage) -
ab43eec22026-07-28 build-loop: Lennar uses LENNAR_STATE_FILTER=slug(state) not LENNAR_STATE (adapter reads _FILTER) — was capped to ~7 alphabetical states, now all 42. DTD 5/5, verified -
1f76088e2026-07-28 KB Home: key community seen-set on name+state (Cody: cross-state name collision) + docstring -
c7715e272026-07-28 KB Home: national single-run adapter (all-states extract, per-record state) — fixes page-dedup coverage gap + kills 42x redundant 5.8MB fetch. DTD 5/5, root-cause verified -
53fe5d852026-07-28 build-loop: add 3 missing AW metros (charleston/jacksonville/myrtle-beach, Cody-gated) + document the intentional roster re-enable -
c9a622d62026-07-28 build-loop: add Taylor Morrison (state-scoped) + Ashton Woods (metro primitive) — DTD 3/2; both were inactive-not-broken, verified 100% priced/addressed -
de14cc6d2026-07-28 engine viewer: empty 'errors: []' no longer flagged red (honest signal) -
c3c35afe2026-07-28 admin: live Engine viewer (/engine) — terminal-style tail of the pm2 ingest build-loop -
a5e1e41e2026-07-28 admin/business: fully interactive — every data point hrefs to live feed data, real charts, sortable field tables -
72e788892026-07-28 admin: Business Analysis page — full analysis + live metrics, accessible in admin -
1a7632dd2026-07-28 build-loop: correct the misleading 'cheap no-op' comment (unserved state = a real sitemap GET) -
7c8f49be2026-07-28 build-loop: scope David Weekley sweep to its 7 served states (Cody-gated: avoid wasted sitemap GETs / WAF-bait) -
d4ba9f8e2026-07-28 build-loop: add David Weekley (100% priced, 7 states) to rotation — DTD 5/5 add -
de3e088d2026-07-28 build-loop: throttle Toll (communities-only) to every 8th sweep — DTD 4/5 (Lennar stays full-rate) -
b9c9bbc32026-07-28 build-loop: add Lennar (state-iterating) + Toll Brothers (national) to ingestion rotation — keep ingesting -
8873056b2026-07-28 auto-save: 2026-07-28T09:29:05 (1 files) — apps/workers/var/ -
04910e042026-07-28 admin/ingestion: LEFT JOIN active sources — surface stale/absent sources (Cody-gated: silent-source blind spot) -
80fb67762026-07-28 feat: HomesOnSpec data-feed API (:9799) — share the development pipeline with RENTV/partners -
847b94d62026-07-28 admin/ingestion: honest error signal — surface per-record homes dropped (per-source), not just failed-run % -
5aea78882026-07-28 engine: per-stream liveness — each cylinder fires only when its data stream is moving live (idle streams go dark; RPM=0 when nothing flows) -
708074422026-07-28 feat: live V8 'engine room' dashboard (:9798) — pistons/crank/belt driven by real DB throughput -
c9a3fdf32026-07-28 admin/ingestion: guard sparkline last-value (TS strict index) -
557ae6582026-07-28 admin/ingestion: live sparkline + new-vs-refreshed + error rate + per-source health table -
d44d52702026-07-28 auto-save: 2026-07-28T08:58:52 (1 files) — apps/admin/src/app/api/ingestion-stats/route.ts -
3cac9a332026-07-28 deploy-kamatera: :80 acme block covers admin.homesonspec.com for renewals -
5064112b2026-07-28 deploy-kamatera: admin block uses LE cert (admin now in cert SANs) -
de505ba82026-07-28 feat: LA all-permit ingest + Census permit geocoder + searchable permit viewer -
b0103f282026-07-28 admin: live ingestion dashboard (/ingestion) — auto-refreshing throughput from Kamatera DB -
db9700f22026-07-28 build-loop: source repo .env for DATABASE_URL (fixes PrismaClientInitializationError on Kamatera) -
9075f7b02026-07-28 feat: construction-pipeline layer — building-permit ingestion + Census geocoder -
89a47a022026-07-28 build-loop: honor injected DATABASE_URL (portable to Kamatera cron) -
be3712822026-07-28 deploy-kamatera: rewrite for homesonspec self-host (correct naming, explicit PORT, pgboss grants, LE-cert vhost) -
e118a5bd2026-07-28 build-loop: max-it — fan out 4 adapters in parallel (per-domain), 30rpm, bigger enrich batches -
168b21d82026-07-28 build-loop: West Coast first + deeper per-state cap (CAP=120) -
53b1804f2026-07-28 collectors: add Ashton Woods adapter (national; JSON-LD QMI, per-home geo) -
da8824a32026-07-28 build-loop: go nationwide — sweep 42 top homebuilding states (all-50 name map) -
40750c022026-07-28 fix: david-weekley stories/garages must be integer (1.5-story home 400'd the Houston page) -
b319e2f02026-07-28 TK-10: add finish-tk10.sh turnkey go-live driver -
887b38f52026-07-28 auto-save: 2026-07-28T06:58:06 (2 files) — collectors/discovery/src/index.ts scripts/build-loop.sh -
eacead2b2026-07-27 collectors: add David Weekley adapter (national; server-rendered homes-ready-soon) -
8550e53d2026-07-27 recon: classify 8 regional builders' plain-fetch inventory feasibility -
444eee612026-07-27 collectors: add Discovery Homes adapter (first regional; Seeno-family feed) -
c61273582026-07-27 auto-save: 2026-07-27T20:54:34 (4 files) — apps/workers/package.json apps/workers/src/cli.ts pnpm-lock.yaml collectors/discovery/ -
fbd5fc6c2026-07-27 workers: register 29 Pacific-region regional builders as onboarding targets -
76c1d2752026-07-27 auto-save: 2026-07-27T20:24:23 (1 files) — scripts/build-loop.sh -
48110bc72026-07-27 scripts: all-night autonomous build-loop (ingest x states + enrichment sweeps) -
8dda33282026-07-27 workers: public-records nearby-enrichment stage (NCES schools + OSM places) -
7677fe3a2026-07-27 collectors: enforce robots.txt in LiveFetcher (POLICY compliance) -
7782f9c42026-07-27 auto-save: 2026-07-27T19:54:12 (1 files) — collectors/common/src/live-fetch.ts -
ce2edb5a2026-07-27 chore: v0.3.1 (session close — spechomes→homesonspec rename) -
63efe7892026-07-27 auto-save: 2026-07-27T18:53:10 (95 files) — .env.example README.md apps/admin/next.config.ts apps/admin/package.json apps/admin/src/app/api/review/route.ts -
ff7f59372026-07-27 Scrub non-owned domain spechomes.com -> homesonspec.com (Layer 1) -
762fa0e52026-07-27 chore: v0.3.0 (session close) — honest positioning, admin fail-closed auth, secret history scrub, typecheck gate green -
1c821fb02026-07-27 chore(TK-10): finalize secret scrub — gitignore ROLLBACK-DNS.txt, env-based admin test cred -
77fbb6322026-07-27 auto-save: 2026-07-27T17:22:24 (1 files) — deploy-kamatera.sh -
89f29a3a2026-07-27 admin: fail-closed auth + generated prod password (TK-10 security #2, partial) -
2fa9a7f92026-07-27 auto-save: 2026-07-27T16:52:13 (3 files) — apps/workers/src/pipeline.itest.ts collectors/taylor-morrison/tsconfig.json packages/source-registry/src/ -
ef45303a2026-07-27 web: honest Lennar-anchored positioning (TK-10 blocker C) -
0d87dcdf2026-07-23 chore: v0.2.1 (session close) — spechomes pm2 prod + redeploy scripts -
8f6d3bf82026-07-23 auto-save: 2026-07-23T13:51:43 (1 files) — pnpm-lock.yaml -
b04f2be02026-07-23 add pnpm redeploy scripts (build + pm2 restart) for prod web/admin -
844edb3a2026-07-23 pm2: boot spechomes-workers via node --env-file so DATABASE_URL loads -
ff4a50f72026-07-23 chore: gitignore screenrecord/ test artifacts -
4acc9f102026-07-23 chore: v0.2.0 (session close) — Taylor Morrison adapter + national multi-state state-fixes -
6612fe5a2026-07-23 fix(dr-horton,tri-pointe): use real parsed state instead of hardcoded CA -
55372bc12026-07-23 fix(pulte): use real state code instead of hardcoded CA (enables multi-state) -
ac8dff842026-07-23 docs(collectors): update builder status — 5 live, TM egress-blocked, Meritage needs XHR trace -
2570ea052026-07-23 fix(workers): declare taylor-morrison collector dep so pnpm links it -
86433ff42026-07-23 feat(collectors): add Taylor Morrison adapter (Sitecore fedmodel, CA) -
08c6d1762026-07-23 fix(collectors): raise DRH+Lennar default PAGE_LIMIT 8→300 for statewide coverage -
aa61dfd42026-07-23 fix(live-fetch): broaden Accept header so D.R. Horton WAF stops 406ing -
f66f9ae42026-07-23 Add Tri Pointe adapter (5th builder) — Next.js RSC (unescape + brace-match display_price objects), CA-scoped, WITH lat/lon; verified 3 live Corona homes + community geo/phone; registered -
8456a67d2026-07-23 Fix new-builder ingest bugs caught on real data: lat/lon optional in home schema (KB/DRH feeds lack per-home geo), TOWNHOUSE→TOWNHOME enum (KB/Pulte), Pulte builder slug pulte→pultegroup + deploy-full pnpm install step -
747869602026-07-23 Add Pulte adapter (4th builder) — JSON API (getcommunities + qmiplans), CA-scoped, WITH lat/lon so homes map; verified 8 live Ontario homes + community geo/phone; registered -
ca4ba1d72026-07-22 CA builders: recon spec doc (collectors/BUILDERS.md) — turnkey extraction specs for Pulte/TriPointe/TaylorMorrison/Meritage; all 6 builders plain-curl/no-anti-bot/per-community-phone -
65775ba22026-07-22 Add KB Home adapter (3rd builder) — single-feed (var allMIRs double-decode), CA-scoped, verified 58 communities + 143 live CA homes from one fetch; registered in pipeline -
d27cab5c2026-07-22 Add D.R. Horton adapter (2nd builder) — Sitecore var-model blob, CA-scoped via DRHORTON_STATE, captures homes+community+salesPhone+images; verified 3 live Manteca homes; registered in pipeline -
0d7bc7782026-07-22 Listings contact: capture per-community sales-office phone from Lennar feed (verified) + Community.salesPhone column + prominent Call button on home detail; Lennar exposes no public email so listings show phone + lead form -
c64214082026-07-22 Lennar adapter: LENNAR_STATE_FILTER for targeted per-state crawls + drop promo/event non-community URLs (alphabetical full-sweep is too slow to reach late-alphabet states like TX) -
ef19ec032026-07-22 Fix broken search: when a query doesn't resolve to a location (city/state/builder name), fall back to a free-text filter (city/community/builder/state) instead of silently returning the entire national catalog -
823198162026-07-22 Design review fix: dedupe home detail Data-provenance table to one row per field (newest) — kills the ~8x per-snapshot row bloat the visual review caught -
2968a9232026-07-22 Builder-image kill-switch: BUILDER_IMAGES_ENABLED env gates all photo render sites (default ON) — one flip to compliance pending media-rights decision (DTD panel FIX-THEN-SHIP) -
f5b911162026-07-22 Contrarian fixes: StagedRecord unique (source,snapshot,home) + upsert/delete-recreate → FORCE_REEXTRACT idempotent (no raw-row bloat); img loading=lazy + hero fetchPriority -
bda9b2932026-07-22 auto-save: 2026-07-22T20:46:37 (1 files) — packages/database/prisma/schema.prisma -
f4b686d42026-07-22 Featured homes: spread price bands (value ~250-380k / mid ~480-650k / luxury 750k+) so tiers read distinctly -
ba86ab2a2026-07-22 Homepage: 3 featured homes on load — Value / Mid-range / Luxury price tiers, real listings with builder photos -
4be9de782026-07-22 deploy-full.sh: also ship collectors + publisher + schemas src (image extractor was silently missing from prod deploys) -
ba895b722026-07-22 Pipeline: FORCE_REEXTRACT env to re-extract already-snapshotted pages (backfills new fields like images onto unchanged-source homes) + durable grant note -
13997e362026-07-22 Builder images: capture per-home photos from Lennar feed (elevationImage/plan/community, verified 58/58 homes), images[] schema+migration, thread through publisher, render in detail hero+gallery+carousel with gradient fallback -
77b81ebe2026-07-22 Home detail: branded hero header + status badge, 'more homes in this community' carousel, prominent builder-contact CTA (builders-want-to-sell), full brand reskin -
da530f2a2026-07-22 Amazon-style faceted search rail: State (multi-select, 50-state overflow) + Builder/firm + Min Sq Ft facets, live counts, clear-all, sticky scroll; add state facet to API + multi-state param -
008a9dea2026-07-22 auto-save: 2026-07-22T18:15:55 (4 files) — apps/web/src/app/search/SearchClient.tsx apps/web/src/lib/parse-search.ts packages/search/src/index.ts deploy-full.sh -
ec6046b82026-07-22 Contrarian gate fixes: guard auto-pause recovery (manual disable stays down), defense-in-depth freshness!=INACTIVE on search+map, honest design-bundle README -
3cb663542026-07-22 Stage-3 verification engine: freshness decay + relabel, source-health auto-pause (SourceRun log + counters), cross-source dedup, verify CLI + 9 unit tests, wired into pipeline runs -
832a5c0b2026-07-22 Design system iter-2: reskin /map explorer panel + /search cards & controls from tokens (brand/accent, Fraunces prices, card-interactive) -
8b8126df2026-07-22 Design system iter-1: Claude Design bundle (tokens + buttons/badges/home-card/map-legend cards w/ @dsCard markers) staged for DesignSync push -
678cf48b2026-07-22 Design system iter-1: @theme token layer (brand/accent/status ramps, Fraunces+Inter, radii/shadows), reskin app shell + hero from tokens -
be4576432026-07-22 auto-save: 2026-07-22T17:15:39 (2 files) — deploy-heromap.sh deploy-web.sh -
bbbcbc6e2026-07-22 Add robust map explorer (/map): 12k canvas markers, per-field on/off toggles (status/price/beds/builder), color-by + legend, localStorage-persisted -
13c6b8372026-07-22 Add live national map to homepage hero (loads on page load) + fix stale demo copy -
ab1a33052026-07-22 auto-save: 2026-07-22T14:44:58 (1 files) — cert-homesonspec.sh -
1a4259352026-07-22 rebrand SpecHomes → HomesOnSpec; add /builders directory (all 30 builders w/ coverage, website, live home counts + links) -
af67cea52026-07-22 clean-relaunch script for homesonspec.com (ship demo-filtered code + purge synthetic DB rows + rebuild + retarget nginx) -
f895480f2026-07-22 HARD RULE: demo/synthetic inventory NEVER surfaces live — isDemo:false filter on search + all consumer queries, isDemo 404-guards on detail pages, banner drops demo language (real builder data only) -
5c8576902026-07-22 resilience: live adapters skip per-URL fetch failures (404/blip) instead of aborting the whole sweep — a single stale Lennar /promo/ URL killed a 4.4k-page run after 15,974 homes -
e8366c4a2026-07-22 auto-save: 2026-07-22T13:14:23 (1 files) — ROLLBACK-DNS.txt -
6e35e39f2026-07-22 fix: relative import for parse-search (the @/ alias mis-resolved against inherited baseUrl under next build — never caught because prod build was never run locally) -
013b82842026-07-22 yolo: harden go-live scripts per contrarian (self-signed origin TLS + CF Full, admin origin-only, default_server preflight, rollback capture) -
030753f02026-07-22 go-live scripts (Kamatera deploy + CF/GoDaddy cutover), gitignored (contain infra topology); pm2 env hardening -
30af08432026-07-22 go-live: Kamatera deploy script; start scripts respect PORT env; national-builder recon recorded (batches 3-4); dream-finders adapter -
0e090e442026-07-22 auto-save: 2026-07-22T12:13:58 (1 files) — collectors/dream-finders/ -
4ba331cd2026-07-22 source runbooks for toll-brothers + lennar live adapters -
45f9ee292026-07-22 lennar live adapter (172 real homes from 8 pages, Apollo state extraction), streaming runPipeline for large sweeps, honest early-preview banner -
f0e81ad02026-07-22 top-30 builder registry + recon findings recorded; toll-brothers live adapter: 337 real communities ingested via sitemap-sanctioned feed, full evidence trail; positioning update (no one-stop place) -
141316172026-07-22 polite LiveFetcher (rate-limited, never circumvents blocks) + top-10 national builder registry seed (sources PAUSED until recon + activation) -
4dce3d292026-07-22 pm2 ecosystem config, 9 ADRs, data-rights policy, source runbook template, README -
0ba882212026-07-22 integration tests (pipeline e2e, only-writer invariant, review-approve flow) + 7 Playwright e2e specs, all green -
73a5db3e2026-07-22 generalize pipeline: hints column on StagedRecord, publisher resolves builder/community from hints, label derives from collection method, live/fixture mode from registry -
7c746ccb2026-07-22 fix Leaflet SSR: keep MapView out of the shared-ui barrel, subpath dynamic import -
6b477e662026-07-22 consumer web app (search/detail/community/builder/contact) + admin app (review/sources/validation/snapshots) + publisher package extraction; both apps serving -
75e00bb82026-07-22 worker pipeline (fetch/extract/validate/publish) + CLI + synthetic seed; fixture pipeline e2e green, idempotent re-run, dup rule scoped to zip -
1e9a023a2026-07-22 collector adapter contract + meridian-homes fixture adapter with hand-authored extraction contracts (7 tests green, null-never-guessed proven) -
d63580332026-07-22 shared utilities (canonicalKey/geo/queue) + zod schemas + validation engine with 10 rules, 31 unit tests green -
1aad19ce2026-07-22 initial scaffold: pnpm monorepo, Prisma schema (published + raw pipeline sides), migrations applied
Authors
- Steve330
- auto-commit-fleet24
- steve5
- Claude1
Agents used
- secrets-manager1
Skills used
- /mobile35
- /claude25
- /code25
- /baths20
- /sqft19
- /homes16
- /beds16
- /workers15
- /lon13
- /package12
- /screenshots12
- /snapshots11
- /tsconfig10
- /deploy9
- /geo8
- /community8
- /search8
- /state7
- /stories7
- /index6
- /legal6
- /fixtures6
- /garage6
- /map6
- /web5
- /seed5
- /price5
- /plan5
- /status5
- /builder5
Creative ideas + design notes
ed938c0f · 2026-09-13 · Publish a fleet-health heartbeat: this poller was invisible to the rollup
Found by a red-team pass on my own changes. fleet-health-rollup globs ~/.claude/skills/*/data/latest.json and SILENTLY SKIPS a skill with no such file (`if (!existsSync(file)) continue`). This poller wrote state only to ops/runtime/, so it contributed ZERO signal and was unknown to dw-canary-meta-watchdog too: if it died, the 7am panel would say nothing was wrong — about the one app under a live Guideline 5.6 conduct citation. Worse, my previous commit's own comment claimed "alert_delivered lands in latest.json for fleet-health-rollup". There was no latest.json for this skill. I asserted an integration I never tested, in the same session spent hunting exactly that failure. Comment corrected; the integration now actually exists and is actually tested — the rollup picks the row up (verdict=ATTENTION, status=WARN). - heartbeatStatus(): approved/pending -> PASS, rejected -> WARN (matching ios-release-train's ATTENTION), and an outcome we could NOT measure -> NOT_MEASURED/WARN, never PASS (TK-11431 #1). A null state means ASC was unreachable or the row did not parse; that is not evidence all is well. - Published AFTER the durable state write and wrapped so a heartbeat failure can never cost the observation. - Never published from a --fixture run (the seam guard learned earlier today). - Two tests lock the mapping, incl. the negative case. TK-11155 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPS3gnB4H5MQKmWcHKvuf6
471d1568 · 2026-09-13 · Poller: notify() must never be able to fail its caller
My previous commit moved notify() BEFORE the log/state write so alert_delivered lands in latest.json for fleet-health-rollup. That made bookkeeping able to break the measurement: a throw in the new cncp_post shell-out would cost the observation AND leave a stale state file, which then re-fires the same "change" next run. _shared/alert_receipt.sh states this rule in its own header; I violated it. Wrapped in try/catch returning false. Proven on the LIVE path with a clean runtime dir (previousState=null forces stateChanged=true so notify actually runs): state persisted, alert_delivered=true, real runtime dir untouched. Noted honestly: the success path is proven; the catch is belt-and-braces, since a missing helper makes `bash -c '. helper && …'` exit nonzero rather than throw. Two earlier attempts at this test were vacuous and are recorded so they are not repeated: --fixture skips notify entirely (`&& !fixturePath`), and repointing HOME breaks ipa-status's key lookup before notify is ever reached. TK-11155 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPS3gnB4H5MQKmWcHKvuf6
043c09b7 · 2026-09-13 · Apple review poller: stop disarming itself while awaiting Apple
The poller treated REJECTED as terminal and called launchctl remove on every run, i.e. it tried to unschedule itself 303 times since 09-08. It survived only because JOB_LABEL said 'com.steve.homesonspec-apple-review' while the label actually loaded is '...-apple-review-v2', so every removal returned status 3 (no such label). Correcting that constant alone would have armed the self-destruct. - shouldDisarm(): only an 'approved' outcome may stop the monitor. REJECTED is the state we are waiting to LEAVE while a Resolution Center reply is outstanding; stopping there blinds us at the moment it matters. - JOB_LABEL corrected to the label that is actually loaded, with a comment that it is only safe alongside the guard above. - Alert on state CHANGE only (was: a desktop banner every 15 minutes) and record alert_delivered via the shared cncp_post helper, which asserts the HTTP status instead of swallowing it. - Negative tests: an attention outcome must NOT disarm, with a positive control so the guard cannot pass as dead code, plus a JOB_LABEL/plist assertion. Verified red-then-green by re-injecting the original logic; all 5 pre-existing tests stayed green through the injected fault, which is why this shipped untested. TK-11155 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPS3gnB4H5MQKmWcHKvuf6
fb984ed6 · 2026-09-11 · eas: pin production ios.image=latest (ITMS-90725 guard)
Fleet sweep under TK-11155 found this app missing the guard that Charge & Explore needed after sitting at 0 builds in ASC on an ITMS-90725 upload bounce. The documented fix is exactly this line (Xcode 26 / iOS 26 SDK image), and the chargeandexplore-release canary treats it as a HARD gate. Cheap insurance: without it a production build can bounce on upload after the EAS build has already been paid for. Semantic diff confirms this adds build.production.ios.image only; nothing else removed or changed. JSON re-validated. Refs TK-11155. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0200179c · 2026-09-10 · TK-11303: retire stale v1 apple-review launchd plist (superseded by v2 wrapper)
The direct-node plist (ops/com.steve.homesonspec-apple-review.plist) is the job launchd bootstrapped once via RunAtLoad then DROPPED (no persistence), and it ran apple-review-poller.mjs from the wrong cwd -> ENOENT mkdir /ops/runtime. It is superseded by com.steve.homesonspec-apple-review-v2 (~/Library/LaunchAgents, runs ~/.claude/skills/homesonspec-apple-review/run.sh, which cd's to the project root and exec's the SAME ops/apple-review-poller.mjs). Nothing auto-bootstraps ops/*.plist, so the file was an inert footgun. The poller .mjs + its test stay (v2 depends on them; 5/5 tests pass). Reversible: git revert restores the file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NdRDCrJcC2BcsYP7k3CxyA
31581ff8 · 2026-09-10 · TK-11364: version + golden-lock the TK-11125 guard's canonicalization contract
Document and version the spurious-generation guard's two canonicalization primitives (codex follow-up). canonicalKey is stored + used as the guard's lookup key, so a rule change re-mints one generation per home (drift-SENSITIVE); payloadHash is recomputed on both sides at compare time, so a rule change is self-consistent and mints nothing (drift-IMMUNE). Adds CANONICAL_KEY_VERSION / PAYLOAD_HASH_VERSION, a golden-vector contract test that breaks the build on any silent rule change (forcing a conscious version bump), CANONICALIZATION-CONTRACT.md, and a guard-comment cross-reference. Code/docs only — no schema, no data write. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NdRDCrJcC2BcsYP7k3CxyA
3e4d499f · 2026-09-10 · O3b: ValidationEvent partition conversion script (corrected pattern)
Second half of O3. Same ATTACH path as SourceEvidence but built on the corrected pattern from today's run rather than repeating its mistakes: - per-partition FKs, never a parent FK before ATTACH (that forced a 170M-row revalidation under ACCESS EXCLUSIVE and stalled the site for ~7 minutes) - GRANTs on the parent and every partition, and the run aborts if any partition is left ungranted (a postgres-created table has no app-role ACL, which 500'd the public page with 42501) - verification includes an app-role query in the exact shape the admin pages use (SET ROLE homesonspec; WHERE passed=false ORDER BY runAt DESC LIMIT 100) runAt is timestamp(3) without time zone, so bounds use TIMESTAMP literals rather than the ::timestamptz casts used for SourceEvidence. Scratch-tested: rows preserved, new rows route to the correct monthly partition, default partition stays empty, admin query shape returns rows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HpKbjp2febJ1r8BNTyZwvP
0f94115d · 2026-09-10 · O3: add grant script so future partitions inherit the app-role ACL
The inline paste kept line-wrapping in the terminal, which split 'sudo -u' from its argument. Same file-pipe pattern as o3-apply.sh: short command, no wrapping. Sets ALTER DEFAULT PRIVILEGES so a partition created later by postgres is automatically granted to the app role instead of silently 42501-ing writes to that range, backfills any partition currently missing the grant, and verifies both the ACL and that a real home detail page still returns 200. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HpKbjp2febJ1r8BNTyZwvP
cc0a0516 · 2026-09-10 · O3: fix the two bugs the live run exposed (FK-before-attach stall, missing GRANTs)
The conversion succeeded on prod but caused two problems the 20k-row scratch test was too small to expose. Both are now fixed in the script. 1. FK-before-ATTACH stalled the live site ~7 minutes. Adding the foreign key to the partitioned parent BEFORE attaching makes Postgres re-validate that FK against every row of the incoming partition -- 170M rows joined against StagedRecord -- while holding ACCESS EXCLUSIVE. Peak 33 app queries blocked, oldest waiting 396s. lock_timeout did not help because the lock was already acquired; the cost was in the work, not the wait. The legacy partition already carries its own valid FK and forward partitions are empty, so per-partition FKs are correct and instant. 2. Missing GRANTs 500'd the public home detail page. A table created by postgres has no ACL for the app role, so prisma.sourceEvidence.findMany() failed with 42501 'permission denied for table SourceEvidence' on /homes/[id]. The script now grants on the parent, the default partition and every forward partition, and sets ALTER DEFAULT PRIVILEGES so future partitions inherit the grant instead of silently breaking writes to a new range. Also adds an app-health assertion to VERIFY: it fetches a real published home detail page and aborts unless it returns 200. The original script verified the database thoroughly and never once checked that the application still worked, which is why a 500 reached users. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HpKbjp2febJ1r8BNTyZwvP
a15775f6 · 2026-09-10 · O3: add prod apply script for the partition conversion
One self-aborting script implementing ops/o3-partition-PROVEN-runbook.md. Preflight hard-aborts on a stale/missing backup, <15G free disk, or row loss. STEP 1 (VALIDATE CONSTRAINT) is online under SHARE UPDATE EXCLUSIVE; STEP 2 is a single catalog-only transaction with lock_timeout so it aborts cleanly rather than queueing behind a long transaction. Adds two things the runbook did not have, both surfaced while preparing the real run: - a DEFAULT partition. Without it, a row whose createdAt falls outside every defined range raises 'no partition of relation found' and ALL ingestion stops. The verify step asserts it stays empty, which is also the alarm for a missing forward range. - forward monthly partitions through 2027-12, so partition exhaustion cannot break ingestion unattended. Mac2 is classifier-blocked from prod SSH, so this runs from Steve's shell. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HpKbjp2febJ1r8BNTyZwvP
d6400d4d · 2026-09-10 · O3: prove SourceEvidence partitioning is feasible with no rewrite and no data-model change
Tested the ATTACH-based conversion end-to-end on a scratch PG 14.23 DB and disproved the three blockers this work has assumed since 2026-08-26: - pg_partman is NOT required (native PG14 declarative partitioning suffices) - the conversion needs ~0 extra disk, NOT ~82GB of scratch for a rewrite - no composite-PK / Prisma data-model change is needed, because a PK-less partitioned parent lets the legacy partition keep its own local PK Verified on prod (read-only) that nothing has an incoming FK to SourceEvidence.id, createdAt is NOT NULL, and the only constraints are the PK and the StagedRecord FK. Verified in code that all four app call sites key on stagedRecordId or entityType/entityId -- there is no findUnique by id anywhere, which is also why SourceEvidence_pkey (11GB) shows 0 scans. Scratch proof: 20k/20k rows preserved with the legacy heap unchanged (no rewrite), insert routing correct, FK still enforcing, pruning working, both hot indexes still used per partition, DETACH/re-ATTACH round-trips cleanly (the payoff: cold archive without deleting history), and all four real app operations plus cross-partition row movement pass. Measured partition fan-out on the public-page query across 36 monthly partitions: execution 0.4-0.6ms and planning within noise of the unpartitioned baseline, so fan-out is not a concern at realistic partition counts. Only real prod cost is one ~82GB sequential scan during VALIDATE CONSTRAINT, held under SHARE UPDATE EXCLUSIVE, which does not block reads or writes. Still deferred: feasibility is no longer the blocker, necessity is. Execute on a TK-11363 trigger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HpKbjp2febJ1r8BNTyZwvP
82fadf19 · 2026-09-10 · ops: preflight now VALIDATES the rollback dump instead of suggesting it (TK-11364)
Checklist item 2 has always said the dump must be validated with pg_restore
--list, but that was a note a human had to remember at 3am. Nobody ever ran
it, so O3's entire rollback rested on an unverified 12.8GB file.
Preflight now does it automatically, cheaply:
- pg_restore --list, and assert SourceEvidence/StagedRecord/ValidationEvent/
InventoryHome are actually present in the TOC
- read the LAST data block in the archive
The tail read is the one that matters here. A pg_dump killed by a full disk
produces a VALID TOC with a truncated tail, and the TOC sits at the FRONT of a
custom-format archive — so reading it proves nothing about the tail. That is a
live risk on this box, which is at 94% and already skipping other backups (the
BACKUP-SKIPPED flag printed right below). Reading the last block forces a seek
to near EOF and does catch it. Both checks measured ~0.04s on the real dump.
Also prints the full-archive proof command for pre-window use rather than
running ~6 min of CPU on every preflight.
Verified live against today's dump: TOC OK (30 tables), all four critical
tables present, tail read OK. Separately ran the full proof out-of-band —
pg_restore of the entire SourceEvidence data block exited 0 after 2m11s
(13GB read), so today's dump is a genuinely valid rollback.
Read-only against prod; no mutations.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
616032a6 · 2026-09-10 · ops: fix preflight rollback check reporting a false "no backup" (TK-11364)
Section 7 globbed /root/backups/* which only matches the top level, so it missed the real dumps in /root/backups/db/ and printed "no obvious dump found" while a fresh 12.8GB homesonspec dump sat one directory down. On the rollback check a false "none" is the worst possible answer — it either aborts a window unnecessarily or, worse, normalizes proceeding without a verified rollback. Now finds the actual dump, prints size + age, warns past a nightly cycle, restates the pg_restore --list validation the checklist requires, and fails loud with an explicit "there is no rollback" if none exists. Also surfaces BACKUP-SKIPPED flags, which are themselves a rollback risk. Verified live: one is present today — DW-Agents nightly skipped at 03:30 with only 34G free, refusing to run to protect Postgres. That flag would otherwise have sat silent while someone planned a conversion. Verified read-only against prod; no mutations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JhnABoxWtpF7mbBowoBWhb
14ed1904 · 2026-09-10 · ops: make Phase-2 preflight actually enforce the disk gate (TK-11364)
Three defects found while validating the O3 runbook against live prod.
1. The disk gate only PRINTED df and relied on a human doing the math — at
exactly the spot where Cody's hard "abort if <75GB free" lives. Combined
with the plan doc's (false) claim that the volume grow had happened, a
session could read past it and start a rewrite that fills the volume and
takes prod Postgres down. Now machine-checked, loudly reported, and the
script exits non-zero with an ABORT banner so no wrapper can proceed on a
skimmed report. Verified against prod: FAIL at 44GB free, exit 1.
2. Section 6 ("is import traffic quiet?") ran count(*) WHERE createdAt >
now()-'2 min'. There is no index on createdAt, so that was a full seq scan
of the 82GB heap on the check you re-run most often while waiting for a
window to go quiet. Replaced with a pg_stat_user_tables n_tup_ins delta:
instant, no heap read, and measures live insert RATE. Whole preflight now
completes in ~80s instead of blowing a 90s budget unfinished.
3. New section 8 surfaces the index inventory and flags the material fact that
SourceEvidence has NO index on createdAt — the column Phase 2 partitions on.
partition_data_proc drains by createdAt range, so every batch is a seq scan
unless an index is built first. That is a build-it-up-front-vs-accept-it
decision, not something to discover mid-window.
Section 5 also now prints an instant reltuples estimate before the slow exact
count, with the seq-scan cost called out.
Verified read-only against prod; no mutations.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JhnABoxWtpF7mbBowoBWhb
88e393b7 · 2026-09-10 · docs: correct stale/false facts in O3 partition plan (TK-11364)
The plan claimed the Kamatera volume grow had happened and that it solved the disk refill. It did not — sda is still 700G with 112d uptime; Steve deferred Phase 1 on 2026-09-03. A future session reading this would assume Phase-2 headroom that does not exist. Adds a status-correction banner reconciling the doc against read-only prod measurement plus the independent homesonspec-size-canary heartbeat: growth 16 -> 3.24 GB/wk (TK-11125 payload guard), SourceEvidence 55 -> 82GB, free space 67 -> 44GB (preflight item 1 now FAILS), size canary already armed, step-1 index drop already applied, and the "retention gets turned ON" pull trigger permanently dead per Steve's keep-full-history ruling. Body preserved as written for audit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JhnABoxWtpF7mbBowoBWhb
aaf2c487 · 2026-09-04 · snapshot before restart: preserve in-flight work
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011gbmuMHgCLDEPM4TpfAr4G
ba37b54c · 2026-09-04 · mobile: make the tracker-drift canary baseline-aware (was firing on steady state)
As first written the canary exited 1 whenever ANY uncovered third-party host was present — which is permanently true, because homesonspec.com serves listing photos from www.drhorton.com and awh.widen.net. A canary that fires on the steady state is noise and gets ignored, which is the one failure mode that makes it worthless. Now baseline-aware, per house canary doctrine: known-benign hosts live in tracker-drift-baseline.json, are reported as 'accepted', and do NOT fail. Exit 1 fires only on a host that is NEW since the baseline — an actual worsening transition. Adds --accept to fold a newly verified asset host into the baseline. Baseline seeded with the two hosts verified 2026-09-04 by inspecting the page source: both appear only as <img src> listing photos (D.R. Horton product catalogue, Widen DAM CDN), so they are asset hosts, not trackers. Verified both directions, not just the quiet one: steady state -> PASS, exit 0 simulated new host -> FAIL, names www.drhorton.com, exit 1 baseline restored -> PASS, exit 0 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEhnWQSSkAhSYxWXHJ3MCw
693125b2 · 2026-09-04 · mobile: add tracker-drift canary guarding the 'Data Not Collected' privacy label
The Browse WebView blocks trackers with a DENYLIST (lib/tracker-policy.ts, 7 hosts),
so the App Privacy label's truth is contingent on homesonspec.com's tag set. Add a
pixel whose host is not on that list — a new ad network, a self-hosted fbevents.js,
or a server-side-GTM first-party proxy — and it passes silently, with no app rebuild
to catch it, quietly making a filed 'Data Not Collected' label FALSE. On an account
already cited under Guideline 5.6 for a declaration that did not match a binary, that
is the drift that matters.
The canary fetches the live site, extracts every third-party host, and flags any not
covered by the denylist. Exit 1 on drift.
Current run: BLOCKED = www.googletagmanager.com + connect.facebook.net (the two real
trackers, both covered). UNCOVERED = www.drhorton.com + awh.widen.net, both verified
by inspecting the page as <img src> listing photos (builder product catalogue and the
Widen DAM CDN) — asset hosts, not trackers. So the label is accurate today.
Also confirmed while wiring this up: the blocker IS correctly applied. components/
TrackedWebView.tsx PREPENDS the block script to any caller-supplied
injectedJavaScriptBeforeContentLoaded and AND-s !isTrackerUrl() with the caller's
onShouldStartLoadWithRequest, so a caller cannot accidentally disable it — and the
existing suite enforces it architecturally ('the wrapper is the one place WebView is
imported', 'no file outside the wrapper imports WebView', 'every WebView rendered in
app/ is a TrackedWebView'). 12/12 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEhnWQSSkAhSYxWXHJ3MCw
4df903f1 · 2026-09-04 · mobile: cap rendered map markers (120, densest-first) + lower grid density — fix react-native-maps on-device OOM crash on the Map tab (TK-11155)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQi5poZk3YeUbEJbDcFRmc
f2de197d · 2026-09-04 · Homes on Spec: actually test the tracker-blocking script (TK-10387)
The App Store 'Data Not Collected' claim rests on the injected TRACKER_BLOCK script working. Until now only isTrackerUrl() — the native-side URL filter — had tests. The script doing most of the work (neutering gtag/fbq/dataLayer and intercepting fetch/XHR/Image/sendBeacon inside the page) had none, so 'it looks right' was the only evidence behind a claim we make to Apple. - lib/tracker-block.ts now exports buildTrackerBlock(hosts) and has ZERO imports, so node --test can load it directly (Node's ESM resolver requires explicit extensions, which the TS/Metro resolver does not use). TrackedWebView composes it from the real TRACKER_HOSTS, so the shipped behaviour is unchanged. - lib/tracker-block.test.mjs runs the REAL script text, built from the REAL host list, in a vm sandbox with a fake window/document, and asserts observable behaviour rather than string matching: gtag/fbq/dataLayer.push are no-ops (and dataLayer does not accumulate), tracker fetch short-circuits to an empty 204 while first-party fetch reaches the real implementation, GA4's sendBeacon transport is refused, tracker XHR never sends, the Facebook tr pixel never gets a real src, subdomains of tracker hosts are blocked, and a lookalike domain is NOT blocked so the filter cannot over-reach and break the site. 12/12 tests pass; tsc --noEmit clean. This verifies the MECHANISM only — the panel's binding condition still stands: do not file 'Data Not Collected' until a full-device proxy capture across all four tabs is clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfGYEoLBywwJD1nfrHe1on
2726cf35 · 2026-09-04 · Homes on Spec: correct stale README claims that misled a downstream review (TK-10387)
Item 4 said the EAS projectId was still the SET-AT-EAS-INIT placeholder. It is not — app.json has carried a real projectId for some time. That stale line is what led an earlier review pass to conclude push registration could never fire, which inverted the actual finding: registration DOES succeed, so getExpoPushTokenAsync was handing a device identifier to Expo for an Alerts feature that cannot deliver anything. Item 1 now describes the PUSH_BACKEND_READY gate and states the flip must happen in the same change that wires the backend. Item 5 marked done — /privacy returns 200, verified today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfGYEoLBywwJD1nfrHe1on
d98894aa · 2026-09-03 · Homes on Spec: route every WebView through one hardened TrackedWebView (TK-10387, DTD verdict A)
The Browse tab was hardened against homesonspec.com's GTM/GA4/Meta-pixel, but saved.tsx opened a SECOND raw <WebView> to the same site with no injected tracker block and no URL filter — so trackers ran freely there and an App Store 'Data Not Collected' label would have been FALSE. The leak happened because hardening was a per-call-site ritual that had to be remembered. A DTD panel ruled A (complete the blocking) 4/7, and the contrarian's surviving objection was that A-as-scoped repeats the same failure mode. So this is structural rather than another copy-paste: - components/TrackedWebView.tsx is now the ONLY file importing the WebView component. It always applies TRACKER_BLOCK and the isTrackerUrl filter. A caller's injectedJavaScriptBeforeContentLoaded is APPENDED (never replaces the block), and a caller's onShouldStartLoadWithRequest is AND-ed (can restrict, never loosen). - browse.tsx and saved.tsx both render <TrackedWebView>; browse keeps WebView only as a type import for useRef<WebView>. - lib/webview-guard.test.mjs fails the suite if any file outside the wrapper imports the WebView component or renders a raw <WebView>. It caught a real miss on its first run. Also stops handing a device identifier to a third party for a feature that cannot work: getExpoPushTokenAsync() round-trips to Expo's servers, but the backend registration POST is still commented out, so no alert can ever be delivered. Token minting is now gated behind PUSH_BACKEND_READY (false), to be flipped in the same change that wires the backend. Permission is still requested, so the Alerts toggle is unchanged. tsc --noEmit clean; 5/5 tests pass. Local only — no deploy, no submit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfGYEoLBywwJD1nfrHe1on
92f06c15 · 2026-09-03 · mobile: make Alerts an inert coming-soon state — disable the toggle + stop it requesting notification permission until push is wired (App Store 2.1/5.1.1v hardening, TK-11155)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQi5poZk3YeUbEJbDcFRmc
edbd4388 · 2026-09-03 · web: large mobile-only brand logo leading the homepage hero (TK-11155)
Add a transparent-background house-mark SVG (public/logo-mark.svg, brand navy/orange, distinct from icon.svg's opaque app-icon variant) and render it large (h-36 w-36, capped at 55vw) with the "Homes on Spec" wordmark above the existing "Every new home..." headline in the hero. Scoped with sm:hidden so desktop/tablet layout is unchanged; only mobile viewports get the large lead logo. Verified: pnpm --filter @homesonspec/web build succeeds (Next 16 compiles, typechecks, and generates all routes). Not deployed. Reversible: git revert this commit.
b233a41e · 2026-09-03 · web: disable the site-wide InstallPrompt PWA banner (TK-11155)
Comment out the import + usage of <InstallPrompt /> in layout.tsx rather than deleting the component, so re-enabling the "Add to Home Screen" nag later is a 2-line uncomment. The native iOS/Android app is now the install path Homes on Spec is steering users toward. Reversible: uncomment the two marked lines in layout.tsx, or git revert.
e387ffba · 2026-09-03 · web+mobile: stable data-hos-install-prompt hook + hide banner in app WebView (TK-11155)
- InstallPrompt.tsx: add data-hos-install-prompt to the dialog root so other
surfaces (the mobile app's WebView CSS) can target it reliably without
depending on Tailwind utility classes that may change.
- browse.tsx: add "[data-hos-install-prompt] { display: none !important; }"
to the injected CSS so the site's "Add to Home Screen" banner never shows
inside the native app's Browse WebView (the native app already IS the
install; the web nag is redundant/confusing there).
Reversible: git revert this commit.
9b533a90 · 2026-09-03 · mobile: regenerate splash.png as a large full-screen brand logo (TK-11155)
Original splash.png was a full-screen navy canvas with a tiny centered house-icon + wordmark glyph (content occupied only ~33% of screen height). Regenerated the asset by extracting the icon and wordmark artwork and upscaling/recentering them to ~88-92% of screen width so the logo reads as large/full-screen-prominent on launch, keeping the same #1a3a6e background and expo-splash-screen config (resizeMode: contain, no app.json change needed since the asset itself now fills the frame). Reversible: git revert this commit to restore the small-glyph asset.
e44f3a5f · 2026-09-03 · fix(homesonspec-mobile): add missing app/index.tsx to fix infinite splash hang on real device (TK-11155)
Root cause: expo-router had no route matching the root path ("/"), so
resolving the initial deep link (homesonspec:///) fell through to the
internal "+not-found" fallback - which has no screen actually registered
in the root Stack (app/_layout.tsx only declares the "(tabs)" group).
React Navigation's NavigationContainer never reaches a resolvable ready
state, so it renders its `fallback` (null) forever and the native splash
screen (SplashScreen.hideAsync() never gets a chance to matter) never
clears. No JS error, no crash - a silent, permanent hang confirmed via
device syslog breadcrumbs tracing execution through registerRootComponent
-> ExpoRoot -> getInitialURL -> getStateFromURL (resolved to "+not-found")
and then nothing further for 60+ seconds.
Fix: add app/index.tsx that <Redirect>s "/" to "/(tabs)/browse", giving
the router an always-resolvable initial route. Verified on a physical
iPhone (from-source Release build): app now reaches Browse tab with real
homesonspec.com content and Map tab with live Apple Maps pins.
9e884ed1 · 2026-09-03 · HoS mobile: block GTM/GA4/Facebook trackers in Browse WebView (Guideline 2.1 Path B)
Neutralizes analytics/ad trackers in the homesonspec.com WebView so the app truthfully collects nothing: stubs gtag/dataLayer/fbq/google_tag_manager and intercepts every WKWebView-exposed network primitive (createElement src, Image/img pixels incl. the FB <noscript> fallback, fetch, XHR, sendBeacon) plus a native onShouldStartLoadWithRequest host filter. Verified via WebKit network capture: 5 tracker requests before, 0 after. Also replaces the SET-AT-EAS-INIT push projectId placeholder with the real id from expo-constants (token stays local; no backend POST, no new data collection). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNivxV68DdxP1rvhViBfcN
6a1800df · 2026-09-02 · TK-11125: e2e-proof evidence bundle for the payload guard (R3, scratch DB)
Verdict PASS. 5 data-boundary cases + unit tests, all green on homesonspec_test. Records the no-migration design divergence + gates respected (no prod write/deploy/push). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016JRL7REtkaBnRrfHk42iYm
319168ad · 2026-09-02 · TK-11125: forward-only spurious-generation guard in extractStage
Skip minting a new StagedRecord generation + SourceEvidence set when a new raw snapshot carries byte-identical extracted property data as the latest generation (only volatile page bytes moved). Compares a canonical payload hash against the latest prior-snapshot generation, whose payload is already stored verbatim in StagedRecord.payload — so NO new column and NO migration. Preserves history: every genuine field change still mints a generation, and a same-snapshot FORCE_REEXTRACT still updates in place (snapshotId-equality escape). Guard can only ever skip an exact duplicate, never a real change. Proven at the DB boundary in payload-guard.itest.ts (5 cases, all green). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016JRL7REtkaBnRrfHk42iYm
671fbb26 · 2026-09-02 · TK-11125: add stableStringify + payloadHash canonical hash helper (shared)
Forward-only dedup guard support (spec TK-11125-impl-spec-2026-09-02). Canonical key-sorted JSON hash so a payload compared across a Postgres JSONB round-trip is order-independent; any real change yields a different hash (guard can only ever SKIP on exact match, never suppress a change). Pure code, no schema change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016JRL7REtkaBnRrfHk42iYm
ddb43e67 · 2026-08-31 · TK-10878 Phase 2 drafts: fix 3 fatal + 2 hardening review findings
- p_type: 'native' is invalid; default to 'range' (v5) with flagged v4
'partman' fallback + a version preflight block (SELECT extversion)
- identifier casing: embed quotes 'public."SourceEvidence"' in every
partman call and the retention part_config UPDATE (unquoted folds to
lowercase and silently no-ops the provenance guard)
- backfill exit: CALL does not set ROW_COUNT; loop on count(*) of
SourceEvidence_old instead
- rollback: replace ON CONFLICT ("id") (errors under the new
("id","createdAt") PK) with plain INSERT..SELECT back into _old
- import-sweep guard: abort on recent inserts + note the RENAME is the one
genuinely-blocking step; pause the sweep first
Drafts only; not applied.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21b9aad6 · 2026-08-31 · docs(homesonspec): TK-10878 Phase 2 drafts — pg_partman SourceEvidence conversion + provenance-safe retention (not applied)
Draft-only: monthly RANGE partitions on createdAt with batched backfill and full rollback path; retention DISABLED for SourceEvidence (provenance not prunable) with a manual detach-to-archive review procedure. Plan file updated with a Phase-2 preflight checklist. No prod touch, no migration run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7114f6a3 · 2026-08-31 · fix(homesonspec): summit planName cuts at first '<' — no raw markup on fresh crawls (TK-10487)
Investigating summit ingest rejects surfaced 166 historical staged records whose planName carried raw markup (e.g. "Riverside Collection ... <div class=\"label\" data-reac") — an INCOMPLETE tag opener that survives plainText's tag-strip when the 3000-char overview slice ends mid-element. The earlier end-anchored fix (<[^>]*$) missed the mid-string case. Now planName is cut at the first '<' (a plan name never contains markup), so fresh crawls emit clean plan names. NOTE: the ingest rejects themselves are NOT this bug — they are the dup.no-active- address integrity rule correctly rejecting re-crawls of addresses that already have an active inventory record (summit had 816 from prior runs). The pipeline dedup gate is working as designed. tsc 0; vitest 11/11. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8ffc6951 · 2026-08-30 · fix(homesonspec): correct 2 more dead CPG seed termsUrls (brohn/summit /terms-of-use 404 -> claytonhomes.com/legal) (TK-10487)
A full seed-URL reachability sweep found brohn + summit still carried the pattern-guessed /terms-of-use that 404s (same class as the oakwood dead-domain + mungo/chafin fixes). Repointed both to the footer-verified Clayton parent legal (brohn's footer explicitly delegates there). All 13 CPG seed website+termsUrl now resolve 200. Full monorepo typecheck clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a0335075 · 2026-08-30 · test(homesonspec): backfill committed selftests for brohn/oakwood/summit — all 13 CPG collectors now fixture-verified (TK-10487)
The 3 batch-1 CPG collectors were live-verified only (no committed fixture-backed selftests). Backfilled to the hardened standard (12 real fixtures each, --compressed, distinct addr+id, honest nulls asserted directly, exact-value snapshot, status branches exercised, schema-valid; secrets scrubbed to placeholders — incl a Segment analytics _writeKey in brohn that gitleaks correctly blocked on the first attempt): - brohn-homes: 11 tests, 12 TX homes, MOVE_IN_READY+UNDER_CONSTRUCTION + SF/TOWNHOME. - oakwood-homes: 13 tests, 12 Colorado homes (oakwoodhomesco.com confirmed live; the dead seed domain oakwoodhomesnc.com fixed separately). +export classifyStatus/toIsoDate. - summit-homes-kc: 11 tests, 12 KS/MO homes. REAL BUG FIXED: plan-name parse swallowed raw markup at a 3000-char slice boundary (home-05/12) -> dangling-tag strip in plainText + a regression test. +export parseHome/isDetailUrl. Whole-workspace typecheck clean. Now 13/13 CPG collectors have committed selftests. Local build/test only; ingest/seed/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57212c91 · 2026-08-30 · fix(homesonspec): correct dead Oakwood seed domain oakwoodhomesnc.com(000) -> live oakwoodhomesco.com (TK-10487)
The seed pointed Oakwood at oakwoodhomesnc.com which is dead (HTTP 000); the live adapter target + real CPG Oakwood site is oakwoodhomesco.com (Colorado, Clayton- referenced). termsUrl repointed to the footer-verified Clayton parent legal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
235736eb · 2026-08-30 · fix(homesonspec): berkeley-building — real self-card isolation test + status docs (TK-10487 Cody gate)
Cody confirmed the extraction is CORRECT (exact-path self-card status does not cross-contaminate siblings; no fabrication; garage/lot genuinely absent; ids distinct) but flagged test-quality holes: - The sibling-isolation test was a DECOY — it proved isolation only against a NONEXISTENT path. Replaced with a same-page multi-path test (home-08): each real sibling path resolves to its OWN card's verified label+status (2069 -> Available December 2026/UNDER_CONSTRUCTION vs 2079 -> Model Home/MOVE_IN_READY on the SAME html) — genuine exact-path isolation. Proven to FAIL when the match is loosened (it then grabs the first card). It also exercises the Pending->null + Available<Month>/Under-Construction + Quick-Move-In/Model branches END-TO-END, which no PRIMARY-home fixture triggers. - Documented the "Model Home -> MOVE_IN_READY with price=null" semantic tension (constructionStatus claim, NOT sales-availability) so downstream never renders it as "for sale now". - Documented the HomeCard__status immediate-child platform assumption (a break is a LOUD cov.status===n failure, not a silent mislabel). tsc 0; vitest 11/11. Local build/test only; ingest/seed/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9eb0f321 · 2026-08-30 · wire(homesonspec): register Elite Homes (Louisville KY CPG) collector (TK-10487)
Add elite-homes-site to the worker CLI ADAPTERS map + workers deps + the CPG seed (website elitebuilthomes.com, Kentucky/Louisville, claytonhomes.com/legal termsUrl). workers + database typecheck exit 0. Ingest/seed-run/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d575caa2 · 2026-08-30 · feat(homesonspec): Elite Homes (Louisville KY CPG) collector (TK-10487)
Cycle-4 CPG collector for Elite Homes (Clayton Properties Group; JSON-LD
brand.name="Elite Homes"; Louisville KY metro). Source elitebuilthomes.com — same
React-SSR JSON-LD platform as arbor/silverthorne (--compressed required). 10 real
homes (all of the sitemap inventory), 10 distinct addr+id (N=10 makes the distinct
assertions genuinely bite), JSON-LD SingleFamilyResidence + HomeOverview.
Cody gate caught a REAL data-quality BLOCKER (not just test hardening): status was
read from the HomeOverview_lead marketing prose, which carries the phrase on only
2/10 homes -> 8/10 genuinely MOVE_IN_READY homes were emitted status=null, hidden
behind a toothless `<= n` assertion. Fixed: status now reads the authoritative
Carousel_h2Lead banner ("Move-In Ready"/"Quick Move-In" present on all 10),
prose as fallback. Test now asserts cov.status===n + pins status in the snapshot +
strips BOTH sources for the semantic-null proof — all proven to fail on the old bug.
Selector drift vs siblings: 3-seg detail URL, garage honest-null (Elite omits it),
status from Carousel banner. tsc 0; vitest 10/10. Local build/test only; gated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c233bfe9 · 2026-08-30 · wire(homesonspec): register Silverthorne Homes (Indianapolis CPG) collector (TK-10487)
Add silverthorne-site to the worker CLI ADAPTERS map + workers deps + the CPG seed (website silverthornehomes.com, Indiana luxury, claytonhomes.com/legal termsUrl). workers + database typecheck exit 0. Ingest/seed-run/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f0d509ba · 2026-08-30 · feat(homesonspec): Silverthorne Homes (Indianapolis CPG) collector (TK-10487)
Cycle-3 CPG collector for Silverthorne Homes — Arbor's luxury sister company (JSON-LD sameAs -> linkedin.com/company/yourarborhome), Indianapolis, Clayton Properties Group. Source silverthornehomes.com (same React-SSR JSON-LD platform as arbor; --compressed required — server gzips). Identity verified: Indiana (McCordsville), not the Colorado town. Source of truth = per-home JSON-LD SingleFamilyResidence/Product + HomeOverview spec list. HONEST inventory: Silverthorne is low-volume luxury — the sitemap lists exactly 1 available spec home; captured it, floor set to the real count (1), NOT padded. Selector drift from arbor handled: garage IS published here (parsed, not null'd); status derived from HomeOverview_lead prose via statusFromLead. Cody gate: extraction confirmed correct + inventory-honest; N=1 test-quality holes fixed — added an exact-value SNAPSHOT test pinning all 14 fields (coverage-% is tautological at N=1; the snapshot is what actually catches a misparse — proven to fail on a flipped value), documented the N=1 distinct-assertion limitation, and disclosed the GTM scrub in _urls.tsv. tsc 0; vitest 10/10. Local build/test only; wiring/ingest/seed/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
86d5d249 · 2026-08-30 · wire(homesonspec): register Arbor Homes (Indianapolis CPG) collector (TK-10487)
Add arbor-site to the worker CLI ADAPTERS map + workers deps + the CPG seed (website yourarborhome.com, coverage IN/KY/OH, footer-verified claytonhomes.com /legal termsUrl). workers + database typecheck exit 0. Ingest/seed-run/deploy gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9e1cea83 · 2026-08-30 · feat(homesonspec): Arbor Homes (Indianapolis CPG) collector — yourarborhome.com (TK-10487)
Cycle-2 CPG collector for the REAL Arbor Homes (the Indianapolis builder Clayton Properties Group acquired 2018), source yourarborhome.com. A prior build against arborhomes.com was DISCARDED — that domain is an unrelated Oregon builder (2 homes, no CPG affiliation); research (claytonhomes.com press release) confirmed the CPG Arbor is yourarborhome.com + its sister Silverthorne is silverthornehomes.com. Source of truth = per-home JSON-LD SingleFamilyResidence/Product (address/geo/price via offers[].price/community via containedIn.name/id via 24-hex productId), with beds/baths/sqft/stories/lot from the PRIMARY home's HomeOverview list (never sibling HomeCard blocks). 12 fixtures across IN/KY/OH, 12 distinct addr+id, schema-clean. Honest nulls: garage (0%, no field), price (Model + coming-soon homes), status (Model home). state/ZIP3 guard nulls a self-contradictory ZIP. Cody gate: core parser confirmed contamination-free; test-coverage holes fixed — added a direct semantic-null assertion on the real Model fixture + a statusFromLead unit test exercising the PLANNED/UNDER_CONSTRUCTION branches no fixture triggers (both proven to fail on an injected bug). tsc exit 0; vitest 8/8. Local build/test only; wiring/ingest/seed/deploy gated. sitemap has 112 homes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ab1b4f74 · 2026-08-30 · fix(homesonspec): harris-doyle uses authoritative dataLayer, not fragile DOM (TK-10487 Cody gate)
Contrarian red-team caught the just-registered adapter shipping 3 data-quality
defects; all reproduced against the captured fixtures and fixed:
- community name: the hero community-anchor regex was DEAD (hrefs are
entity-encoded /, not /), silently falling back to a slug titlecaser that
mis-cased prepositions ("Foothills At Blackridge"). Now read from the builder's
own dataLayer ("113 | The Foothills at Blackridge") -> correct case. Slug
fallback also fixed to keep joining words lowercase.
- status: was a hardcoded MOVE_IN_READY constant with a truthy-only "coverage"
test (theater). Now mapped from the dataLayer pageType via statusFromPageType()
(honest null when absent); the selftest proves it goes null on an unknown type.
- zip: the site itself publishes a wrong ZIP on some homes (AL homes tagged FL's
32542). Added a state<->ZIP3 guard (AL/FL, extensible) that nulls a ZIP that
can't belong to the parsed state — honest null over known-wrong data.
New selftest asserts community names are naturally cased (no mid-name title-cased
prepositions). tsc --noEmit exit 0; vitest 5/5. Facts-only; local build/test only;
ingest/seed/deploy remain gated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
73a0e94f · 2026-08-30 · TK-10809: snapshot-verify catches DEST symlink false-green before gated delete
FIX1: lstatSync existence check + distinct 'symlink' verdict; never hash-follow a DEST symlink (rsync -a preserves links; a link back to SRC would sha-match and score 'ok' right before a gated delete wipes the real file). Wired through offload-snapshots counters/summary/slice-print/clean-check so a symlink forces clean=false. FIX2: +2 tests — absolute-under-SRC legacy-row shape classifies 'ok'; DEST symlink back to SRC classifies 'symlink' (not 'ok') and proves non-destructive (SRC intact). FIX3: explicit BLOCKING breakdown line (miss/mismatch/symlink/abs-not-under-src). FIX4: runbook — step 5 is a prerequisite for step 4 PASSING when abs-not-under-src>0.
a7904b1e · 2026-08-30 · fix(homesonspec): correct fabricated CPG termsUrls in seed (TK-10487)
Mungo /terms-of-use and Chafin /terms-of-use/ were pattern-guessed by the batch-2 build loop and both 404. Replaced with footer-verified 200 URLs: mungo.com/legal and the CPG-parent claytonhomes.com/legal that Chafin's own footer links (Chafin has no standalone terms page). Facts-only; seed is not executed (seeding stays Steve-gated). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
aff87907 · 2026-08-30 · TK-10809: offload VERIFY — no false PASS on a sample, tally wrong --src
FIX1: show sampled/total + coverage% of the WHOLE store; a clean SAMPLE prints 'VERIFY PASS (SAMPLE ONLY …)' + a loud not-proof warning and, under --apply, exits 3 (distinct) so automation can't treat sample-only as a proven-clean copy. FULL+clean=0, any dirty=1. FIX3: count abs-not-under-src rows separately (wrong --src, not a copy failure) so the operator can tell it from an incomplete copy. Uses the shared resolver. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d461d39d · 2026-08-30 · TK-10809: single shared snapshot-path resolver (ops/lib), kill 3-way drift
Extract relTail/resolveAgainstDir/resolveAgainstDest into ops/lib/snapshot-resolve.mjs and import it in verify-snapshots.mjs + backfill-drh-geo-from-cache.mjs. Make the TS resolveSnapshotPath strip the same var/snapshots/ tail so it stops lying about being the single source of truth; add the tail-strip test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
File tree
- .env.example
- .gitignore
- COMPETITIVE_ANALYSIS.md
- DEPLOY.md
- README.md
- apps/admin/next-env.d.ts
- apps/admin/next.config.ts
- apps/admin/package.json
- apps/admin/postcss.config.mjs
- apps/admin/src/app/api/engine-log/route.ts
- apps/admin/src/app/api/ingestion-stats/route.ts
- apps/admin/src/app/api/review/route.ts
- apps/admin/src/app/business/SortableTable.tsx
- apps/admin/src/app/business/page.tsx
- apps/admin/src/app/corrections/page.tsx
- apps/admin/src/app/engine/EngineLive.tsx
- apps/admin/src/app/engine/page.tsx
- apps/admin/src/app/globals.css
- apps/admin/src/app/ingestion/IngestionLive.tsx
- apps/admin/src/app/ingestion/page.tsx
- apps/admin/src/app/layout.tsx
- apps/admin/src/app/leads/page.tsx
- apps/admin/src/app/live/LivePreview.tsx
- apps/admin/src/app/live/page.tsx
- apps/admin/src/app/page.tsx
- apps/admin/src/app/review/ReviewActions.tsx
- apps/admin/src/app/review/page.tsx
- apps/admin/src/app/snapshots/page.tsx
- apps/admin/src/app/sources/page.tsx
- apps/admin/src/app/validation/page.tsx
- apps/admin/src/middleware.ts
- apps/admin/tsconfig.json
- apps/mobile/.gitignore
- apps/mobile/APP-STORE-LISTING.md
- apps/mobile/ASC-METADATA.md
- apps/mobile/ASC-PASTE-KIT.md
- apps/mobile/DEVICE-CAPTURE.md
- apps/mobile/README.md
- apps/mobile/SCREENSHOT-SHOTLIST.md
- apps/mobile/_recovered/homesonspec-build2.ipa
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/AppIcon60x60@2x.png
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/AppIcon76x76@2x~ipad.png
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Assets.car
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/EXConstants.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/EXConstants.bundle/app.config
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Expo.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoApplication_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoApplication_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoConstants_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoConstants_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoFileSystem_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoNotifications_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/ExpoNotifications_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFileSystem.framework/ExpoFileSystem
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFileSystem.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFileSystem.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFont.framework/ExpoFont
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFont.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoFont.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesCore.framework/ExpoModulesCore
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesCore.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesCore.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesJSI.framework/ExpoModulesJSI
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesJSI.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesJSI.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesWorklets.framework/ExpoModulesWorklets
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesWorklets.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ExpoModulesWorklets.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/React.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/React.framework/React
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/React.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_boost.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_boost.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_folly.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_folly.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_glog.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/ReactNativeDependencies_glog.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/ReactNativeDependencies.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/hermesvm.framework/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/hermesvm.framework/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Frameworks/hermesvm.framework/hermesvm
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/HomesonSpec
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/PkgInfo
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/RNCAsyncStorage_resources.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/RNCAsyncStorage_resources.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-Core_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-Core_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-cxxreact_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-cxxreact_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-timing_privacy.bundle/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/React-timing_privacy.bundle/PrivacyInfo.xcprivacy
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/SplashScreen.storyboardc/EXPO-VIEWCONTROLLER-1-view-EXPO-ContainerView.nib
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/SplashScreen.storyboardc/Info.plist
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/SplashScreen.storyboardc/SplashScreenViewController.nib
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/_CodeSignature/CodeResources
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/embedded.mobileprovision
- apps/mobile/_recovered/hx/Payload/HomesonSpec.app/main.jsbundle
- apps/mobile/_recovered/hx/Symbols/154A708D-4C97-3216-AD93-9830609DBC29.symbols
- apps/mobile/_recovered/hx/Symbols/903F9CB7-DBBE-3903-BF0E-4695C5EC362F.symbols
- apps/mobile/_recovered/hx/Symbols/C902FD19-95D2-30F8-B0BC-C3FED2B361DB.symbols
- apps/mobile/_recovered/hx/Symbols/CFFF0ACD-9CD8-37A3-8127-F128196D16F2.symbols
- apps/mobile/_recovered/hx/Symbols/D5125F60-E6E4-3200-B818-0B91781F1A51.symbols
- apps/mobile/_recovered/hx/Symbols/EA3AF269-9DC7-3041-BFF9-0BD60D1DA3B2.symbols
- apps/mobile/app.json
- apps/mobile/app/(tabs)/_layout.tsx
- apps/mobile/app/(tabs)/alerts.tsx
- apps/mobile/app/(tabs)/browse.tsx
- apps/mobile/app/(tabs)/map.tsx
- apps/mobile/app/(tabs)/saved.tsx
- apps/mobile/app/_layout.tsx
- apps/mobile/app/index.tsx
- apps/mobile/assets/adaptive-icon.png
- apps/mobile/assets/icon.png
- apps/mobile/assets/splash.png
- apps/mobile/babel.config.js
- apps/mobile/components/TrackedWebView.tsx
- apps/mobile/device-proof-evidence/BUILD3-stills-2026-09-04T13-10-12Z/1-browse.png
- apps/mobile/device-proof-evidence/BUILD3-stills-2026-09-04T13-10-12Z/2-saved.png
- apps/mobile/device-proof-evidence/BUILD3-stills-2026-09-04T13-10-12Z/3-map.png
- apps/mobile/device-proof-evidence/BUILD3-stills-2026-09-04T13-10-12Z/4-alerts.png
- apps/mobile/device-proof-evidence/BUILD3-stills-2026-09-04T13-10-12Z/5-browse-return.png
- apps/mobile/device-proof-evidence/FINAL-stills-2026-09-03T22-28-13Z/1-browse.png
- apps/mobile/device-proof-evidence/FINAL-stills-2026-09-03T22-28-13Z/2-saved.png
- apps/mobile/device-proof-evidence/FINAL-stills-2026-09-03T22-28-13Z/3-map.png
- apps/mobile/device-proof-evidence/FINAL-stills-2026-09-03T22-28-13Z/4-alerts.png
- apps/mobile/device-proof-evidence/FINAL-stills-2026-09-03T22-28-13Z/5-browse-return.png
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-2026-09-03T21-10-10Z.mov
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-2026-09-03T21-10-10Z.mov.privacy-reviewed.sha256
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-BUILD3-2026-09-04T13-10-12Z.mov
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-BUILD3-2026-09-04T13-10-12Z.mov.privacy-reviewed.sha256
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-2026-09-03T22-28-13Z.mov
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-2026-09-03T22-28-13Z.mov.privacy-reviewed.sha256
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-mapfixed-2026-09-04T15-31-01Z.mov
- apps/mobile/device-proof-evidence/homesonspec-DEVICE-journey-FINAL-mapfixed-2026-09-04T15-31-01Z.mov.privacy-reviewed.sha256
- apps/mobile/device-proof-evidence/privacy-sweep-2026-09-03T21-10-10Z.jpg
- apps/mobile/device-proof-evidence/privacy-sweep-BUILD3-2026-09-04T13-10-12Z.jpg
- apps/mobile/device-proof-evidence/privacy-sweep-FINAL-2026-09-03T22-28-13Z.jpg
- apps/mobile/device-proof-evidence/stills-2026-09-03T21-10-10Z/1-browse.png
- apps/mobile/device-proof-evidence/stills-2026-09-03T21-10-10Z/2-saved.png
- apps/mobile/device-proof-evidence/stills-2026-09-03T21-10-10Z/3-map.png
- apps/mobile/device-proof-evidence/stills-2026-09-03T21-10-10Z/4-alerts.png
- apps/mobile/device-proof-evidence/stills-2026-09-03T21-10-10Z/5-browse-return.png
- apps/mobile/eas.json
- apps/mobile/finish-homesonspec-appstore.sh
- apps/mobile/lib/api.ts
- apps/mobile/lib/notifications.ts
- apps/mobile/lib/storage.ts
- apps/mobile/lib/tracker-block.test.mjs
- apps/mobile/lib/tracker-block.ts
- apps/mobile/lib/tracker-policy.test.mjs
- apps/mobile/lib/tracker-policy.ts
- apps/mobile/lib/webview-guard.test.mjs
- apps/mobile/package.json
- apps/mobile/screenshots/00-current-state.png
- apps/mobile/screenshots/01-landing.png
- apps/mobile/screenshots/final/01-map.png
- apps/mobile/screenshots/final/02-detail.png
- apps/mobile/screenshots/final/03-browse.png
- apps/mobile/screenshots/final/04-saved.png
- apps/mobile/screenshots/final/05-alerts.png
- apps/mobile/screenshots/final/06-filter.png
- apps/mobile/screenshots/final67/01-map.png
- apps/mobile/screenshots/final67/02-detail.png
- apps/mobile/screenshots/final67/03-browse.png
- apps/mobile/screenshots/final67/04-saved.png
- apps/mobile/screenshots/final67/05-alerts.png
- apps/mobile/screenshots/final67/06-filter.png
- apps/mobile/screenshots/gen/01-map.png
- apps/mobile/screenshots/gen/02-search.png
- apps/mobile/screenshots/gen/03-home.png
- apps/mobile/screenshots/gen/04-builders.png
- apps/mobile/screenshots/gen/05-saved.png
- apps/mobile/screenshots/ipad13/01-map.png
- apps/mobile/screenshots/ipad13/02-detail.png
- apps/mobile/screenshots/ipad13/03-browse.png
- apps/mobile/screenshots/ipad13/04-saved.png
- apps/mobile/screenshots/ipad13/05-alerts.png
- apps/mobile/screenshots/ipad13/06-filter.png
- apps/mobile/scripts/build-ios-prod.exp
- apps/mobile/scripts/caption-shot.py
- apps/mobile/scripts/tracker-drift-baseline.json
- apps/mobile/scripts/tracker-drift-check.mjs
- apps/mobile/scripts/vshots/.gitignore
- apps/mobile/scripts/vshots/build.sh
- apps/mobile/scripts/vshots/chrome.js
- apps/mobile/scripts/vshots/common.css
- apps/mobile/scripts/vshots/data.js
- apps/mobile/scripts/vshots/frame-and-caption.py
- apps/mobile/scripts/vshots/raw/01-map.png
- apps/mobile/scripts/vshots/shot-map.html
- apps/mobile/scripts/vshots/shot-native.html
- apps/mobile/tsconfig.json
- apps/web/next-env.d.ts
- apps/web/next.config.ts
- apps/web/package.json
- apps/web/postcss.config.mjs
- apps/web/public/ads.txt
- apps/web/public/apple-touch-icon.png
- apps/web/public/favicon-32.png
- apps/web/public/icon-192.png
- apps/web/public/icon-512.png
- apps/web/public/icon.svg
- apps/web/public/logo-mark.svg
- apps/web/public/offline.html
- apps/web/public/sw.js
- apps/web/scripts/gen-pwa-icons.mjs
- apps/web/scripts/verify-install-prompt.mjs
- apps/web/scripts/verify-pwa.mjs
- apps/web/src/app/HeroMap.tsx
- apps/web/src/app/[state]/[city]/page.tsx
- apps/web/src/app/api/corrections/route.ts
- apps/web/src/app/api/facets/route.ts
- apps/web/src/app/api/leads/route.ts
- apps/web/src/app/api/map/route.ts
- apps/web/src/app/api/pwa-event/route.ts
- apps/web/src/app/api/search/route.ts
- apps/web/src/app/builders/[slug]/page.tsx
- apps/web/src/app/builders/page.tsx
- apps/web/src/app/communities/[slug]/page.tsx
- apps/web/src/app/compare/page.tsx
- apps/web/src/app/contact/ContactClient.tsx
- apps/web/src/app/contact/page.tsx
- apps/web/src/app/globals.css
- apps/web/src/app/homes/[id]/CorrectionForm.tsx
- apps/web/src/app/homes/[id]/LeadForm.tsx
- apps/web/src/app/homes/[id]/NearbySubs.tsx
- apps/web/src/app/homes/[id]/page.tsx
- apps/web/src/app/layout.tsx
- apps/web/src/app/manifest.ts
- apps/web/src/app/map/MapCanvas.tsx
- apps/web/src/app/map/MapExplorer.tsx
- apps/web/src/app/map/page.tsx
- apps/web/src/app/page.tsx
- apps/web/src/app/plans/[id]/page.tsx
- apps/web/src/app/privacy/page.tsx
- apps/web/src/app/saved/page.tsx
- apps/web/src/app/search/SearchClient.tsx
- apps/web/src/app/search/page.tsx
- apps/web/src/components/AdSlot.tsx
- apps/web/src/components/InstallPrompt.tsx
- apps/web/src/components/PWARegister.tsx
- apps/web/src/lib/analytics.ts
- apps/web/src/lib/contractors.ts
- apps/web/src/lib/parcel.ts
- apps/web/src/lib/parse-search.ts
- apps/web/src/lib/trades.ts
- apps/web/tsconfig.json
- apps/workers/apply-lennar-images.sh
- apps/workers/package.json
- apps/workers/scripts/enrich-nearby.ts
- apps/workers/scripts/register-pacific-regionals.ts
- apps/workers/src/cli.ts
- apps/workers/src/health-server.test.ts
- apps/workers/src/health-server.ts
- apps/workers/src/index.ts
- apps/workers/src/lennar-mac-fetch.mts
- apps/workers/src/payload-guard.itest.ts
- apps/workers/src/pipeline.itest.ts
- apps/workers/src/pipeline.ts
- apps/workers/src/queue-resilience.itest.ts
- apps/workers/src/snapshot-path.test.ts
- apps/workers/src/snapshot-path.ts
- apps/workers/src/verify-cli.ts
- apps/workers/src/verify.test.ts
- apps/workers/src/verify.ts
- apps/workers/tsconfig.json
- apps/workers/vitest.integration.config.ts
- apps/workers/vitest.integration.setup.ts
- cert-homesonspec.sh
- collectors/BUILDERS.md
- collectors/SPECS-AUDIT.md
- collectors/arbor/.gitignore
- collectors/arbor/fixtures/homes/_urls.tsv
- collectors/arbor/fixtures/homes/home-01.html
- collectors/arbor/fixtures/homes/home-02.html
- collectors/arbor/fixtures/homes/home-03.html
- collectors/arbor/fixtures/homes/home-04.html
- collectors/arbor/fixtures/homes/home-05.html
- collectors/arbor/fixtures/homes/home-06.html
- collectors/arbor/fixtures/homes/home-07.html
- collectors/arbor/fixtures/homes/home-08.html
- collectors/arbor/fixtures/homes/home-09.html
- collectors/arbor/fixtures/homes/home-10.html
- collectors/arbor/fixtures/homes/home-11.html
- collectors/arbor/fixtures/homes/home-12.html
- collectors/arbor/package.json
- collectors/arbor/src/index.ts
- collectors/arbor/src/selftest.test.ts
- collectors/arbor/tsconfig.json
- collectors/ashton-woods/fixtures/austin-321-possumhaw-lane.html
- collectors/ashton-woods/package.json
- collectors/ashton-woods/src/index.test.ts
- collectors/ashton-woods/src/index.ts
- collectors/ashton-woods/tsconfig.json
- collectors/beazer/package.json
- collectors/beazer/src/index.ts
- collectors/beazer/tsconfig.json
- collectors/berkeley-building/.gitignore
- collectors/berkeley-building/fixtures/homes/_urls.tsv
- collectors/berkeley-building/fixtures/homes/home-01.html
- collectors/berkeley-building/fixtures/homes/home-02.html
- collectors/berkeley-building/fixtures/homes/home-03.html
- collectors/berkeley-building/fixtures/homes/home-04.html
- collectors/berkeley-building/fixtures/homes/home-05.html
- collectors/berkeley-building/fixtures/homes/home-06.html
- collectors/berkeley-building/fixtures/homes/home-07.html
- collectors/berkeley-building/fixtures/homes/home-08.html
- collectors/berkeley-building/fixtures/homes/home-09.html
- collectors/berkeley-building/fixtures/homes/home-10.html
- collectors/berkeley-building/fixtures/homes/home-11.html
- collectors/berkeley-building/fixtures/homes/home-12.html
- collectors/berkeley-building/package.json
- collectors/berkeley-building/src/index.ts
- collectors/berkeley-building/src/selftest.test.ts
- collectors/berkeley-building/tsconfig.json
- collectors/brohn-homes/.gitignore
- collectors/brohn-homes/fixtures/homes/_urls.tsv
- collectors/brohn-homes/fixtures/homes/home-01.html
- collectors/brohn-homes/fixtures/homes/home-02.html
- collectors/brohn-homes/fixtures/homes/home-03.html
- collectors/brohn-homes/fixtures/homes/home-04.html
- collectors/brohn-homes/fixtures/homes/home-05.html
- collectors/brohn-homes/fixtures/homes/home-06.html
- collectors/brohn-homes/fixtures/homes/home-07.html
- collectors/brohn-homes/fixtures/homes/home-08.html
- collectors/brohn-homes/fixtures/homes/home-09.html
- collectors/brohn-homes/fixtures/homes/home-10.html
- collectors/brohn-homes/fixtures/homes/home-11.html
- collectors/brohn-homes/fixtures/homes/home-12.html
- collectors/brohn-homes/package.json
- collectors/brohn-homes/src/index.ts
- collectors/brohn-homes/src/selftest.test.ts
- collectors/brohn-homes/tsconfig.json
- collectors/brookfield/package.json
- collectors/brookfield/src/index.ts
- collectors/brookfield/tsconfig.json
- collectors/century-communities/package.json
- collectors/century-communities/src/index.ts
- collectors/century-communities/tsconfig.json
- collectors/chafin-communities/fixtures/homes/_urls.tsv
- collectors/chafin-communities/fixtures/homes/home-01.html
- collectors/chafin-communities/fixtures/homes/home-02.html
- collectors/chafin-communities/fixtures/homes/home-03.html
- collectors/chafin-communities/fixtures/homes/home-04.html
- collectors/chafin-communities/fixtures/homes/home-05.html
- collectors/chafin-communities/fixtures/homes/home-06.html
- collectors/chafin-communities/fixtures/homes/home-07.html
- collectors/chafin-communities/fixtures/homes/home-08.html
- collectors/chafin-communities/package.json
- collectors/chafin-communities/selftest-live.mts
- collectors/chafin-communities/src/index.ts
- collectors/chafin-communities/src/selftest.test.ts
- collectors/chafin-communities/tsconfig.json
- collectors/clayton-properties/RECON.md
- collectors/common/package.json
- collectors/common/src/adapter.ts
- collectors/common/src/index.ts
- collectors/common/src/live-fetch.ts
- collectors/common/src/robots.selftest.ts
- collectors/common/tsconfig.json
- collectors/david-weekley/fixtures/dfw-homes-ready-soon.html
- collectors/david-weekley/package.json
- collectors/david-weekley/src/index.test.ts
- collectors/david-weekley/src/index.ts
- collectors/david-weekley/tsconfig.json
- collectors/discovery/package.json
- collectors/discovery/src/index.ts
- collectors/discovery/tsconfig.json
- collectors/dr-horton/package.json
- collectors/dr-horton/src/index.ts
- collectors/dr-horton/tsconfig.json
- collectors/dream-finders/package.json
- collectors/dream-finders/src/index.ts
- collectors/dream-finders/tsconfig.json
- collectors/drees-homes/package.json
- collectors/drees-homes/src/index.ts
- collectors/drees-homes/tsconfig.json
- collectors/elite-homes/.gitignore
- collectors/elite-homes/fixtures/homes/_urls.tsv
- collectors/elite-homes/fixtures/homes/home-01.html
- collectors/elite-homes/fixtures/homes/home-02.html
- collectors/elite-homes/fixtures/homes/home-03.html
- collectors/elite-homes/fixtures/homes/home-04.html
- collectors/elite-homes/fixtures/homes/home-05.html
- collectors/elite-homes/fixtures/homes/home-06.html
- collectors/elite-homes/fixtures/homes/home-07.html
- collectors/elite-homes/fixtures/homes/home-08.html
- collectors/elite-homes/fixtures/homes/home-09.html
- collectors/elite-homes/fixtures/homes/home-10.html
- collectors/elite-homes/package.json
- collectors/elite-homes/src/index.ts
- collectors/elite-homes/src/selftest.test.ts
- collectors/elite-homes/tsconfig.json
- collectors/fischer-homes/package.json
- collectors/fischer-homes/selftest.mjs
- collectors/fischer-homes/src/index.ts
- collectors/fischer-homes/tsconfig.json
- collectors/fulton-homes/package.json
- collectors/fulton-homes/src/index.ts
- collectors/fulton-homes/tsconfig.json
- collectors/gl-homes/package.json
- collectors/gl-homes/src/index.ts
- collectors/gl-homes/tsconfig.json
- collectors/goodall-homes/fixtures/homes/_urls.tsv
- collectors/goodall-homes/fixtures/homes/home-01.html
- collectors/goodall-homes/fixtures/homes/home-02.html
- collectors/goodall-homes/fixtures/homes/home-03.html
- collectors/goodall-homes/fixtures/homes/home-04.html
- collectors/goodall-homes/fixtures/homes/home-05.html
- collectors/goodall-homes/fixtures/homes/home-06.html
- collectors/goodall-homes/fixtures/homes/home-07.html
- collectors/goodall-homes/fixtures/homes/home-08.html
- collectors/goodall-homes/fixtures/homes/home-09.html
- collectors/goodall-homes/fixtures/homes/home-10.html
- collectors/goodall-homes/fixtures/homes/home-11.html
- collectors/goodall-homes/fixtures/homes/home-12.html
- collectors/goodall-homes/fixtures/homes/home-13.html
- collectors/goodall-homes/fixtures/homes/home-14.html
- collectors/goodall-homes/package.json
- collectors/goodall-homes/src/index.ts
- collectors/goodall-homes/src/selftest.test.ts
- collectors/goodall-homes/tsconfig.json
- collectors/harris-doyle/fixtures/homes/_urls.tsv
- collectors/harris-doyle/fixtures/homes/home-01.html
- collectors/harris-doyle/fixtures/homes/home-02.html
- collectors/harris-doyle/fixtures/homes/home-03.html
- collectors/harris-doyle/fixtures/homes/home-04.html
- collectors/harris-doyle/fixtures/homes/home-05.html
- collectors/harris-doyle/fixtures/homes/home-06.html
- collectors/harris-doyle/fixtures/homes/home-07.html
- collectors/harris-doyle/fixtures/homes/home-08.html
- collectors/harris-doyle/fixtures/homes/home-09.html
- collectors/harris-doyle/fixtures/homes/home-10.html
- collectors/harris-doyle/fixtures/homes/home-11.html
- collectors/harris-doyle/fixtures/homes/home-12.html
- collectors/harris-doyle/fixtures/homes/home-13.html
- collectors/harris-doyle/fixtures/homes/home-14.html
- collectors/harris-doyle/package.json
- collectors/harris-doyle/src/index.ts
- collectors/harris-doyle/src/selftest.test.ts
- collectors/harris-doyle/tsconfig.json
- collectors/highland-homes-fl/.gitignore
- collectors/highland-homes-fl/fixtures/homes/_urls.tsv
- collectors/highland-homes-fl/fixtures/homes/home-01.html
- collectors/highland-homes-fl/fixtures/homes/home-02.html
- collectors/highland-homes-fl/fixtures/homes/home-03.html
- collectors/highland-homes-fl/fixtures/homes/home-04.html
- collectors/highland-homes-fl/fixtures/homes/home-05.html
- collectors/highland-homes-fl/fixtures/homes/home-06.html
- collectors/highland-homes-fl/fixtures/homes/home-07.html
- collectors/highland-homes-fl/fixtures/homes/home-08.html
- collectors/highland-homes-fl/package.json
- collectors/highland-homes-fl/src/index.ts
- collectors/highland-homes-fl/src/selftest.test.ts
- collectors/highland-homes-fl/tsconfig.json
- collectors/highland-homes/package.json
- collectors/highland-homes/src/index.ts
- collectors/highland-homes/tsconfig.json
- collectors/holt-homes/package.json
- collectors/holt-homes/src/index.ts
- collectors/holt-homes/tsconfig.json
- collectors/kb-home/package.json
- collectors/kb-home/src/index.ts
- collectors/kb-home/tsconfig.json
- collectors/khovnanian/package.json
- collectors/khovnanian/src/index.ts
- collectors/khovnanian/tsconfig.json
- collectors/landsea-homes/package.json
- collectors/landsea-homes/src/index.ts
- collectors/landsea-homes/tsconfig.json
- collectors/legacy-al/.gitignore
- collectors/legacy-al/fixtures/homes/_urls.tsv
- collectors/legacy-al/fixtures/homes/home-01.html
- collectors/legacy-al/fixtures/homes/home-02.html
- collectors/legacy-al/fixtures/homes/home-03.html
- collectors/legacy-al/fixtures/homes/home-04.html
- collectors/legacy-al/fixtures/homes/home-05.html
- collectors/legacy-al/fixtures/homes/home-06.html
- collectors/legacy-al/fixtures/homes/home-07.html
- collectors/legacy-al/fixtures/homes/home-08.html
- collectors/legacy-al/package.json
- collectors/legacy-al/src/index.ts
- collectors/legacy-al/src/selftest.test.ts
- collectors/legacy-al/tsconfig.json
- collectors/lennar/package.json
- collectors/lennar/src/index.ts
- collectors/lennar/tsconfig.json
- collectors/lgi-homes/package.json
- collectors/lgi-homes/src/index.ts
- collectors/lgi-homes/tsconfig.json
- collectors/mattamy/package.json
- collectors/mattamy/src/index.ts
- collectors/mattamy/tsconfig.json
- collectors/meridian-homes/package.json
- collectors/meridian-homes/src/extract.test.ts
- collectors/meridian-homes/src/index.ts