Sunday, 15 November 2026

Building Intersection Intelligence: the slides and the story

By Mo Khan · Presentation edition · 28 slides

I had never built a mapping application before Intersection Intelligence. I started with a question about a place: what is here, and how do we know? That question became my personal mapping experiment and an internal research application, built with help from Codex and Claude. It is not being used commercially.

This talk follows the journey from South Africa to a single corridor: learning the geospatial stack, importing imperfect datasets, preserving human knowledge, tuning rendering performance and choosing an achievable research MVP. It includes the software architecture, technology stack and Linux deployment.

Open the full-screen presentation ↗

Use Next to reveal each build, or choose a slide from the menu. Show all reveals a whole slide; Notes opens the accompanying explanation. For detailed maps and diagrams, use Full screen. On a phone, opening the presentation in a new tab and rotating to landscape gives it more room.

Click inside the deck to use the keyboard: arrows or Space to advance, A to reveal, N for notes, F for fullscreen. The text version below remains available without the player.

The South African screenshots have company and provider names, commercial values and installation counts obscured. Infrastructure identifiers are omitted. Deterministic masks preserve the original map pixels, labels and geometry. The cover is a fictional intersection illustration generated with AI.

Map data © OpenStreetMap contributors; Protomaps cartography. Research use does not remove attribution or licence obligations.

The story behind the slides

Expand a title to read its explanation.

01 · Building Intersection Intelligence

I had no previous experience building mapping applications. Intersection Intelligence is my personal map-learning experiment and an internal research tool. It is not being used commercially. This talk explains the decisions, mistakes, performance cycles and accepted research MVP. Codex helped implement and verify the work. Claude challenged architecture and reviewed recorded increments. I remained responsible for intent and acceptance. The fictional cover illustration was generated with AI. Revised 14 November 2026.

02 · A question about a place

The starting point was a gap between aggregate knowledge and specific places. A spreadsheet could tell me how many assets were reported in a region. I wanted to select an intersection and understand the evidence behind it. That includes who has responsibility, what equipment is recorded and what remains unknown. I am deliberately using generic terms here because the engineering story does not depend on publishing our commercial information. The aim was to connect geographic context with attributable knowledge. This is the product question that drove the rest of the architecture.

03 · Start with South Africa

Start at country scale in South Africa. This is a screenshot of the signed-in research app captured on 14 November 2026. Company and provider names, commercial values and installation counts are redacted. Map data © OpenStreetMap contributors, https://www.openstreetmap.org/copyright; Protomaps cartography. Published administrative boundaries are reference geography, not cadastral boundaries. The map is a learning and research environment with uneven source coverage. It is not a commercial service. Sensitive UI is covered with deterministic pixel masks. The original map pixels, labels and geometry are unchanged.

04 · The journey in the repository

The design existed before the late-August implementation. The first standalone slice landed on 30 August with deterministic fixtures. Real Gauteng data followed immediately, and MapLibre with PMTiles arrived by 1 September. September then expanded into team contributions, source integration, identity preservation and analytics. Performance work became central later that month. Signal AI reached its first native production increment at the end of September. October and early November added country coverage and hardened deployment boundaries. These are milestones reconstructed from git and release records. They are not an assertion that every broader product ambition was complete at each milestone.

05 · Zoom into Gauteng

The same map moves into Gauteng, where the first real-data slice taught me what the prototype had hidden. Early rendering repairs bounded visible objects, reused coordinates and improved initial paint. By 1 September we moved to MapLibre GL JS with PMTiles. The screenshot shows the later research app, not the original prototype. Sensitive UI is redacted. Map data © OpenStreetMap contributors; Protomaps. https://www.openstreetmap.org/copyright Sensitive UI is covered with deterministic pixel masks. The original map pixels, labels and geometry are unchanged.

06 · Find the city-scale question

