How the model works, and its limits
What is data and what is model. Three things come from public data: the chance a plant has an RMP release in a year, how release records split by where the release came from and what happened, and the share of OSHA 300A filings that fail a plausibility screen. Everything else is a model parameter that I chose: unit layout, nominal readings, noise, alarm limits, incident duration, and the simulated operator's response times. None of those parameters is a measurement of any plant.
Incident clock. Each seed draws two independent streams. The release stream is a Poisson process whose yearly probability is the chosen rate_pct (for example, a plant in the selected inventory band has that share of plant-years with a release). The yearly probability p is converted to an hourly hazard with lambda = -ln(1 - p) per year, so the chance of at least one release in a year equals p. Source unit type is drawn from the “where from” flag counts below; release type flags (gas, liquid, fire, explosion, runaway) are drawn independently with probability flag count / 2,611. The filing stream draws one Bernoulli per simulated year with the implausible-filing share, and raises an alert on the control building.
Alerts. A release applies a short model signature to its source unit (gas reading up, pressure or level down). An alert is raised when a model limit is first crossed. Normal noise is bounded and never reaches a limit; a test in the repository checks this. Because the drawn rates are low, many seeds show no release inside the horizon. That is the honest behaviour of the statistic, not a defect: use Next incident, another seed, or Inject test excursion.
Ontology pattern. Objects (Unit, Alert, Incident, WorkOrder, Filing), links between them, and action types with parameters and submission criteria follow the pattern in ehs-osha-analysis src/ehs_osha/ontology/spec.json. The filing action is that repository's “Flag filing as implausible”. Every action, applied or rejected, writes an audit entry with who, what and when (simulated time). The log exports as JSON and includes the seed, parameters, rates and ontology so a run can be reproduced. Independent design on public data; not affiliated with Palantir.
Rates used
| Inventory band | Plant-years | Releases | Rate per plant-year | Wilson interval | Exact interval |
|---|
Source: ehs-chemical-peers/docs/data/compare.json, groups rel-inv-*, fields n, events, rate_pct, wilson_pct, exact_pct. Implausible filings: , ehs-osha-analysis/outputs/tables/quality_overall.csv, column implausible_share.
Release source mapping
| RMP “where from” flag | Records | Schematic unit type |
|---|
Counts from release_anatomy_all.source in ehs-chemical-peers/outputs/summary.json. Flags are not exclusive, so the model normalises the mapped counts to weights (). That normalisation is a model choice. Columns, exchangers, the flare and the control building are never drawn as release sources because no source flag maps to them. Release type shares used: .
Action types
| Action | Parameters | Submission criteria |
|---|
Model signals (parameters, not data)
| Unit type | Signal | Nominal +/- noise | Limits |
|---|
Monte Carlo what-if: method and limits
The what-if panel runs N seeded replications (100, 500 or 1,000; the work is chunked so the page stays responsive). Each replication is one simulated plant-year. The chosen scenario supplies a committed share of plant-years with a release, rate_pct, from groups[...] in ehs-chemical-peers/docs/data/compare.json. That share is converted to a Poisson rate lambda = -ln(1 - p) per year, so the chance of at least one release in a year equals p. The panel shows the histogram of incident counts, the mean with its standard error, the share of replications with a release next to the source rate, and an empirical 90% interval (5th and 95th percentile of the count). The same seed, scenario and N always give the same output.
Scenarios are the four inventory bands plus the other release groups in the same file (employee size, release history, number of regulated chemicals, chemical family). Nothing else is selectable, because nothing else has a committed rate. Export insights writes a JSON report (seed, parameters, source citations, results) and a Markdown summary.
Limits. Poisson assumption: independent releases at a constant rate. No clustering, and no link between a plant's past and future releases, although the data shows groups with a release in the past five years have a higher rate. The source rate is a share of plant-years, so counts above one per year are a modelling extrapolation, not an observation. The site is synthetic, and the result describes a plant drawn from the chosen public group, not any real plant. No effect of controls is modelled or claimed. With small rates most replications are zero, so the empirical interval is coarse and can be narrower than the Wilson interval on the rate itself.
Limits. The simulation says nothing about the risk of a real plant or any real layout. A plant-level rate is applied to one synthetic site, so unit-level incident rates are not estimated. Release flags describe where a release came from, not why. Time runs for up to 100 simulated years so that low-rate events can appear, which also means the site does not age, change or learn. The 3D model, dimensions (in drawing units) and unit counts are illustrative. Fire, explosion and runaway flags are recorded and drawn only as part of the incident record. The insight panels cite the exact file and key for every figure and make no causal claim.
Files: work/plant-blueprint.html, work/plant-blueprint.js, work/plant-blueprint-sim.js, work/plant-blueprint-mc.js, scripts/build_plant_blueprint_data.py, tests/test_plant_blueprint.py, tests/plant_sim_check.js, tests/plant_mc_check.js. Sources have no docs/insights.md at origin/main, so none is cited.