**Note** from Bead: Firewatch Camera Grid · [canonical source](https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-13/notes/02-camera-wall-framesets-and-uri-authz.md) · session 2026-06-13 · discussion: Talk: Firewatch Camera Grid
Three corrections/extensions Stephen made after S2 (2026-06-13). They change the *primitive* the catalog is built on. Supersedes the "grid of one camera's frames" reading in notes 00/01.
## 1. The grid is a wall of CAMERAS, scrubbed by time The tile is a **camera/source**, not an image. Scrubbing the timeline swaps each tile to that camera's frame **nearest the playhead** — a synchronized, time-scrubbable camera wall (CCTV-matrix-as-time-machine). The grid⇄geo morph flies the camera tiles to their fixed map positions, posed by azimuth. This is exactly the incident-viewer's nearest-frame-to-playhead billboard logic (the Sandy 15801 billboard), promoted to a grid of tiles. - Per-camera data unit = `frames-<camId>.json` (S2 already produces this): a time-ordered list of posed frames. One bundle per tile. - Tile render at time *t* = binary-search the camera's frames for nearest *t* (±tolerance); show it, or a "no frame near *t*" placeholder.
## 2. Cameras and "frame-set" collections are first-class; phones bring multi-sensor image-sets The grouping primitive is the **source** and its **collections**, not the lone frame: - **frame-set** — a time-ordered collection of one camera's frames (a timelapse). 15801's 666 frames = one frame-set. - **image-set** — multiple sensors captured *together at one moment* (the phone case: front + back facing, opposite headings, each independently posed). A sibling of the frame-set: grouped by (source, moment) instead of (source, time-range). - The design opportunity = **playing with cameras + frame-sets**: group / split / collect / compare (front↔back), select a bound → make a collection. Maps cleanly onto STAC: **source/frame-set → Collection**, **frame → posed Item** (the sidecar), assets = the image(s). Phone image-set = a Collection whose Items share a `datetime` and a capture id but differ by sensor + heading.
## 3. STAC bind-to-URI establishes the access + authorization pathways Binding a frame-set/Collection (or Item) to a **URI** is the governance act, not just addressing. Per downstream-pattern a bind is simultaneously devops + governance + ACL + attribution + ledger; per the acequia auth model the URI is **where access + authz live**: - read scope via `read:anonymous` / capability sidecars; write/contribute scope via scoped `writePaths` + chain/capability tokens (reference_token-minting-pattern, feedback_acequia-as-not-no-as); the `/auth/*` peer mesh issues/attenuates. - *Managing catalogs = managing these pathways.* Who may **view** a camera's frame-set, who may **contribute** frames (a phone parciante PUTting an image-set into a collection's `uploads/` dock — "hey you, it's me"), and attribution flowing back up the bind (advanced wave) are all set by the URI binding + its auth sidecars.
## 4. RTE remote-first: qualified URLs, never relative realtime.earth's premise: **~99.9999% of queried pixels are remote** — and the query is often a *sub-image* (tile/pixel/region), not the whole image. The catalog is a thin index; pixels live elsewhere and are fetched on demand. Engineering rule for this fork: - **Absolute, qualified URLs everywhere** — never relative `./`. The forked santafe app's relative `./imageMeta`/`./imagePose`/`./thumbnails` must become absolute canonical URIs. `frames-<camId>.json` already uses absolute frame URLs. - **No local co-location.** The manager is a remote-first *view*: it does NOT mirror/deploy the 666 jpgs or thumbnails beside the app — grid tiles pull frames straight from their `https://simtable.acequia.io/...` URLs (CORS `*`). The only thing served at `…/app/` is the app + the small index bundle(s). - **Toward pixel/tile queries.** Design tiles to request what they show (eventual range/tile/COG-style fetches), not whole-image downloads — so the wall scales to many cameras × long time-spans without bulk transfer. - Consistent with feedback_bead-links-absolute-urls and layer 3 below — the absolute URL *is* the bound URI that carries the access pathway.
## The three layers (how it composes) 1. **Pose sidecar** — per-frame `{lat,lon,heading,pitch,fov,...}` (santafe `imagePose` ≈ ArcGIS Oriented Imagery). Image-addressable, standard-agnostic. (S2.) 2. **Frame-set / image-set Collection** — the source's grouping of frames (timelapse) or a moment's multi-sensor set (phone). The grid tile ≈ a Collection; "add to STAC" promotes a bound-selection to one. (S7.) 3. **URI binding + auth** — the Collection/Item bound at a URI carries read/contribute capability; the catalog manager is the human surface for curating both the grouping *and* the access pathway.
## Implication for the build - S2's per-camera bundle is the right unit — reframed as "frame-set per tile," not "one camera's grid." - **Data: go off the ONLINE source (the local mirror was incomplete).** The online dir `https://simtable.acequia.io/incidents/2026-CA-SandyFire/ops-alertcalifornia/` has **10 cameras**, all with telemetry + frames: 15801 South_Mountain_East_1, 15830 Las_Virgenes_1, 1886 Castro_Peak_1, 1887 Castro_Peak_2, 1934 Decker_2, 2220 Oat_Mtn_South_2, 2335 Saddle_Peak_1, 2456 Topanga_Canyon_2, 2763 Topanga_Peak_1, 2764 Topanga_Peak_2. Positions/az from the **STAC cameras collection** (all 10 present, SoCal) — NOT `getCameraDataByLoc.locs` by id (collides: locs 1886 = an Oregon cam). **Co-located pairs** Castro Peak (1886/1887) + Topanga Peak (2763/2764) = the image-set/multi-camera-site case, live. Thin index built: `repo/cameras-sandy.json` (id/name/lon/lat/az + qualified telemetry URLs + co-located sites). The wall fetches this manifest + per-cam telemetry + lazy frame pixels, all from qualified online URLs. - S7 "add to STAC" gains a 3rd dimension: emit the Collection **and** its access sidecar (the bind establishes the authz pathway), not just the Items.