The app focuses on Johannesburg and a useful cluster of mapped junctions. The selected city, shortlist and rendered evidence need consistent scope. A fast pan is insufficient if the displayed answer belongs to an earlier viewport. Sensitive UI is redacted. Map data © OpenStreetMap contributors; Protomaps. https://www.openstreetmap.org/copyright Sensitive UI is covered with deterministic pixel masks. The original map pixels, labels and geometry are unchanged.

07 · Follow a corridor

A corridor turns isolated points into a connected geographical question. This view shows a published Johannesburg route, not traffic simulation or a prediction of flow improvement. The screenshot is from the research app on 14 November 2026. Sensitive UI is redacted. Map data © OpenStreetMap contributors; Protomaps. https://www.openstreetmap.org/copyright Sensitive UI is covered with deterministic pixel masks. The original map pixels, labels and geometry are unchanged.

08 · One place, several kinds of evidence

OSM can describe multiple signal nodes and roads. An authority register can report an equipment asset. A colleague can contribute an observation. A regional summary can count assets without giving coordinates. These are different grains. Summing them can double count or create a population that means nothing. We preserved their identities and provenance, then resolved the view appropriate to the user's question. Aggregate counts never became fabricated point locations. Unknown, absent, unavailable and zero remained distinct.

09 · Every source needed a way in

Every provider or authority had different workbook layouts, street conventions, identifiers and completeness. We built custom importers, preserved original values and source identity, then shared only stable matching mechanics. Fuzzy road-name and road-pair matching plus geographic evidence produced candidates. The documented browser workflow used the app and Google Maps to review confusing locations. That did not confer copying rights, establish ownership or turn an agent-assisted result into a human confirmation. Ambiguous and unpositioned rows remained in the inventory. Several assets could share a physical marker. Import validation checked dossiers and exports as well as parsed rows.

10 · Refreshes had to preserve human knowledge

Once people contribute, stable identity becomes a product requirement. Source geography can change, and grouping can split or merge candidates. Rebuilding the map must preserve the human evidence already attached to it. We retained source identities, tracked aliases and surfaced unresolved reconciliation rather than silently reminting records. A specific September correction preserved deleted heads as well as active API rows. That detail shows why checking only the visible current records was insufficient. The diagram is an illustrative identity model, not an actual production record.

11 · Codex and Claude worked through evidence

Codex was the implementation owner in the documented collaboration loop. Claude acted as a peer architect and read-only independent reviewer, inspecting the same repository. I supplied product intent and resolved decisions the evidence could not make for us. The curated ledger recorded questions, findings, corrections and decisions. It was an engineering notebook rather than a message transport. This arrangement reduced the amount of manual copying between assistants. It did not mean that every commit had independent review. Separate workstreams sometimes had different ownership.

12 · Independent review changed the work

These are examples of what the review loop was for. Early MVP reconciliation retired stale assumptions about Leaflet, hosted extraction and the deployment model. Later Signal AI review caught places where shared infrastructure assumed a financial business unit. We also kept responsibility for execution clear: Claude's source review was not a claim that it had run the tests. Codex had to produce that evidence. I had to manage the process too. During the long September AI refactor I pushed for delivery, separated unrelated work and ultimately requested solo continuation. The records preserve that boundary. They do not claim Claude approval for later solo work.

13 · Software architecture

The native JavaScript atlas uses MapLibre and PMTiles. The shared chat client brings its React conversation surface into the map host. The standalone Fastify API owns product semantics and authorised access. Prepared files support map and dossier reads; verified read-only SQLite workers serve analytics. Human evidence uses a separate mutable repository. Signal AI shares execution and operations while Intersection owns its tools and geographic context. The existing platform remains the entitlement authority. Everything is in the monorepo, but the deployment package is isolated. A root-checkout import is not proof that the deployed service starts.

14 · The technology stack

