**Note** from Bead: Sandy Fire Camera Tuner · [canonical source](https://redfish.acequia.io/guerin/.agents/0671f6fa-eb89-42a1-a854-6a95b97af23f/2026-06-22/notes/01-debbie-uxui-sketches.md) · session 2026-06-22 · discussion: Talk: Sandy Fire Camera Tuner
> This **replaces the ASCII version** per Stephen's 2026-06-22 directive ("we already talked about not using ASCII for sketches… i want to see sketches that show transitions"). The sketches are now **rendered, low-fidelity, interactive HTML** in the house style of `plume.html`, and each one **shows a transition** — the behavior over time (before → action → after). Per **Buxton**, interaction design is the *experience over time*; the design lives in the **transition**, not in any static frame. So every card has a *▶ replay transition* control that animates the key interaction over ~1–2s. > > Still sketch-ux (Buxton / Ervin): rough, question-bearing, **fork them, don't approve/reject.** Every affordance maps to a GET/PUT on the **namespace bus** (`b2d9f6e1` notes/02). Running theme: **every constraint is soft** — a tuned scenario is the *current minimum of a residual surface*, not a "right answer," and the UI must say so or a non-expert will over-trust a wrong fit. **Rendered sketch (open this):** https://redfish.acequia.io/guerin/.agents/0671f6fa-eb89-42a1-a854-6a95b97af23f/2026-06-22/artifacts/sketches/debbie-uxui-sketches.html The questions below are **answerable inside the sketch** — each card posts your fork choice + notes to this bead's dock (`request/`), which Debbie monitors (see `about.md` Modus Operandi).
## The organizing move: a cockpit with two truth-windows and one residual gauge Three organs already exist separately — the **model** (`fire-in-taos.html`: slope-biased fire CA on the real Sandy DEM, five sliders, observed-perimeter overlay, hectares + ROS graphs, a master clock); **truth-window A, the lens** (`through-the-lens-test-v1.html`: snapshot pins to screen, fly behind it, lock, drag points, an **LM solve** that already reports a residual); and **truth-window B, top-down** (the `toa-2026sandyv1` reference: 9 dated perimeters as RGB minutes-from-origin, plus the AlertCalifornia camera grid). Nobody has fused them into one tuning loop. The sketches ask: *where does the residual live, how do you drive the knobs, and how honest is the fit gauge?*
## S1 — What the eye judges: through-the-lens overlay vs TOA diff - **The question:** Is the primary match surface the **camera image** (through-the-lens) or the **map** (TOA diff) — and is the secondary one a glance away or hidden? - **Two forks:** **1A** render the sim fire from a camera's known pose and ghost it over the real frame at adjustable opacity (the Simtable differentiator, the LM-ready surface; weakness: one camera sees one sector, plume parallax is hard to read). **1B** a signed difference raster (sim isochrones − observed minutes-from-origin), top-down: reads the *direction* of error — too fast uphill, lagging on a flank — far better than any single lens. - **The transition it shows:** in 1A, an opacity slider **ghosts the sim front in** over the stand-in camera frame (before: bare frame → after: orange front blooming in at ~85%). In 1B, the **signed-error raster fades in** (red "sim ahead" lobe uphill, blue "sim behind" on the flank). The replay drives the fade so you feel the discrepancy appear, not just see a final picture. - **Least-action:** 1A reuses the snapshot-overlay + screen-pinned `<img>` from `through-the-lens-test-v1` wholesale; 1B reuses the model-vs-observed perimeter overlay already in `fire-in-taos.html`, swapped from polygon-outline to a per-pixel diff of the RGB minutes raster. - **Bus:** overlay frame = GET `cameras-sandy/<cam>/frame@<t>`; sim render is local; chosen surface + opacity ride in `location.hash`.
## S2 — How the knobs move: hand vs Solve vs seed-then-refine - **The question:** Does the human tune, the solver tune, or does the human **seed** and the solver **refine** — and which parameters are human-owned vs solver-owned? - **Two forks:** **2A/2B** keep the five sliders (maximally legible, the user *feels* slope-bias) **or** one **Solve (LM)** button that minimizes the residual over the parameter vector (fast, but a black box a non-expert won't trust). **2C** the synthesis: the human drags the ignition and roughs the wind (a *prior*), then "Solve" refines the rest — and **a 📌 pin on any slider becomes a hard constraint the solver won't touch**. The literal UI of "every constraint is soft… until you pin it." - **The transition it shows:** press **Solve** → the sliders visibly **drift to their fitted values** while the **residual gauge drops** from 0.74 (red) to ~0.09 (green) over ~1.3s. In 2C, you first **drag the ignition ◉** (the front re-renders live under your cursor), then Solve **settles the rest** — and any slider you **📌-pin stays frozen** through the solve. That before→after settle *is* the human-in-the-loop LM tuning made visible. - **Least-action:** sliders + ignition exist; the LM solver + residual loop + accept/reject damping exist (for pose). New work is the *parameter Jacobian* and the **📌-lock affordance**, not new optimization code. - **Bus:** a tuning attempt is a PUT `scenarios/<id>/params.json` (`{ignition, k, base, wind, locked[]}`); Solve writes the converged vector back to the same URI.
## S3 — Why you trust the fit: one score vs honesty band - **The question:** Is goodness-of-fit ONE trust-at-a-glance number, or a decomposed residual that shows **where** the model disagrees — and how do we render uncertainty without lying? - **Two forks:** **3A** a single five-dot "match" score with a since-last-solve delta (instantly legible for the public; hides *what* is wrong, invites over-trust). **3C** the honesty layer: draw the sim front as a **band, not a line** (width = confidence), surface **which parameters are unconstrained** ("ignition ±200 m — no camera sees the origin"), and when the residual surface is *shallow*, say "many tunings fit about equally well." - **The transition it shows:** in 3A, after a solve the dots **tick up** (●●●○○ → ●●●●○, "+22%"). In 3C, the single confident **line blooms into a fuzzy band** — the before→after that says *this fit is one of many*. That bloom is `every-constraint-is-soft` made visible, and it's what separates us from a fake-precise competitor. - **Least-action:** the hectares + ROS graphs already are the area/timing residual; the LM loop already computes a cost we can expose; band-vs-line is a render-style toggle on the existing front. - **Bus:** residual is derived (no storage); a *trusted* fit is a PUT `scenarios/<id>/fit.json` (`{residual, confidenceBands, unconstrained[]}`).
## S4 — How it fits on screen: docked cockpit vs stage + drawer - **The question:** Do all four windows stay **docked** and visible (cockpit), or is one promoted to a **stage** with the others as a peek-drawer you swap in? - **Two forks:** **4A** cam-grid rail, 3D/lens center, knobs right, TOA-diff + residual + timeline along the bottom — everything in peripheral vision, best for an expert solver, dense on a laptop or phone. **4B** one window is the *stage*, the other three are live thumbnails in a drawer; click one to promote it (calmer, mobile-friendly, field-appropriate; costs a click to compare). - **The transition it shows:** in 4A, the **shared master clock scrubs** and each panel **highlights in sync** — the one time-spine moving every window together. In 4B, **clicking a drawer thumbnail animates it UP to become the stage** (a real position/size tween). The non-negotiable spine in both: the **master clock** is the single shared time axis — scrubbing it moves the camera frames, the sim's model-time, AND the TOA perimeter together. - **Least-action:** the cam-grid's grid⇄map morph + canvas timeline are built (`timeline.js`); the model's panel + clock are built; 4B is mostly *promotion/peek* chrome over panels that already render. - **Bus:** clock position = `&t=` in `location.hash`; staged window = `&stage=lens|toa|grid`.
## S5 — Who tuned it (defer the shelf): solo deep-link vs scenario shelf - **The question:** Is multi-author / human-vs-solver scenario comparison in v1, or does v1 ship as a single-tuner tool with the social layer deferred? - **Two forks:** **5A** solo v1 — one tuning session, a **"Share view" deep-link** only (pure URL-state); ships fastest, the differentiator lands first. **5B** a **scenario shelf** — named, forkable tunings (human and auto-LM runs side by side), compared A/B on the diff map: this is where the **soft tournament** lives (rival fits as competing minima, the Hubler/least-action framing), but it's scope on top of an already-hard loop. - **The transition it shows:** in 5A, pressing **🔗 Share view** flashes "copied — anyone opens your exact fit" (the URL-state we're already encoding for S1–S4). In 5B, the rival scenarios **slide in one by one** (Debbie's fit · auto-LM run-7 · Cpt. Ruiz), each forkable. - **Recommendation:** defer the shelf; ship *one* social hook in v1 — the **citable deep-link** — because it costs almost nothing and it's the seam the shelf later grows from. - **Bus:** PUT `scenarios/<who>/<id>.json`; compare = GET two and diff; share = the hash URL.
## How they compose, and which to prototype first These are five layers of one cockpit, not rivals: **S1** what the eye judges · **S2** how the knobs move · **S3** why you trust it · **S4** how it fits on screen · **S5** who tuned it. A defensible first cut is **1A · 2C · 3C · 4B · 5A** — a through-the-lens overlay you tune by *seed-then-refine* with **pinnable** params, fit shown as an **honest band** (not a fake number), laid out as a **stage + drawer** on a **shared master clock**, with a single **citable deep-link** as the only social hook. That turns three separate viewers into one trustworthy tuning loop with almost no new math — we are mostly *wiring organs that already work*. **Designer's recommendation on what to prototype first: S2's fork 2C (seed-then-refine with pinnable parameters), riding on S1A's overlay.** It is the *beating heart* — the human-in-the-loop LM tuning — and it reuses the most existing code (the proven LM solver + the snapshot overlay), so the prototype is a wiring exercise, not a research project. **Build S3's honesty gauge alongside it, not after** — the moment a solver moves a slider on its own, the user must see *how soft that fit is* or they will over-trust or reject the tool. Then S4's layout, then the S5 deep-link. **The one genuinely un-pre-decided question for Stephen — keep it open:** *which residual is authoritative when the lens and the TOA disagree?* — the image-space "through-the-lens" match (what a camera saw) or the top-down TOA timing (minutes-from-origin). They will not minimize together (a fit that nails the plume from a camera can still arrive too fast on the back flank). That tension is the real fork under all five sketches, and per `every-constraint-is-soft` the answer is probably *weighted, re-weightable, and shown* — not picked once. Fork that question, or pick a sketch above to drive to prototype + Tufte.