← gpu-pilot · json · source: CONTINUE.md

▶ CONTINUE (national roadmap)

The national roadmap — current status, data provenance, and the ordered next-pass plan. · updated 2026-06-12 21:37

TL;DR

  • NATIONAL roadmap. Phase 1: complete the NYC test (E4 kill crow-fly→graphs, journey reconstruction, publish res-10/res-9 NYC hex map with time+cost). Phase 2: whole-country hex maps from Golden Source GTFS — H3 res-10 in dense cities, res-9 in super-suburbs. Phase 3: top-100 metro commute tests + SEO/GEO savings pages.
  • Real cost engine DONE — fares/tolls/parking/CRZ/fuel all from the gtfs3 `commute` DB (authoritative, internal 172.26.1.152, trust-auth). Only the drive TIME is interim (OSRM free-flow ×peak; Valhalla NOT deployed, no traffic feed).
  • Validated: 30 tri-state commuter towns, rail cheaper 30/30, faster 26/30, avg $15.07 vs $58.80 → ~$1,924/mo saved (run_commute_towns.py).
  • DATA task: ingest CNT H+T Affordability Index (htaindex.cnt.org, 2022) — net-new `hta_index` table; download is cookie-gated (needs a browser session). Compare our door-to-door transport cost vs CNT's modeled transport % of income.
  • Phases gated: Phase 2 only after Phase 1 acceptance (5 OD pairs within ±2-3 min of OTP; VRAM <12 GB; Second-Brain 8030 untouched).

CONTINUE.md — gpu-pilot → National Commute-Cost Hex Maps

Date: 2026-06-11 · Type: Roadmap + session handoff (national plan) Host: geocoder (RTX 5080, 172.26.1.95) · Repo: github.com/tlcengine/gpu-pilot (private) Board docs: https://board.certihomes.com/project-docs/gpu-pilot/ Living report: https://videolens.certihomes.com/r/2026-06-10-raptor-design-review.html

New session: ssh krish@geocoder.tlcengine.com; cd gpu-pilot; source venv/bin/activate; claude. Read CLAUDE.mdraptor-design/SESSION_LOG.md (newest first) → this file.


2026-06-12 — Per-mode isochrones live on hexmap-api (Session 12)

POST /v1/isochrone now takes an optional modes: list[str] (+ objective: time|cost). No modes = the legacy walk+transit pass, byte-identical — both live sites verified unaffected. Modes: walk, bike, drive, transit (Train), uber, pnr (Park&Ride = drive→railhead→RAPTOR→walk), knr (Kiss&Ride = uber→railhead→RAPTOR→walk). >1 mode → per-hex BEST + winning mode:{h3:name} map + stats.mode_counts. Code: new hexmap-api/modes.py (cuGraph SSSP walk/bike with cutoff pruning, threaded OSRM /table drive/uber, synthetic access-CSR for P&R/K&R) + additive engine.isochrone_modes() + app.py branch. Per-mode disk cache uses a separate key so live-site caching is untouched. VRAM peak ≈ 4.3 GiB (both graphs resident). RAPIDS fix: libcugraph.load_library() runs before cudf so the lazy import cugraph works.

FE/adapter hand-off (next agent — how to call it): map the existing trip-type toggles → modes. Single toggle = modes:["<that>"]. "Show all" / compare = pass the full list and read mode per cell to colour by winning mode. Suggested ttyp→mode: Walk→walk, Bike→bike, Drive→drive, Train/Transit→ transit (or omit modes entirely for the legacy path), Uber/Rideshare→uber, Park&Ride→pnr, Kiss&Ride→knr. Pass objective:"cost" when the choropleth is in cost mode so the best-of is cheapest-generalized-cost rather than fastest. The geo2 multimodal adapter and the geo3 /map proxy were not changed this run — they keep calling the no-modes default; wiring the toggles is the FE pass.


Mission

Replace the CPU OpenTripPlanner polar-sampling precompute (10-day tri-state ETA, saturates OTP) with a GPU multi-source RAPTOR kernel on one RTX 5080, then build pre-calculated commute-cost Hex maps for the entire US (door-to-door time + real money, multimodal), and monetize via SEO/GEO "how much you save" pages for the top metros. Speed target met: full NYC res-9 (535K origins × 992 stops) in 73 ms vs a 10-day CPU baseline.