The browser uses a native JavaScript atlas with MapLibre, PMTiles and Protomaps, plus the shared React chat client. Node 24 and Fastify serve product-specific geography and evidence contracts. Python handles heavy geospatial preparation and custom source adapters off-host. Versioned files and read-only SQLite serve prepared evidence. Blob events and conditional heads preserve human contributions. Entra ID, the shared AI platform and GitHub CI supply integrations. This stack diagram describes concrete technologies; the preceding architecture shows responsibility and request flow.

15 · Building and serving are different workloads

The early real-data preparation exceeded the small serving host's memory envelope. We responded by separating the workloads. Operator-triggered Python processing acquires pinned sources, builds geography and validates the resulting release. The application serves prepared artifacts and accepts bounded edits. Application CI packages code; it does not run national extraction. This also makes rollback more understandable because a release has an explicit application identity and an explicit data identity. The benefits are architectural, not a claim of a specific infrastructure saving.

16 · Deployment architecture

This is a generalised view of the documented early-November deployment. App Service sits behind Entra authentication. The browser obtains short-lived read-only access to the geographic basemap account. Restricted source evidence and ownership overlays follow authenticated application paths. Restricted evidence storage restricts network access to the application's integration subnet via a Storage service endpoint. This is a restricted public endpoint design, not Private Link. Prepared application data remain on persistent storage and verified local analytical copies. The map application calls existing entitlement and AI services. Resource names, endpoints, network ranges and credentials are omitted.

17 · A small Linux host shaped the design

The recorded host is one Azure App Service Linux B2 instance, with the built-in Node.js 24 LTS runtime and Always On. Microsoft lists B2 as two cores, 3.5 GB RAM and 10 GB plan storage. Plan storage differs from the temporary local filesystem whose actual free capacity was measured for SQLite copies. Heavy extraction runs away from this worker. Local query copies are recoverable caches backed by verified persistent releases. These specifications do not establish sustained concurrent-user capacity. No resource names, endpoints, prices or private identifiers are shown.

18 · A map release must preserve contribution history

The immutable release holds prepared geographic facts and read models. Mutable human intelligence holds events, current heads and reviews. The write path first creates an event and conditionally advances a head. A stale version receives a conflict. The accepted history follows committed ancestry, so a failed competing event is not automatically an accepted edit. Releases and rollbacks must preserve that history. The same principle applies to map refreshes: current visible rows alone do not prove preservation of every committed head. Explain why this matters to the user: knowledge gained from a site visit should survive a technical improvement to the map.

19 · Rendering improved through repeated cycles

The early prototype needed bounded visible objects, clustering and coordinate reuse. The September traces distinguished acquisition, preparation, transfer and browser source updates from GPU paint. Changing UI heights had resized the map and produced old-bounds queries followed by repeat requests. Reserving layout space and synchronising final dimensions fixed that path. Skipping unchanged resize calls avoided renderer work. Short-lived viewport caches then reused complete contexts, with invalidation for access changes and edits. These were separate increments, not one renderer rewrite.

20 · Measure the visible result, keep the caveats

Thirty primed desktop filter changes produced 30 cache hits with zero new requests and zero aborts. Visible counts and source inputs matched. Coarse application completion was 90.5 ms median and 116.5 ms p95; this was not GPU paint latency. In the September 19 hosted comparison, n=30 per arm, Cape Town street viewport median improved from 771 to 529 ms, while overview median worsened from 1596 to 1687 ms. Sequential host and I/O variation prevents attributing every change to the code. The scope is a dated navigation experiment, not a universal responsiveness or multi-user capacity claim.

21 · A measured improvement in repeated queries

This is one dated production experiment, not a current whole-product benchmark. On 22 September we compared isolated execution with a resident SQLite worker. The median of the three repeated provider-count requests fell from 855 milliseconds to 276 milliseconds. The first request was essentially unchanged. Other shapes improved by much less, and some remained multi-second operations. All timed comparisons used verified local SQLite. The run checked result/evidence hashes and CSV parity. This small sample did not establish sustained capacity, twenty-user support or an application-wide speedup.

