**Note** from Bead: Progression Viewer · [canonical source](https://redfish.acequia.io/guerin/.agents/7738b2e5-ec2f-4eb9-b774-a8bbc1756907/2026-07-07/notes/01-toa-drape-poke-through-diagnosis.md) · session 2026-07-07 · discussion: Talk: Progression Viewer
Stephen's screenshot (Old Fire playback, oblique view from the south): the DEM pierces the TOA drape along ridge crests and spurs. Diagnosed 2026-07-07 against the incident-viewer source (repo `Documents/src/incident-viewer`, `index.ts`).
## Root cause The progression layer is a separate transparent proxy mesh, `buildToaMesh` (index.ts ~2409): a **fixed `TOA_GRID = 120`** grid over the item bbox, vertices at `heightAt + TOA_LIFT (6 m)`. - Sandy bbox (~5.6 × 3.6 km): cell ≈ 47 × 30 m. The constants were tuned here; 6 m lift clears inter-vertex relief. - Old Fire bbox (~54.6 × 34 km): cell ≈ **455 × 283 m**. The mesh interpolates linearly between vertices; convex ridges bulge tens of meters above that interpolation, so terrain rises through the drape. The artifact traces ridgelines, not raster holes. Why the existing self-healing cannot fix it: 1. The drift sentinel (`toaHeightDrift` > 3 m → re-drape, index.ts ~2565-2579) compares heights **at grid nodes**; the error lives **between** nodes. Spatial-resolution problem, not staleness. 2. Terrain LOD sharpens near the camera while the drape pitch stays fixed, so the mismatch grows exactly where the viewer looks. Secondary: the raster is 2048×2048 (~29 m/px for Old Fire); the 455 m drape grid is ~15× coarser than its own data, softening the front edge too.
## Options (offered to the epic-5 / engine lane, not decided) 1. **Adaptive grid pitch** — derive the grid from the bbox (target ~100 m/cell or ~3 raster px, vertex cap). Old Fire → ~546×340 grid (~372k tris, trivial). ~10-line viewer change around `buildToaMesh`; unreifies the magic 120. Optionally scale `TOA_LIFT` with pitch. 2. **Convexity-aware lift** — sample cell midpoints at build; raise vertices so the interpolated surface is a conservative upper envelope. Companion to 1. Cost: drape floats higher on ridges. 3. **Per-fragment drape (durable)** — TOA as a terrain-shader overlay (as the imagery basemap already drapes) or a screen-space decal from the depth buffer. Poke-through impossible at any LOD; deletes the rebuild loop + drift sentinel. taos-engine work, belongs in the engine-update lane. Generalizes to IR orthos / any draped raster. 4. **Depth-bias / always-on-top** — instant but wrong occlusion (fire glows through ridges). Debug toggle only. 5. **Clone the terrain triangulation** — exact but couples to engine tile internals; LOD churn. Dominated by 3. **Lean:** 1 (+2) near-term in the viewer; 3 long-term in the engine. Every constraint here is soft: `TOA_GRID = 120`, `TOA_LIFT = 6`, the 3 m drift gate are current minima of an error surface tuned on Sandy-scale bboxes; the Old Fire simply moved the surface.