Skip to content
0xElCapitanPublic

About

BREATH — An air quality intelligence construct for the Echelon prediction market framework that ingests real-time air quality data from PurpleAir's 30,000+ sensor network and EPA AirNow federal monitoring stations, runs prediction markets on AQI outcomes across configurable time windows, and exports Brier-scored RLMF training certificates.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

BREATH

An air quality intelligence construct for the Echelon prediction market framework, built on constructs by Soju. Ridden by Loa.

What it does

BREATH ingests real-time air quality data from PurpleAir's 30,000+ sensor network and EPA AirNow federal monitoring stations, runs prediction markets on AQI outcomes across configurable time windows, and exports Brier-scored RLMF training certificates. It is the third construct in the TREMOR → CORONA lineage, adapting the proven seismic prediction market architecture to the air quality domain.


Why air quality

  • Ground truth oracle — BREATH uses AirNow current observations as its settlement authority for low-latency market resolution (category_number >= threshold_category_number closes the market). AirNow observations are preliminary — final regulatory data lives in AQS/AirData and may differ. Normal-condition drift between AirNow and AQS is likely modest but has not been directly quantified. This is an explicit product trust-policy choice: fast settlement over regulatory finality.
  • Binary structure — EPA AQI category breakpoints (51, 101, 151, 201, 301) create natural threshold gates. Every question has a crisp YES/NO resolution.
  • Fast cycles — AQI updates hourly. Theatres resolve in 4–72 hours. High-frequency RLMF data generation.
  • Exogenous — Predictions do not affect air quality. No reflexivity. Clean RLMF signal.
  • Dense network — 30,000+ PurpleAir sensors enable sensor-to-sensor corroboration. Localized phenomena (divergence, dropout) are detectable before EPA stations report.

Quick start

import { BreathConstruct } from './src/index.js';

const bc = new BreathConstruct({
  apiKeys: {
    purpleair: process.env.PURPLEAIR_API_KEY,
    airnow:    process.env.AIRNOW_API_KEY,
  },
  purpleair: {
    bboxes: [{ nwlng: -123.0, nwlat: 38.0, selng: -122.0, selat: 37.5, label: 'sf-bay' }],
  },
  airNow: {
    regions: [{ lat: 37.77, lon: -122.41, radius_miles: 25, label: 'sf-bay' }],
  },
});

// Open a prediction market
bc.openAqiThresholdGate({
  region_name:   'San Francisco Bay',
  region_bbox:   [-123.0, 37.5, -122.0, 38.0],
  aqi_threshold: 151,    // Will AQI reach Unhealthy (>=151)?
  window_hours:  24,
});

bc.start();                        // Begin polling (PurpleAir every 2m, AirNow every 60m)
const state = bc.getState();       // { construct, running, stats, theatres }
const certs = bc.getCertificates(); // RLMF training certificates
bc.stop();

Architecture

src/
  index.js              BreathConstruct, SensorRegistry
  processor/
    aqi.js              NowCast, breakpoints, AQI categories
    quality.js          Channel consistency, freshness, density scoring
    uncertainty.js      Doubt pricing, threshold crossing probability
    settlement.js       Evidence class: provisional -> ground_truth
    bundles.js          EvidenceBundle assembly
  oracles/
    purpleair.js        PurpleAir API v1 (120s cadence)
    epa-airnow.js       EPA AirNow API (60m cadence)
  theatres/
    aqi-gate.js         T1: AQI Threshold Gate
    sensor-divergence.js T2: Sensor Divergence
    wildfire-cascade.js  T3: Wildfire Cascade
  rlmf/
    certificates.js     Brier scoring, certificate export
spec/
  construct.json        Constructs Network spec

Settlement architecture

BREATH uses a two-tier oracle model:

Tier Source Cadence Role
Signal layer PurpleAir 120s Early warning — updates Theatre position probability
Settlement authority EPA AirNow 60m Ground truth — resolves Theatre YES/NO

PurpleAir bundles never resolve a Theatre directly; they blend position toward thresholdCrossingProbability. EPA AirNow bundles resolve immediately based on category_number >= threshold_category_number.

AirNow bundles are always processed before PurpleAir bundles in each poll cycle to ensure settlement signals resolve markets before signal-layer updates can affect post-resolution positions.


Theatre templates

Template Type Question format Window Resolution
aqi_threshold_gate Binary Will AQI reach category X in region R? 4–72h EPA AirNow confirmation or expiry
sensor_divergence Binary Will sensors A and B diverge by >N AQI for K consecutive readings? 4–24h Self-resolving (consecutive counter) or expiry
wildfire_cascade Multi-class (5 buckets) What fraction of sensors will exceed AQI 151? Up to 72h resolveWildfireCascade at window close

Wildfire cascade buckets: 0–10% | 10–30% | 30–50% | 50–70% | 70%+


Calibration edge cases

EPA AirNow hourly delay — AirNow publishes observations on the hour, not in real-time. A theatre that should resolve at 14:00 may not see the confirming bundle until 14:05–14:15. closes_at should account for this lag; using window_hours >= 1 is always safe.

PurpleAir A/B divergence — PurpleAir sensors have two independent measurement channels. When |pm25_a - pm25_b| / avg > 0.7, the bundle is classified channel_inconsistent and does not update Theatre position. This prevents degraded sensors from corrupting market prices.

Sensor dropout — Sensors absent from the PurpleAir API response for > 2× poll cadence are flagged dropout in SensorRegistry. Dropout bundles have evidence_class: 'sensor_dropout' and are not forwarded to Theatres.

AQI breakpoint discontinuities — EPA breakpoint tables have a gap at category boundaries (e.g., PM2.5 12.0 = AQI 50, PM2.5 12.1 = AQI 51). BREATH uses <= on Chigh per the official formula. A PM2.5 of exactly 12.0 maps to AQI 50 (Good), not 51 (Moderate). Values are truncated, not rounded, per EPA specification.

Wildfire smoke transport lag — Local and regional fires (under ~200 km) can reach downwind sensors in roughly 2–12 hours. Long-range transport events can take 12–72+ hours depending on atmospheric conditions. T3 window_hours should reflect the event type: 72h is reasonable for short long-range or snapshot-style events; regional fire sieges may need 72–168h. The low-exceedance prior [0.40, 0.25, 0.15, 0.12, 0.08] reflects the observation that low-exceedance outcomes are more common; bucket probabilities converge as sensors report.


Settlement trust policy

AirNow current observations are used as settlement authority for fast-cycle markets. These are preliminary values — AQS is the final regulatory system of record and may publish revised data. BREATH intentionally uses AirNow for low-latency settlement because market resolution speed matters more than regulatory finality for RLMF training. Normal-condition drift between AirNow preliminary and AQS final is likely modest, but has not been directly quantified in this construct. If your use case requires final regulatory truth, implement a deferred reconciliation path against AQS/AirData.


Calibration status

Many threshold values and scoring weights in the processor pipeline are engineering estimates awaiting empirical calibration. These are marked with // TBD: empirical calibration needed in the source code. See the audit report for the full list.


Dependencies

Zero. Node.js 20+ only.


License

AGPL-3.0

About

BREATH — An air quality intelligence construct for the Echelon prediction market framework that ingests real-time air quality data from PurpleAir's 30,000+ sensor network and EPA AirNow federal monitoring stations, runs prediction markets on AQI outcomes across configurable time windows, and exports Brier-scored RLMF training certificates.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages