I built a Foundry-native application that turns public Texas transportation data into an operational corridor pressure monitor.
For any selected week, it answers one question:
Which Texas freight corridors are behaving normally, running above normal, or showing below-normal/disrupted movement compared to their own historical baseline?
Stack: Pipeline Builder → Ontology → Workshop → AIP Generated Content Validation event: Winter Storm Uri, week of 2021-02-15 Object grain: one corridor during one week
The system is deliberately scoped as a corridor pressure anomaly monitor. It is not a diesel demand, truck-demand, or fuel-consumption model. The goal was to demonstrate a complete, inspectable Foundry implementation pattern end to end.
Why this problem
Freight corridors are operational systems. When movement across a major corridor deviates from its own normal pattern, that deviation can reflect weather disruption, logistics stress, demand shifts, or regional transportation change. For energy and midstream operators, corridor-level movement is external context around regional diesel demand. But public data doesn’t come packaged as an operational signal.
The gap this project addresses is narrow and concrete: public traffic data exists, freight corridor geometry exists, and nothing connects them into an inspectable, week-by-week operational view. That connection layer, running from data to objects to map to grounded summary, is what this build implements. The demand-signal question is deliberately deferred to future iterations (see the expansion path at the end).
Data
The build uses public Texas transportation datasets: TxDOT / MS2 traffic count data, TxDOT Permanent Count Station metadata, the Texas Highway Freight Network for corridor references and geometry, and WIM/classification station reference data reserved for future truck-specific weighting.
These feed a derived corridor-week pressure layer: one row = one corridor during one week.
Modeling the app on a corridor-week aggregate rather than raw station readings was a deliberate MVP decision. It let the first version focus on object grain, the Pipeline Builder serving layer, geospatial rendering, week-level replay, AIP grounding, and event validation. The station/classification data gives the project a clear expansion path, but the current application is intentionally served from a corridor-week operational layer.
Architecture
The build has two ontology-backed paths.
The first creates the detailed map object:
public traffic + corridor data
→ Pipeline Builder
→ fddi_corridor_weekly_map_layer_v2_pb
→ CorridorWeeklyPressureV2
→ Workshop geospatial map
The second creates the week-level summary object used for AIP grounding:
fddi_corridor_weekly_map_layer_v2_pb
→ Pipeline Builder weekly aggregation
→ fddi_week_summary_v2
→ FddiWeekSummaryV2
→ AIP Generated Content
The separation is intentional: CorridorWeeklyPressureV2 is the detailed corridor-week object used by the map; FddiWeekSummaryV2 is the selected-week network summary object used by AIP. Workshop performs no raw data logic.It consumes ontology objects, filters object sets, and renders the selected week.
Ontology model
The core object is CorridorWeeklyPressureV2. One object represents one Texas freight corridor during one week. For example, IH0035-KG during 2021-02-15 | Storm Uri.
The grain was the most important modeling decision. A corridor alone repeats across weeks. A week alone spans many corridors. The unique operational record is the pair, so the primary key is:
pressure_record_id = corridor_id + period_date
Key properties: corridor id and name, week label, period date, traffic volume, freight intensity (experimental, reserved for future truck-classified weighting), pressure z-score, pressure status, coverage flag, and corridor geometry (geoshape) plus raw WKT. The Pipeline Builder output backing this object has ~7.8k corridor-week rows across 12 ontology-ready columns.
Signal design
Raw traffic volume is not directly comparable across corridors: a major interstate and a smaller freight route operate at very different baseline levels. Each corridor-week is therefore scored against that corridor’s own historical baseline as a z-score, then classified:
z <= -2.0 disrupted
-2.0 < z <= -0.5 below_normal
-0.5 < z < 0.5 normal
0.5 <= z < 2.0 above_normal
z >= 2.0 hot
The methodology is intentionally simple and transparent. The goal of this version was not model complexity; it was an anomaly layer that can be inspected, validated, and served through Foundry.
Workshop app
The Workshop app renders a selected week as a geospatial corridor pressure map:
Object type: CorridorWeeklyPressureV2
Filter: Week Label = selected week
Geometry: Corridor Geometry
Color: Pressure Status
Colors run disrupted (dark purple) → below_normal (light purple) → normal (blue) → above_normal (yellow) → hot (red). Changing the selected week updates both the map and the AIP summary, giving the app week-level replay across the corridor network.
The contrast between this week and Storm Uri (Image 1) is the point: a calm week reads calm, a disrupted week reads disrupted,in both the map and the generated summary.
AIP integration
The AIP design principle: do not ask the LLM to reason from only a date string.
A weak AIP input would be 2021-02-15 | Storm Uri. Instead, the selected week resolves to an active FddiWeekSummaryV2 object carrying structured network metrics — corridor count, covered count, per-status counts, min/avg/max z-scores, and a materialized aip_prompt property built in the pipeline (visible as the “AI_prompt context” transform in Image 4).
The Workshop flow:
selected week
→ active FddiWeekSummaryV2 object
→ aip_prompt property
→ AIP Generated Content
→ grounded weekly corridor pressure summary
For Storm Uri, the summary object contains:
corridor_count: 14 disrupted: 9 below_normal: 5
normal: 0 above_normal: 0 hot: 0
min z: -3.86 avg z: -2.43 max z: -0.90
The generated summary correctly characterizes the week as a broad negative corridor pressure shock and carries the scope caveat into the generated output itself:
This is a public-data corridor pressure anomaly signal, not a direct diesel demand or truck-demand measurement.
Validation: the iteration that mattered
The first version of the classification only had normal / above_normal / hot. That worked for positive pressure, but it failed to represent negative movement shocks.
Winter Storm Uri exposed the gap. During the week of February 15, 2021, Texas corridor movement showed strongly negative z-scores. V1 could detect the anomaly numerically, but it could not classify the event because it lacked negative-status categories.
V1 could see the anomaly. It could not name it.
V2 added below_normal and disrupted, changing the system from a one-sided pressure monitor into a two-sided pressure and disruption monitor.
Storm Uri corridor results:
SH0006-KG z = -3.86 disrupted
SH0031-KG z = -3.48 disrupted
US0090-KG z = -3.38 disrupted
IH0035W-KG z = -3.20 disrupted
SH0130-KG z = -3.01 disrupted
US0084-KG z = -2.97 disrupted
US0082-KG z = -2.85 disrupted
US0287-KG z = -2.65 disrupted
IH0027-KG z = -2.47 disrupted
IH0020-KG z = -1.63 below_normal
US0059-KG z = -1.47 below_normal
IH0010-KG z = -1.21 below_normal
US0281-KG z = -0.94 below_normal
IH0035-KG z = -0.90 below_normal
I also validated the object grain directly: max rows per corridor-week = 1, duplicated corridor-weeks = 0. The object layer is modeled at the intended resolution.
Limitations
Technical: the app uses corridor-week aggregates, not raw station-level objects. Active station counts and station contribution lists are not yet exposed in the ontology. Coverage varies by week, so different weeks can show different corridor counts. The map is intentionally scoped to a selected-week object set;clearing the week filter would attempt to render the full corridor-week history, which is not the intended flow.
Methodological: the signal uses all-vehicle movement on freight-designated corridors, not truck-isolated movement. The baseline is each corridor’s full-period mean/std, not a seasonal baseline, and anomaly weeks are still included in it. Sensor-level weighting and double-counting controls are not yet exposed.
These limitations define the boundary between this proof of work and a production-grade signal. The architecture is set up so each can be addressed without changing the core design.
Next iteration
Planned additions for auditability and coverage: active_station_count, station_coverage_ratio, baseline_n / baseline_mean / baseline_std, and explicit no_data status for missing corridor-weeks. The AIP layer can also be extended to ground on the most severe corridor-level records for the selected week, not just the week summary.
Path toward a freight-specific signal
The reason WIM/classification station data is in the source set despite being unused: it is the path from corridor pressure to a freight-specific signal. Truck-classified counts would let the index isolate freight movement from passenger traffic, and a truck-isolated corridor pressure index is a materially closer proxy for regional freight activity, and eventually diesel consumption, than all-vehicle volume.
That claim is intentionally not made by the current version. Any demand relationship would need external validation against fuel-sales or freight benchmarks before it is asserted. The methodology sequence is:
station-level truck-classified observation
→ coverage-adjusted corridor freight index
→ weekly network summary
→ external benchmark validation
The current build is the serving-layer foundation that sequence deploys onto.
Final result
Pipeline Builder → V2 corridor-week map layer + weekly summary layer
Ontology Manager → CorridorWeeklyPressureV2 + FddiWeekSummaryV2
Workshop → geospatial pressure/disruption map with week replay
AIP → grounded weekly summary from the active summary object
Validation → Storm Uri tests negative disruption classification
Happy to go deeper on the pipeline, ontology grain, Workshop object-set wiring, AIP grounding, or validation checks.







