**Note** from Bead: Firewatch Camera Grid · [canonical source](https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-14/notes/10-handoff-2026-06-14.md) · session 2026-06-14 · discussion: Talk: Firewatch Camera Grid
Picks up #firewatch-camera-grid. Supersedes note 09 (2026-06-13) for everything below. Read note 09 too for the camera-wall / adsb history.
## Identity + mounts - **Write-target bead:** `firewatch-camera-grid` **65783732-7907-4a36-983a-3b015e75e80b**. - **Mounted-for-read:** - **`cbf8b027`** incident-viewer-taos-engine-app — the 3D viewer's home bead (cross-bead ships log here). - **`31f69717`** stac-camera-telemetry — **AIR7 telemetry collaboration** (active; see §4). Its bead is **local-only (404 on the redfish remote)** — messages move via the local commons mirror. - **`c66cbd1d`** taos-engine — engine knowledge + the **taos-orama** query index (§5). - **`6f5044df`** orama-bead — the reusable `bead-orama` skill. - `2986ff41` (adsb-palisades pull), `b3461c66`, `90f902e0`.
## 1. THE THING: incident-viewer (3D STAC viewer) - **Source:** `c:/Users/steph/Documents/src/incident-viewer/` — a **local git repo, NO GitHub remote** (commits are local only). Single `index.ts` (~3k lines) + `index.html` + `public/`. Builds against the sibling `../taos-engine` clone: **`npm run build`** → `dist/` (index.html + one hashed chunk). - **Deployed to BOTH, byte-identical index.html:** - **redfish** `https://redfish.acequia.io/guerin/apps/incident-viewer/` (bearer `.credentials/redfish-acequia-jwt.txt`) → defaults to the **simtable incidents** catalog (Palisades + Sandy). - **santafe.live** `https://santafe.live/` as `index.html` (bearer `.credentials/santafe-live-token.txt`) → defaults to **its own `./stac/catalog.json`** (59 historical photos). - **Deploy = WebDAV PUT** the chunk + index.html, then DELETE the old chunk, to EACH host. **Current: commit `44d6487`, chunk `index-Dw0d792j.js`.** - **STAC override:** `?stac=<catalog.json>` overrides; default = same-origin `./stac/catalog.json`, fallback = simtable. walkStac is **shape-flexible** (root→incident→collection→item AND root→collection→item single-event) and tolerates **non-FMV events** (posed stills, no clips). - **CDP verify (REQUIRED, pixels not counts):** serve `dist/` on `:8123` (`python3 -m http.server 8123` from dist) → `tools/cdp-shot.mjs <url> <out.png> <ms>` + `tools/ev.mjs '<expr>' out.png` (reads `window.__misb`). Use `?cb=$RANDOM` to bust the CDP cache. WebGPU needs a real GPU — never headless-screenshot.
## 2. Tokens / caching (RESOLVED — see §"why") - **Maps are TOKEN-FREE:** DEM = **AWS Terrarium** (`s3.amazonaws.com/elevation-tiles-prod`), imagery = **Esri World Imagery** — both public, no key (`geo.addRasterDemTerrain(AWS_TERRARIUM, {imagery: ESRI_WORLD_IMAGERY})`). NOT "Brendan's" — there's no map token. - The only token (`?token=` on the `/taos` engine bundle, `lhwk2ev8u8khycd17a1njrk7`) is **now MOOT** — Stephen made `/taos` public; verified the viewer renders with **no token at all**. Droppable (queued). Keep it for now (harmless). NOTE: dropping the `?token=` *blanks terrain* ONLY if /taos were private — it was a cache/SW confound earlier; with /taos public the token does nothing. - **DEM tiles ARE cached:** persistent browser **Cache-Storage `cesium-tiles-v1`** (verified 993 terrarium tiles live) via `HttpDataSource.fetchArrayBuffer` + an in-memory **512 MiB LRU** per tileset (`GeoTerrainOptions.budgetBytes`). The "cache override" is `fetchJson(url,{cache:true})` for immutable tileset.json (Cesium/3D-tiles path). - **NO service worker** — removed (it only existed to token-shim `/taos` workers when private; `/taos` public now). `/sw.js` is a RESERVED acequia-platform path, so never re-add an SW named sw.js.
## 3. What shipped this session (commits, newest→oldest) `44d6487` version (v0.1.0) in gear footer + skip CORS-blocked alertwest stills · `33a019c` items right-click **context menu** (copy url · open in tab · fly-to H · show/hide · set timeline to extent · set map to bounds · properties), **no auto-fly on select**, **STAC selector at panel top**, hide glyphs in H · `930e0bd` **catalog-driven track renderer** (AIR7 from `adsb_track` sidecar) · `9a4c982` nearest-frame on look-through/project + hide glyph in H · `dbeb1b8` **posed stills → cameras** (H/I) + look-through shows hidden · `98d49cc` **projection (P)** drapes image onto terrain · camera-look-through (`camLock`) = sensor-lock analog · `5a76e6a` same-origin default STAC · `34d9ec5`/`6ed4166` **drop SW** (keep token) · generic events + all-off-startup + per-catalog localStorage visibility · `bcdc3ca` camera look-through · default-Sandy fit-all + AIR7 prefetch · roster→focus. Plus: **santafe.live deploy** (renamed old manager → `STAC-manager.html`; built santafe STAC via bead skill `derive-stac-from-image-cache.mjs`). Also updated the **live simtable AIR7 item + news-aerial collection** with `start/end_datetime` = the track window (temporal bounding fix).
## 4. AIR7 telemetry collab (31f69717) — ACTIVE, my next lane - The Palisades **N828AP** news-heli path now renders **catalog-driven** from its `adsb_track` sidecar (recovered-prior = dim/thin), supersedes the hardcoded `air7-track.json` for catalog items. Loader accepts both `{points:t_ms,lat,lon,alt_m,hdg}` and raw `{track:[{t_sec,lat,lon,alt_ft,track}]}`. - **GO directive (their dock → me):** update STAC (unified pose), display track ✓, **camera-follows-track** (NEXT), deploy ✓. Framing: the track is a **SOFT PRIOR not truth** — pose = minimum of a collective error surface, settled by **least-action bidirectional coherence (= bundle adjustment / factor graph)**; build the prior as a **reweightable soft node**, don't foreclose future **calibrators** (GCPs + UV-UV tie points). Durable truth = `constraints[]`, not the estimate. - **My replies are in `31f69717…/uploads/` (LOCAL only).** I owe them: the post-camera-follow consume/ignore report. - **⚠️ UNREAD INBOUND in MY dock (`65783732…/uploads/`) — READ THESE:** (1) `2026-06-14T204711-stac-bead-unified-sidecar-schema.md` — their **unified pose-sidecar schema draft** (the contract the renderer + editable-Properties should target); (2) `2026-06-15T023012-stac-bead-ack-temporal-bound.md` — they **acked** my `start/end_datetime` bounding. I sent them the temporal-bounding FYI (`…022900-firewatch-air7-temporal-bounding.md`). Still owed by them: a **Sandy news-aerial STAC item** (to delete the hardcoded air7-track.json).
## 5. taos-orama — query the engine instead of grepping (USE THIS) `c66cbd1d/2026-06-14/skills/taos-orama/` — `node build-taos-index.mjs --query taos-index.json "<q>"` (reuses `6f5044df` bead-orama core; `@orama` resolves from there). Answers engine API/capability questions in one query. Confirmed: **Google Photorealistic 3D Tiles = `GoogleTilesSource` (`src/geo/google_tiles.ts`), uses the caller's Google Maps key, NO Cesium ion**. Next: distil a `capability-matrix.md` + a taos-dev `agent.md` on top of it.
## 6. NEXT (queued, pick up here) 1. **camera-follow** the AIR7 track over the master clock (soft node) — closes the 31f69717 directive; reply with consume/ignore + URL. 2. **adaptive billboard sizing** — cameras as min-screen-size thumbnails at any zoom (Stephen's "minimal effective pixel size vs geospatial range"), so the 3D view shows cameras like the firewatch grid. SUBSUMES the **close-range look-through** (the range-trick WIP showed terrain — REVERTED; do view-locked instead). 3. **editable Properties panel** — turn the read-only props (right-click → Properties) into heading/pitch/height/fov/opacity editors → feeds the calibrator/soft-constraint schema. 4. **alertwest CORS proxy** (WORK-QUEUE) — non-timelapse cams' `latest` is on `alertwest.live` (403 cross-origin, CORS-blocked); a proxy re-enables those snapshots. Timelapse cams use CORS-OK simtable `frames_base` (unaffected). Skip is live. 5. Drop the `/taos` token; add `deploy.sh` (build→push both) + optional GitHub remote.
## 7. Conventions Qualified URLs only; animate in ECEF; **verify PIXELS via CDP**; every ship = commit (`Co-Authored-By: Claude…`) + deploy BOTH + CDP verify + one `log.md` line; chat log incrementally; sync the bead at end. Windows: `python3` is Windows Python (no MSYS `/tmp`); console cp1252 (ASCII prints).