Inspiration

I have a bucket list, and owning an EV is on that list. I came up with an idea: to get sponsored to drive an EV jetski, or a drone that can carry me about 8' off the ocean — that's plenty high enough for me — or even an EV speedboat. I thought if I started a project that would help the industry, I might get some eyes on me and a head start at getting a machine that will do that for me.

I created HarborGrid to explore where marine charging stations should be placed, and to show how a charging network could make electric travel on the water more practical.

What it does

HarborGrid is a planning demonstration for marine EV charging in the Salish Sea and Juan de Fuca Strait. A deterministic optimizer scores every combination of 6 synthetic candidate harbour sites against 8 weighted demand nodes and picks the best network for a given charger budget — reproducibly, with no AI in the decision loop. A budget slider (1–5 chargers) drives an interactive Leaflet map and a before/after dashboard: at a 10 nm usable-range assumption, 1 charger covers 40% of weighted demand; 3 chargers cover 92% and cut the longest charging gap from 36.4 to 12.7 nautical miles (+52 points, −23.7 nm).

Click a selected site and the verified, structured facts appear first — coverage gain, gap reduction, confidence, known limitations. Only then does GPT-5.6 speak: a server-side explanation service converts those exact facts into plain language under strict instructions to never select, rank, recommend, or invent. A source badge shows exactly what you're reading — "GPT-5.6" or "Deterministic Fallback" — and if no API key is configured, the app degrades gracefully to a deterministic template with the same numbers. Every screen carries the disclosure: demonstration dataset; deterministic optimization; feasibility requires partner validation.

How we built it

Built solo in two days (July 14–15) as a docs-first project: PROJECT.md defined scope and non-goals, DECISIONS.md recorded 11 dated architecture decisions before and during implementation, and STATUS.md tracked the sprint checklist. The stack is Next.js (App Router), React, TypeScript, CSS Modules, Leaflet + React Leaflet over OpenStreetMap tiles, and the official OpenAI JavaScript SDK calling the Responses API from a server-only service (model configurable via env var, default gpt-5.6-sol).

The core design rule came first: deterministic code makes every siting decision. The optimizer exhaustively scores site combinations (appropriate for 6 candidates) using straight-line Haversine nautical miles, and a precomputed budget × range scenario matrix (budgets 1–5 × 10/15/20/25 nm — 20 rows) powers the slider with zero AI calls and zero client-side solver runs. Between the optimizer and the model sits a Structured Facts layer: the API route accepts only a charger budget and site id, looks up deterministic facts server-side, and sends those facts — nothing else — to GPT-5.6. The route adds rate limiting, an in-memory cache keyed by a SHA-256 hash of the facts, and a 503 fallback path so the UI never breaks without a key.

Challenges we ran into

The honest-numbers problem: at a 45 nm usable-range assumption, coverage saturated at 100% for every budget — no story. The tempting fix was to juice the synthetic demand data until the demo looked dramatic. Instead, the decision log records the rule we chose: never alter synthetic inputs merely to produce impressive numbers. We built the budget × range scenario matrix and picked 10 nm because that's where the progression is real: 40% → 92% → 100%.

The other challenge was keeping the language model in its lane. The explanation service constrains GPT-5.6 with explicit instructions (never choose, rank, add, remove, or substitute a site; never change a number; refuse to repair inconsistent facts) and the UI is designed so the verified table renders before the narrative — the model can only ever be the second voice in the room.

Accomplishments that we're proud of

A working demonstration of an unfashionable idea: that AI belongs in the explanation layer, not the decision loop, when the subject is infrastructure. The optimizer's output is reproducible to the digit; the model's narrative is auditable against the fact table directly above it; and the app tells you honestly, on every screen, what it is (synthetic demonstration data) and what it is not (navigation, engineering, permitting, or investment advice). Also: this is the second solo entry shipped this week — planned, built, verified, and submitted alongside SeniorSidekick.

What we learned

What I learned is: don't guess, just do. I was guessing I was barely going to be able to get one idea through the gate with a team, and I managed two solo — and I'm wanting to do another.

I also learned that as I build, I can learn as I go: working in small steps, and reviewing before I move forward.

What's next for HarborGrid

The real dataset exists: a hand-mapped 584 NM Vancouver Island circumnavigation network — 36 real stations from Victoria Inner Harbour around Cape Scott and back, with per-leg distances and the two zero-infrastructure gap zones (Brooks Peninsula, Cape Scott) marked for mobile support-vessel charging. Next step is feeding those 36 real nodes into the HarborGrid optimizer in place of the 6 synthetic ones, at realistic vehicle ranges. Roadmap items already logged: water-aware coverage geometry and marine routing instead of straight-line proxies, and a scalable solver for larger candidate sets.

Built With

Share this project:

Updates