22 · Performance meant doing less repeated work

The recurring issue was avoidable work. Reopening connections, preparing national evidence for a local query and repeatedly acquiring unchanged data all mattered. We introduced bounded reuse and resident workers, and moved scope selection earlier where it preserved semantics. But early filtering is not correct if it changes what the user asked to count. A page is not a total, and a cache needs an invalidation boundary. We measured the path from user action through acquisition and preparation to SQL and rendering. A faster inner function cannot establish a faster or more capable whole application.

23 · AI in the product uses authorised evidence

Separate development AI from product AI. The product's shared chat interface receives the selected map context. Product-owned read tools retrieve bounded facts through the application boundary. Deterministic code supplies counts and comparisons. The model explains those facts, including gaps and partial results. Saved turns retain their original map context, so panning later does not redefine an earlier 'here'. A nonfinancial application has its own scope rather than a fabricated business unit. Reusing the engine also meant reusing the conversation UX and central operations.

24 · The first usable release required an owner decision

The late-September AI task illustrates the limits of an autonomous engineering process. There was substantial implementation and review effort, but the live feature was still pending. I had to bring the work back to the next useful increment, preserve the existing application's behaviour and separate optional improvements. The first native AI release reached production at the end of September under a bounded owner-approved launch policy. It kept authentication and data-integrity gates while retaining quality and capacity work as explicit follow-up. This is not advice to weaken safeguards. It is a reminder that product priorities require an accountable human decision.

25 · The accepted research slice

As of this source snapshot, the recorded product has a working atlas, dossiers, source-aware analytics, contributions and contextual AI over a nine-country catalogue. Coverage depth varies. The product ledger still tracks performance and concurrency acceptance, richer topology and source coverage, and the validation required for future opportunity models. After storage separation, data and ownership-publication maintenance are gated pending a reviewed procedure. Application and UI releases continue to be supported. The app is a discovery-and-capture alpha, not a live traffic-control system or a proof of traffic benefit. Evidence date: source master retrieved on 9 November, latest commit 7 November. Current state comes from capability and product ledgers, not old roadmap summaries.

26 · Original vision, accepted MVP

The original vision was a rich digital representation of intersections and the surrounding road network, with responsibility, equipment and planning context. The accepted research MVP was discovery and capture: navigate from a country to a junction or corridor, inspect source-aware evidence, preserve reviewed corrections and ask bounded contextual questions. Complete national coverage and a universal current twin were never established. Live control, calibrated traffic benefits and sustained multi-user capacity remain outside acceptance. The distinction matters because a persuasive map can make an unfinished model look authoritative.

27 · What I would repeat

These are the practices I would carry into another unfamiliar stack. Start with a concrete problem and move to representative real data early. Define the meaning of records, totals and missing values before the interface makes them look authoritative. Give independent reviewers bounded questions and ask what evidence would falsify the proposed design. Keep the implementation owner responsible for the tests. Finally, distinguish code completion, deployment and acceptance by a user. The AI agents made implementation accessible and productive, but they still needed the product context and constraints I brought. This is a personal reflection grounded in the development records, not a measured productivity comparison.

28 · Learning a new stack with AI

Return to the original ambition. I wanted a rich picture of a place and its surrounding network. I accepted a smaller research MVP: navigate, inspect evidence, preserve a reviewed correction and ask a bounded question in context. Complete coverage, rich topology, calibrated benefits and sustained capacity remain open. This is my personal learning experiment and internal research tool, not used commercially. Codex and Claude helped me learn the stack while I owned scope and acceptance. OSM licensing still applies to research use.

Further reading

My earlier post, Two AIs, One Branch, No Human Clipboard, explains the collaboration pattern. For the mapping building blocks, see the MapLibre GL JS documentation and the PMTiles guide.

No comments:

Post a Comment