**Note** from Bead: Wildfire World Model · [canonical source](https://redfish.acequia.io/guerin/.agents/a617e16d-2257-40b7-8d30-9cfc5ff452e8/2026-06-20/notes/02-initial-plans-fuse-measure-forecast.md) · session 2026-06-20 · discussion: Talk: Wildfire World Model
**Bead:** `a617e16d` (wildfire-world-model) · 2026-06-20. Companion to `01-world-models-technical-approach.md`. Three staged plans, one per capability Stephen named. Each is **least-action** (reuse what exists), maps to the V/M/C blocks of the world model, and is tagged with the senior-architect plane it rides. Worked example throughout: **Sandy Fire (CA-VNC-SANDY)** — the most complete cross-sensor archive we have (heat-perimeter KMLs, AlertCalifornia PTZ telemetry, a built TOA raster).
## PLAN A — FUSE imagery (world-model block **V**; planes 0, 4) **Goal:** every observation — MISB aircraft FMV, AlertWildfire PTZ, news-heli video, citizen photo, IR/heat raster — landed as a **posed, time-stamped layer on one terrain grid and one UTC clock**, indexed in STAC. This is the encoder front-half: pixels → georegistered state. > **Updated 2026-06-21:** Plan A's front-end is the **detect→forage** pipeline now formalized in [`wildfire-forager` `5b518c35`](https://redfish.acequia.io/guerin/.agents/5b518c35-2ce7-474a-a5a8-ec83e2fd0e82/about.md) (the forager *pattern*: detection source → normalized **ignition record** → fan-out into foragers → catalog) and its first source-subscriber [`wildcad` `bd08d6d4`](https://redfish.acequia.io/guerin/.agents/bd08d6d4-76a2-438e-94a3-82314bd70065/about.md) (`subscribe-wildcad.mjs`). This adds **stage A0 (detect)** below and reframes A2 as *forager fan-out*, not bespoke wiring. The end-to-end picture is in [`03-overarching-plan.md`](https://redfish.acequia.io/guerin/.agents/a617e16d-2257-40b7-8d30-9cfc5ff452e8/2026-06-21/notes/03-overarching-plan.md). What exists (don't rebuild): - **Detect (ignition trigger):** `wildcad` `bd08d6d4` (`subscribe-wildcad.mjs` polls WildWeb/WildWeb-E dispatch → normalized ignition records) under the `wildfire-forager` `5b518c35` umbrella (the ignition-record contract + fan-out architecture; FIRMS/IRWIN/NIFC/WatchDuty as further sources). - **MISB-0601 aircraft:** `cataloging-incident` `97559992` (`catalog-incident.mjs` reads mission.json + KLV → catalog) and `taos-engine` `c66cbd1d` (projects FMV onto the DEM from per-frame pose). - **News-heli:** `adsb-for-heli-videos` `2986ff41` (recover camera-ship track from video UTC window) + `media-forager` `58c0a5e0` (yt-dlp → STAC). - **AlertWildfire/AlertCalifornia PTZ:** `firewatch-camera-grid` `65783732` (PTZ telemetry → pose sidecar; *design-only, not built*) + `wildfire-imagery-acquisition` `b3461c66` (`grab-alertwest.py`). - **Citizen / telemetry-less imagery:** `pose-ux-ui` `edb06426` + `image-pose-calibrator` `74c30681` + `georegister-image` `58091f55` + `set-time-space` `09fd1bf6` (manual/solved pose for photos with no telemetry). - **Substrate:** `catalog` `90f902e0` (STAC duck-typing) + the FMV pose-stream STAC extension. Stages: - **A0 — detect (ignition trigger).** Run `subscribe-wildcad.mjs` (`wildcad` `bd08d6d4`) against the dispatch centers covering the AOI; emit **normalized ignition records** `(id, name, type, lat, lon, acres, created, center, source)` per the `wildfire-forager` `5b518c35` contract. The record is a *trigger* — a bbox + UTC window — not an endpoint. Add further sources (FIRMS/IRWIN/NIFC) as conforming subscribers. *Output: a fresh ignition record on the bus.* (plane 0/4) - **A1 — common frame contract.** Define the *fused observation* schema: a STAC item with `(geometry on DEM, datetime UTC, pose, sensor-type, footprint, asset)`. Adopt the three-clock model (capture/harvest/retention) from `stac-camera-telemetry` `31f69717`. *Output: one schema all producers emit.* (plane 0) - **A2 — forager fan-out.** An ignition record fans out (per the `wildfire-forager` pattern) to the imagery/ADS-B/media foragers — `media-forager` `58c0a5e0`, `wildfire-imagery-acquisition` `b3461c66` (`grab-alertwest.py`), `adsb-for-heli-videos` `2986ff41` — each keyed on the record's bbox+window, each emitting A1 observation items into `/incidents/<id>/observations/`. Build the one missing producer (firewatch-camera-grid `65783732` PTZ→pose). *Output: per-incident multi-sensor observation set, posed.* (plane 4) - **A3 — citizen lane.** Stand up the dock path: citizen photo `PUT`s to a bead `uploads/`, pose-calibrator solves pose (campanile UV↔geopoint + DEM), item joins the set. This is the **first-three-hours moat** — fusing public imagery before any aircraft is up. (plane 4) - **A4 — encode to grid.** Resample/raster every observation onto the shared DEM grid at the cursor time → the **fused observation tensor** (the V output the model consumes). **Open Qs:** confidence/weight per sensor (feeds the soft-constraint assimilation)? PTZ calibration accuracy good enough, or does every PTZ need a one-time GCP solve? citizen-imagery trust/spam gate? who runs the `subscribe-wildcad` poller (a server bead, the orchestrator `4c6470f9`, or on-demand) and which dispatch centers?
## PLAN B — MEASURE wildfire behavior (block **V→state**; planes 0, 2, 3) **Goal:** turn the fused observations into **physical state variables** over time: active fire front / perimeter, **rate of spread (ROS) field**, **fireline intensity / flame length**, area & growth rate. These are both the *current state* the model assimilates and the *labels* it trains against. What exists: - **fire-progression** `182bd1a7` — `progression-maker.mjs`: time-stamped perimeters → **TOA raster** via scanline-rasterize + chamfer signed-distance + per-interval level-set blend, RGB-encoded minutes-from-origin. *This already computes observed spread.* Built for Sandy (`2026Sandy_v2`). - **Heat-perimeter KMLs** in `cbf8b027` (`artifacts/stac/2026SandyFire/perimeters/`, 6 perimeters 183→2,114 ac). - **fire-in-taos** `b6fcda63` — slope-biased CA + DEM gradient (the geometry/terrain plumbing). Stages: - **B1 — perimeter extraction from imagery.** Today perimeters arrive as vendor KMLs. Add detection: extract the active front from IR rasters and from AlertWildfire/citizen frames (threshold/segment in image space, project to DEM via the A-stage pose). *Output: perimeters on demand, not just vendor-supplied.* (plane 3) - **B2 — ROS field.** Difference successive perimeters along front normals (the level-set gradient fire-progression already computes) → per-cell observed ROS (m/min) and direction. *Output: ROS raster per interval.* (plane 0) - **B3 — intensity / flame length.** From IR radiance + Byram (I = H·w·ROS) → fireline-intensity and flame-length rasters. *Output: intensity channel.* (plane 0) - **B4 — behavior timeline.** Area(t), growth-rate(t), max-ROS(t) bound to the **master time-cursor** (`time-line-web-component` `ade9cea6`); scrub observed behavior in incident-viewer. (plane 2) **Open Qs:** IR radiance → intensity needs sensor calibration we may not have — proxy from flame-length in oblique imagery? front detection robustness in smoke? B1 = the biggest new build.
## PLAN C — FORECAST (block **M** + assimilation; planes 0, 3, 4) **Goal:** the world model proper — roll the fire state forward and emit forecast products (TOA, burn-probability, evac lead time), corrected by each new observation. Built in three tiers, each shippable. What exists: - **fire-in-taos** `b6fcda63` (forward CA on DEM) — the seed of the physics prior. - **fire-progression** `182bd1a7` — provides **observed TOA = ground truth** to validate against. - **agentscript-webgpu** `f4ef67b7` (GPU ABM step loop in taos-engine) — the compute substrate. - **wildfire-as-Phase-4-computation** `ab987654` (Finney framing) — conceptual. Tiers: - **C1 — physics baseline (deterministic).** Upgrade fire-in-taos from slope-biased probability to a **Rothermel ROS field + level-set front propagation** on the DEM, driven by gridded wind/fuel-model/moisture. Run as a GPU compute kernel via `f4ef67b7`. *Output: a deterministic spread forecast, rendered live in taos-engine.* This alone is a usable product. (plane 3) - **C2 — ensemble + data assimilation.** Run an **ensemble** (perturb wind/moisture/ignition — the ELMFIRE pattern), and **assimilate** each new observed perimeter (Plan B) via **EnKF / morphing-EnKF** to nudge the ensemble toward reality. *Output: probabilistic forecast (burn-probability map) + uncertainty, updated every observation.* This is the observe→update→predict loop = the actual world model. (plane 0, 4) - **C3 — learned residual (world-model proper).** Train a **learned dynamics correction** on the STAC archive of past fires (Sutton's experience corpus): a model that predicts the *residual* between physics-forecast and observed spread, in the TOA/representation space (JEPA-style, not pixel generation). Optionally a Dreamer-style latent RSSM for fast ensemble rollouts. *Output: a forecast that improves as the fire archive grows.* (plane 3) - **C0 — validation harness (build first, alongside C1).** Replay Sandy & Sorrento: forecast-from-perimeter-N vs observed-perimeter-N+1; score on TOA error / IoU of arrival. *Without this, no tier is trustworthy.* This is the gap the Explore survey flagged (no sim-vs-observed harness exists yet). **Open Qs:** wind source (HRRR? on-fire WRF-Fire coupling, or gridded forecast input only)? fuel-model raster source (LANDFIRE)? is C3 worth it before we have N≥10 archived fires? coupling depth — do we need fire→atmosphere feedback (WRF-Fire) or is one-way wind forcing enough for first-3-hours?
## Build order (recommendation) Least-action, value-first, aligned to senior-architect's "tighten plane 4 + plane 1 first": ``` 1. A1 + A2 fused observation schema + wire producers (gets multi-sensor onto one grid) 2. C0 + C1 validation harness + Rothermel/level-set (a real, scored forecast) 3. B1 + B2 perimeter-from-imagery + ROS field (close the observe side) 4. C2 ensemble + EnKF assimilation (the world-model loop) 5. A3 citizen lane via the dock (the first-3-hours moat) 6. C3 learned residual (improves with the archive) ``` Steps 1–2 give a demoable "fuse → forecast → score" thread on Sandy. Steps 4–5 turn it into the live, assimilating, citizen-fed world model that is the realtime.earth / Acequia differentiator. **Gated on Stephen:** which capability to drive first (A / B / C), and the open-Q decisions per plan (sensor weighting, wind/fuel sources, whether C3 waits for a larger archive).
## References (bead cross-links) - Bead: Wildfire Forager · [canonical](https://redfish.acequia.io/guerin/.agents/5b518c35-2ce7-474a-a5a8-ec83e2fd0e82/) - Bead: Wildcad · [canonical](https://redfish.acequia.io/guerin/.agents/bd08d6d4-76a2-438e-94a3-82314bd70065/)