← Back to all projects

Simulation · Supply Chain Risk

Supply Chain Hazard Risk Simulator

PythonFastAPINext.jsSimulationGeospatial

A supply chain disruption simulator built for a supply chain working group, with three rules that shape everything else. The simulation is deterministic and model-free: no language model touches the numeric path, and the same config with the same seed produces byte-identical output, which a determinism test pins with seeded run hashes. The AI briefing layer is grounded or silent: it receives structured simulation output and hazard records and nothing else, every claim it makes has to carry an evidence identifier, and if the data does not support a conclusion it has to say so. That is enforced as a schema requirement, not a prompt suggestion. And it uses federal and free data sources only, with every hazard record attributable by URL and retrieval timestamp. Two parts were genuinely hard. When orders exceed origin capacity, naive proportional rationing strands throughput because it ignores per-lane caps, so I wrote an iterative re-pooling loop that fills to the constraint and redistributes the remainder; in the bottleneck case it lifts units dispatched from 55 to 95, and the pathological case is pinned by tests. Matching hazards to shipping routes across thousands of kilometers breaks under naive planar buffering, so I chunk each corridor into segments, reproject each segment into an azimuthal-equidistant projection centered on it, and unwrap antimeridian crossings that would otherwise produce world-spanning polygons that match every asset on Earth. It is 3,259 lines across 20 Python modules with 64 test functions, a FastAPI service, and a Next.js operations console.

What it does

Deterministic, model-free simulation: the same config and seed produce byte-identical output, pinned by a determinism test with seeded run hashes

AI briefing layer is grounded or silent: every claim carries an evidence identifier, enforced as a schema requirement rather than a prompt

Federal and free data sources only, each hazard record attributable by URL and retrieval timestamp

Water-fill allocation: an iterative re-pooling loop that respects per-lane caps, lifting units dispatched from 55 to 95 in the bottleneck case

Geodesic corridor buffering: per-segment azimuthal-equidistant reprojection with antimeridian unwrapping to avoid world-spanning match polygons

3,259 lines across 20 Python modules, 64 test functions

Tech stack

SimulationDeterministic, seeded, model-free
BackendFastAPI
ConsoleNext.js operations console
GeospatialAzimuthal-equidistant reprojection, antimeridian unwrapping
AI LayerGrounded briefing with schema-enforced evidence
DataFederal and free sources, URL + timestamp attributed
Testing64 test functions, seeded determinism hashes
← Back to all projects