Status — what's DONE (Phases A–E)

Phase What State
A kernel correctness GPU RAPTOR bit-exact vs CPU reference (T1 synthetic, T2 1K real-feed)
B scale + perf res-9 535K in 73 ms; res-10 3.75M in 3.31 s (6-chunk); tiled parquet; depart-window loop ✅ core
C network walk legs cuGraph SSSP over OSM walk net replaces crow-fly — tri-state walk + Citi Bike matrices shipped 2026-06-12 (see E4) ✅ tri-state
D tri-state multi-feed Golden Source subway+LIRR+MNR+NJT(+PATH); cross-feed transfers; 1,491 platforms
E1/E2 real cost engine fares.py from the gtfs3 commute DB: zone fares, peak tolls, P&R parking, fuel
E3 rush-hour traffic OSRM free-flow × peak factor (interim — Valhalla NOT deployed, no traffic feed) ⚠️ interim
E5 commute-town matrix 30 tri-state towns, RAIL vs DRIVE, one kernel pass: rail cheaper 30/30, ~$1,924/mo

INTERACTIVE HEX MAP — ✅ LIVE 2026-06-12 (click→isochrone, real engines)

hexmap-api on geocoder :8098 (/home/krish/gpu-pilot/hexmap-api/, systemd hexmap-api.service enabled; own venv + .pth into the RAPIDS venv; imports raptor-design modules, no duplication — folded into the gpu-pilot repo, see its README): - POST /v1/isochrone {dest_h3|lat/lon, window, depart?, samples?} → one-dest RAPTOR pass (full+city nets resident) → {times:{h3:sec}, costs, chains} for the 15,530 covered res-9 cells. Key speedup: compact-origin CSR (16,621 covered origins, not the 535K grid) — bit-exact vs v1 parquet (verified 0/15,530 mismatches, Midtown+Bklyn AM), 0.6–0.9 s warm at 13 samples, VRAM peak 2,737 MiB total. Cache hexmap-api/cache/iso_*.json (~30 ms hit; 4 cores × 2 windows pre-warmed). One kernel at a time (asyncio lock, busy → 429 + Retry-After: 5). - GET /v1/cell/{h3} → v1 parquet rows + hex_hta CNT row (national) + pop/jobs (res-10 children sum). GET /v1/national/{cell/{h3},hta?bbox=} → CNT H+T anywhere in the US (Chicago slice ~70 ms). GET /healthz. - Engines stated honestly: kernel golden union + walk matrix v2 + commute-DB fares (heuristic_v1, no parent pointers yet); drive remains OSRM×peak — Valhalla slot intentionally empty (logged decision, no traffic feed).

