▶ CONTINUE (national roadmap)
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. ReadCLAUDE.md→raptor-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:
- 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.pyis 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 matrixwith 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.pyegress, terminal→office fixed 6-min walk, cross-feed 250 m transfers — removehaversinefrom the hot path (drive = OSRM172.26.1.151:5002); (d) optional res-10 dense-core grid. - Rush-hour drive times (E3 finalize): calibrate the OSRM peak multiplier
against the
commuteDB'shex_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). - 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.
- 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. - 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.pystand 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.
- 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). - 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. - 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.
- Cost layers nationally: the
commuteDB already covers fares/tolls/parking/ fuel beyond NYC (566 transit agencies intransit_fares; nationaltoll_rates,parking_rates, EIAenergy_prices, EPAvehicle_fuel_economy). Expand zone maps as metros are added. - 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
- Generalize
run_commute_towns.pyinto 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 thecommuteDB. Emit a per-metro savings table (parquet + JSON). - 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.
- 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
commuteDB + CNT H+T (below). - 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 inraw/<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 + acounty_all.zip; byte-identical, deduped) · cbsa 927 · mpo 398 · us_house 437 · state 52 → 359,924 rows staged inhta_index.tsv. - How it was pulled (re-runnable for 2019/2016): headless Playwright in
hta/pwenv— the "cookie wall" is just auser=<registered-email>cookie set by the landing-page login form (krishna@tlcengine.comis registered).harvest_links.py→manifest.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_codeis the literal string'nyc'(1.31M rows), not a CBSA code. - Load plan (staged, not yet run):
hta_index.sql= one tablehta_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.shruns DDL +\copy - analyze.
- ✅ blkgrp↔H3 DONE 2026-06-12 (
/home/krish/gpu-pilot/crosswalk/, board:crosswalk-CROSSWALK.html):tiger_blkgrp35,559 BGs (CT/NJ/NY/PA, TIGER 2022) →blkgrp_h3_crosswalk22M rows (res 9: 2.75M · res 10: 19.3M, centroid containment via h3_polygon_to_cells; installedh3_postgis4.2.3) → viewhex_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_blkgrp239,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_htanational: 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 ontohex_hta— in 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.comfor gtfs3/gtfs4 →71.172.xis firewalled. - Git push routes via geo (geocoder's key isn't on GitHub):
rsync -a .git/ geo:gpu-pilot/.git/thenssh geo 'cd gpu-pilot && git push'. Sync the worktree on geo byrsync-ing files (NOTgit 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.