Frontend commutingcost.com/map (geo3 commutingcost-hexmap, branch hexmap-interactive merged → main, pm2 restarted): click any hex → side panel (4-core times+fares AM/off-peak, CNT benchmark strip, pop/jobs) → "Set as destination" → GPU isochrone choropleth (green<30/yellow<60/ orange<90/red≥90 min) + AM/off-peak toggle; national CNT H+T res-9 layer (checkbox, zoom≥9, any metro); legacy origin-isochrone (geo3:8096) untouched. Browser → /map/api/gpu/* Next proxy → geocoder internal. Deploy gotcha: next build regenerates .next/standalone WITHOUT .next/static — always cp -r .next/static .next/standalone/.next/static before pm2 restart.

Phase-2 hook: national commute times = per-metro _Network registry (golden feeds + per-metro walk matrices via pyosmium+cuGraph recipe) — the engine isolates everything per network already; hex_hta layer is national TODAY.


PHASE 1 — Complete the NYC-region GPU test (CURRENT)

Goal: call NYC "done" = a published res-10/res-9 NYC hex map with door-to-door time + real cost per hex, every leg on a real graph, validated. Remaining work:

  1. E4 — kill all crow-fly → graphs: ✅ MATRICES SHIPPED 2026-06-12, integration remains. - DONE: tri-state (NY+NJ+CT) pedestrian graph 11.31M nodes / 12.36M edges → output/walk_matrix_res9_tristate.parquet (65,706 rows, 4,171 cells × 1,431 subway stops, GPU cuGraph SSSP 43 s, VRAM peak 2.99 GB). Cycling graph 9.18M/9.75M → output/bike_matrix_res9_citibike.parquet (858,232 rows, 2,404 Citi Bike docks). Validated: OSRM-foot 12/12 (+3.6% median), water physics floor 0 violations (no cross-Hudson walks), station self-cells PASS. Gotcha: pyrosm 0.8 crashes on the CT extract — walk-matrix/parse_ct_pyosmium.py is the bit-exact-parity replacement (25 s vs pyrosm's 904 s; use it for all future parses). - REMAINING (E4b): (a) commuter-rail anchors — rerun --stage matrix with the Phase-D gtfs-fixed-v3 union (LIRR/MNR/NJT rail ~50K stops, batch the SSSP); (b) 57 silent stops snap to 2-node OSM islands (station stairs) — restrict snapping to the giant component; (c) WIRE the matrices into the pipeline: multimodal.py egress, terminal→office fixed 6-min walk, cross-feed 250 m transfers — remove haversine from the hot path (drive = OSRM 172.26.1.151:5002); (d) optional res-10 dense-core grid.
  2. Rush-hour drive times (E3 finalize): calibrate the OSRM peak multiplier against the commute DB's hex_isochrone (1,593 drive-PEAK reachability polygons) — empirical, no Valhalla. (Cost side already real.) Decision logged: don't deploy Valhalla without a speed feed (it's free-flow like OSRM).
  3. Journey reconstruction: kernel emits arrival-time only; add parent pointers so each itinerary is explained leg-by-leg (board/alight/transfer) and fares are derived from the path, not inferred from endpoints.
  4. Produce the NYC hex map: res-10 in dense cores (Manhattan/inner boroughs/ Jersey City/Hoboken), res-9 elsewhere → parquet (h3, dest, time_sec, cost_usd, mode_chain) for AM-peak + off-peak windows.
  5. Acceptance (must pass before Phase 2): - 5 ground-truth OD pairs within ±2–3 min of OTP (NE oracle DOWN 2026-06-12: gtfs3 parked, gtfs4 has bad RAM — assets staged on geocoder, host TBD; see CLAUDE.md). Until it's back, table-band verdicts via otp_compare.py stand in. - 30-town matrix sane (✅ rail 30/30 cheaper); 08854→10001 in 67–78 band (✅). - VRAM < 12 GB at res-9; res-10 chunked. Second-Brain Parser's 2 GB on :8030 untouched.

Key files: raptor-design/{raptor_kernel.cu,raptor_pipeline.py,fares.py, multimodal.py,run_commute_towns.py,build_walk_matrix.py}, gtfs-arrow/scripts/ build_multifeed_arrow.py.


PHASE 2 — National rollout (whole country, adaptive Hex resolution)

Only after Phase 1 acceptance. Build pre-calculated hex maps for the entire US.

  1. Golden Source GTFS for every region — reuse validate_fix_gtfs.py (orphan- service-id extender) over all US feeds. Namespaced multi-feed union (build_multifeed_arrow.py) per metro/region. Feeds live on the Golden Source host; the orphan fix already generalizes (Phoenix/SLC/Denver/ABQ/Tucson noted).
  2. Adaptive H3 resolution (per the spec): - H3 res-10 in dense cities (high pop/job density — NYC, SF, Chicago, Boston, DC, Philly cores, etc.). - H3 res-9 in "super suburbs" / lower-density metro rings + exurban. - Drive the res choice from hex_demographics (pop/jobs) or a density threshold; store the chosen res per cell so downstream joins are unambiguous.
  3. Scale/VRAM: origin chunking already built (res-10 = 6 chunks for NYC). National = partition by metro/CBSA; one kernel run per metro's feed-set + hex set.
  4. Cost layers nationally: the commute DB already covers fares/tolls/parking/ fuel beyond NYC (566 transit agencies in transit_fares; national toll_rates, parking_rates, EIA energy_prices, EPA vehicle_fuel_economy). Expand zone maps as metros are added.
  5. Output: national hex parquet partitioned by state/CBSA → object storage; refreshed on feed/fare updates.

PHASE 3 — Top-100 metro commute tests + SEO/GEO pages

  1. Generalize run_commute_towns.py into a metro-driven runner: for each of the top 100 US metros (CBSA), define commuter towns → job-center terminal, RAIL (P&R/K&R/Uber) vs DRIVE, one multi-source kernel pass at AM peak, real cost from the commute DB. Emit a per-metro savings table (parquet + JSON).
  2. SEO pages (programmatic): one page per (origin town → metro center) — "Commute cost from {Town} to {City}: rail ${x}/mo vs drive ${y}/mo — save ${z}/mo" with the leg-by-leg breakdown, schema.org markup, internal linking.
  3. GEO pages (Generative Engine Optimization): structure the same data as clean, citable answer blocks (tables, explicit numbers, sources) so LLM answer engines surface "how much do I save taking the train from {town}?" Cite the commute DB + CNT H+T (below).
  4. Anchor on savings — the headline numbers (NYC: rail cheaper 30/30, ~$1,800–1,900/mo) are the hook per metro.

DATA TASK — CNT H+T Affordability Index (htaindex.cnt.org)

Why: validate our computed transportation cost against CNT's published H+T transportation % of income — credibility + a differentiator (we compute door-to-door multimodal door cost; CNT uses modeled averages). Feeds Phase-3 pages.

✅ STATUS 2026-06-12 — LOADED. hta_index in the commute DB: 359,924 rows, all 8 levels verified exact. NYC CBSA benchmark (note: CNT 2022 uses the OLD OMB name New York-Newark-Jersey City, NY-NJ-PA, not NY-NJ-CT): ht_ami 43% (h 30 + t 13), t_cost_ami $12,297/yr, transit_cost_ami $1,615/yr, pop 19.9M. Gotcha: in aggregate levels (state/us_house) cbsa_name is a comma-joined LIST; filter by level. The 15 KB All-U.S. cbsa_name was nulled (btree limit).

  • What we have (geocoder /home/krish/gpu-pilot/hta/): 2022 release, all 8 geography levels, 259 zips in raw/<level>/, every zip verified, headers uniform per level. Unique rows: blkgrp 239,178 · tract 84,094 · place 31,694 · county 3,144 (source ships every county twice — per-state files + a county_all.zip; byte-identical, deduped) · cbsa 927 · mpo 398 · us_house 437 · state 52 → 359,924 rows staged in hta_index.tsv.
  • How it was pulled (re-runnable for 2019/2016): headless Playwright in hta/pwenv — the "cookie wall" is just a user=<registered-email> cookie set by the landing-page login form (krishna@tlcengine.com is registered). harvest_links.pymanifest.json (259 links) → download_all.py (cookie + UA + content-type guard).
  • Gotchas: source GEOIDs come triple-quoted ("""011210113012""") — stripped in the TSV. CBSA files carry NO numeric CBSA code, only names ("New York-Newark-Jersey City, NY-NJ-CT") → join by name or go through county/tract/blkgrp FIPS. hex_demographics.metro_code is the literal string 'nyc' (1.31M rows), not a CBSA code.
  • Load plan (staged, not yet run): hta_index.sql = one table hta_index, PK (year, level, geoid), name + cbsa_name + 52 metric columns (ht/h/t % at ami/80ami/nmi, auto ownership + VMT + transit costs, transit trips/commute share, CO₂, density indices, housing costs). load_hta.sh runs DDL + \copy
  • analyze.
  • ✅ blkgrp↔H3 DONE 2026-06-12 (/home/krish/gpu-pilot/crosswalk/, board: crosswalk-CROSSWALK.html): tiger_blkgrp 35,559 BGs (CT/NJ/NY/PA, TIGER 2022) → blkgrp_h3_crosswalk 22M rows (res 9: 2.75M · res 10: 19.3M, centroid containment via h3_polygon_to_cells; installed h3_postgis 4.2.3) → view hex_hta = CNT H+T per hex (93.6% of cells carry a CNT row). Validation: hex_demographics (NOTE: it's res-10 ONLY) matched 100.00%; Times Sq cell → BG 360610119001 (ht 12%, 30% transit commuters); Piscataway → 340230006031 (ht 57%); household-weighted hex avg ht_ami 43.0 = CBSA row exactly. ✅ NATIONAL ROLLOUT DONE 2026-06-13 (~1h50m, zero failures): tiger_blkgrp 239,781 BGs / 51 states; crosswalk 403,236,574 rows = 92.3M res-9 national + 310.9M res-10 across 1,836 CBSA counties (45 GB table; commute DB now 48 GB on gtfs3's NVMe /data/postgres/main, 1.6 TB free). Alaska antimeridian split shipped (504/504 BGs, sql/05_ak_res9.sql). hex_hta national: Chicago/LA/Seattle spot checks pass, CNT join 97.45%. Per-state table in CROSSWALK.md §NATIONAL ROLLOUT. Comparison view ours-vs-CNT per hex = a join of E-phase outputs onto hex_htain any US metro.

OVERNIGHT RUN 2026-06-13 — ✅ ALL SHIPPED (see morning status)

Sites/repos LIVE on GitHub (private, populated): tlcengine/energysavings-site (a33e883, 761 pages + 10-min DEPLOY.md), tlcengine/tlc-index-site (88e75d9, 44 dollars-first pages), tlcengine/utilities-api (7fb17f4, FastAPI 25/25 tests). gpu-pilot pushed (ce61f9b + overnight commit). NYC hex map v1 + national crosswalk: see sections below. TLC index site: 🟢 LIVE 2026-06-12 at https://commutingcost.com/TLCcosts/ (Option A on geo3; vhost gotcha: no .bak files in sites-enabled — duplicate ipv6only listens fail nginx -t; backups → ~/nginx-backups/). Still open (Krish decisions): EnergySavings DNS go/no-go; OTP-NE rehoming (2026-06-12: lower-Xmx failed with evidence, gtfs3→gtfs4 migration ABORTED — memtester proved gtfs4 RAM bad; verified assets staged on geocoder /home/krish/otp-northeast — pick a host: geocoder 119Gi-free vs repair gtfs4 DIMMs); reso_etl ETL mapping for CJMLS Heating/Cooling fields (2.4%→~100% fuel coverage); GSMLS/NJMLS feeds for full-Jersey; Search Console sitemap submit for /TLCcosts/ (GSC access needed); B25040 county fuel priors via ~/.census_api_key (utilities agent ran pre-key); trademark search "True Lifestyle Cost Index".

SUB-PROJECT — Energy / utility rates (U-layer + EnergySavings) — ✅ LOADED 2026-06-12

Workspace /home/krish/gpu-pilot/energy/; docs on the board (energy-ENERGY.html, energy-SITE-SPEC.html). In commute DB: utility_providers 3,230 · utility_rates_annual 4,141 (EIA-861 2023+24, residential ¢/kWh per utility×state) · utility_service_territory 23,558 (CT name-only) · utility_tariffs 17 (URDB v0; full 166K bulk CSV on disk) · state_energy_choice 51 · views energy_cost_per_mmbtu + utility_savings_county (8,187). energy_prices += heating_oil_no2 21,846 + propane 28,759 (weekly, 1990→2026-03). NJ anchors: PSE&G 20.42¢ vs JCP&L 15.65¢ all-in; PSE&G PTC 10.938¢ (2026 BGS auction); gas $1.341/therm; $/MMBTU gas 13.41 vs oil 42.15. Krish decisions: EnergySavings.certihomes.com go/no-go (prototype energy/site/index.html, NOT deployed); zip↔utility source (EIA iou_zipcodes URLs dead → DOE/HIFLD or NREL key); phase-2 live supplier-offer scraping ToS; move weekly oil/propane refresh into geo's run_energy_prices_etl.py.

SUB-PROJECT — TLCcosts (H+U+C index, commutingcost.com) — ✅ v0 LIVE 2026-06-12

Workspace /home/krish/gpu-pilot/tlccosts/ (METHODOLOGY/BRAND/RESULTS on the board as flat tlccosts-*.html — board slug route 400s nested paths). Original index, CNT H+T® = benchmark-only w/ attribution. acs_housing LOADED in commute DB: 34,839 NY/NJ/CT rows, ACS 2020–2024 (vintage 2024; api.census.gov now REQUIRES a key → fetch uses keyless www2.census.gov summary files; optional CENSUS_API_KEY env activates API path). v0 (11 NYC counties, county level): H+U vs CNT h_ami r=0.95, TLC% vs ht_ami r=0.90; C (commute-only, door-to-door) runs ~7 pts under CNT t_ami (construct difference — ours is commute, theirs all-travel). Rail-vs-drive worth $1,635–2,429/mo. Open decisions for Krish in tlccosts/RESULTS.md: U source (DOE LEAD?), HUD AMI vs CBSA-median, naming/trademark, 48% threshold, commuters-per-HH weighting. (Census API key ✅ resolved 2026-06-12 — ~/.census_api_key on geocoder, auto-read by fetch_acs.py; never commit it.)


REFERENCES (all)

DBs - commute (AUTHORITATIVE Commute-Cost DB) — gtfs3, internal 172.26.1.152:5433, trust-auth from internal IPs (geocoder reaches it directly; external 71.172.x is firewalled — use the internal NAT). Tables: transit_zone_fares (zone_name names stations), toll_rates (peak/offpeak + CRZ $9), parking_rates (P&R by station), transit_transfer_rules, hex_isochrone (drive-peak + walk polygons), hex_transit_us, hex_demographics, transit_agencies/routes/stations, toll_facilities, energy_prices, vehicle_fuel_economy, pois. Exported slice → gtfs-arrow/fares/*.json for fares.py. - reso_etl on geo (socket /var/run/postgresql:5433) — older subset of the above. - Golden Source GTFS: gtfs3:/mnt/drive1/otp/northeast-2026-06/gtfs-fixed-v3/ (from gtfs3:~/validate_fix_gtfs.py); local copies gtfs-arrow/raw/feeds-golden/.

Routing / live services (geo2 internal 172.26.1.151) - OSRM drive :5002, OSRM-foot :5003, R5 :7080, OTP :8090. Valhalla NOT deployed. - OTP-NE CPU reference gtfs3:8091. Citi Bike GBFS (public) for micromobility gate.

Code (raptor-design/ unless noted) - Kernel: raptor_kernel.cu / .h (NVRTC + nvcc sm_120). Pipeline: raptor_pipeline.py. - Cost: fares.py. Multimodal legs: multimodal.py. Runners: run_commute_towns.py, run_multimodal_options.py, run_full_res9.py, run_res10_chunked.py. - Walk matrix: build_walk_matrix.py. Multi-feed ingest: gtfs-arrow/scripts/build_multifeed_arrow.py. - Publish: publish_report.py (videolens HTML), board_docs_publish.py (board MD→HTML+JSON). - H3 grids: output/nyc_tristate_h3_res9.parquet (535,471), …res10.parquet (3,748,291).

Run commands (venv active) - Town matrix: python raptor-design/run_commute_towns.py - Multimodal trip: python raptor-design/run_multimodal_options.py 7 - Full res-9 / res-10: python raptor-design/run_full_res9.py --window / run_res10_chunked.py - Multi-feed ingest: python gtfs-arrow/scripts/build_multifeed_arrow.py - Walk matrix: python raptor-design/build_walk_matrix.py - Republish: python raptor-design/publish_report.py + python raptor-design/board_docs_publish.py

Constraints / gotchas

  • DO NOT touch port 8030 (Second Brain Parser, ~2 GB VRAM) on geocoder.
  • nvcc at /usr/local/cuda-12.8/bin/nvcc (not on PATH), sm_120.
  • Internal NAT, not external: gtfs3=172.26.1.152, geo2=.151, geo=.45. External *.tlcengine.com for gtfs3/gtfs4 → 71.172.x is firewalled.
  • Git push routes via geo (geocoder's key isn't on GitHub): rsync -a .git/ geo:gpu-pilot/.git/ then ssh geo 'cd gpu-pilot && git push'. Sync the worktree on geo by rsync-ing files (NOT git reset --hard — it's on the deny list).
  • Service date 20260415 (Wed; all feed calendars overlap; 511 snapshot expired 2026-05-16).
  • Drive-time is the only estimate left in the cost stack; everything else is real DB data.

Security note (open)

The shared sudo password (geo:~/secret.txt, unchanged since 2026-03-28) was exposed in a transcript and is still unrotated — owner to rotate fleet-wide. SSH keys WERE rotated 2026-06-11. See geo:~/INCIDENT-react2shell-20260611.md.

Comments