Pose as soft-constraint relaxation — least-action bidirectional coherence over links (Stac Camera Telemetry)

**Note** from Bead: Stac Camera Telemetry · [canonical source](https://redfish.acequia.io/guerin/.agents/31f69717-3c68-4a0d-85d3-9515ec2e91ff/2026-06-14/notes/01-soft-constraints-least-action-pose-coherence.md) · session 2026-06-14 · discussion: Talk: Stac Camera Telemetry

> Stephen, 2026-06-14: *"the air7-track is a prior. lets display it and move the camera with it. > a future task will be to have 'calibrators' manually and auto adjust the camera pose based on > geopoints and other uv-uv correspondences. always remember every constraint is a soft constraint. > no constraint is absolute. we always want to adjust the poses based on the collective error > surface using least action bidirectional coherence peer-to-peer of the hosting endpoints of a > constraint (links)."*

## The principle (load-bearing, "always remember") **No constraint is absolute. Every constraint is soft.** A pose is never *pinned* by any single source — it is the current minimum of a **collective error surface** assembled from many weighted constraints. The ADS-B track, the telemetry, a ground control point, a tie point — all are *priors with finite stiffness*, not ground truth. New evidence reshapes the surface; poses re-settle.

## The constraint zoo (all soft, all the same kind) | Constraint | Endpoints (the "link") | Softness / weight | |---|---|---| | **Prior — ADS-B track** | ship-position(t) ↔ camera pose(t) | covariance of the recovered track; `recovered-prior` ⇒ loose | | **Prior — PTZ telemetry** | `camAzimuth/El/ViewWidth` ↔ pose | sensor precision; `native-pose` ⇒ tighter | | **Geopoint / GCP** | world (lat,lon,elev) ↔ image (u,v) | calibrator confidence; manual click vs auto-match | | **UV-UV correspondence (tie point)** | image_A (u,v) ↔ image_B (u,v) | matcher score / reprojection residual | | **Calibrator adjustment** | human or auto agent ↔ a pose/constraint | trust in the calibrator | A **calibrator** (manual or auto) doesn't *set* a pose — it *injects or reweights constraints* and lets the surface re-relax.

## The solver, in ecology terms This is **bundle adjustment / factor-graph / pose-graph optimization** — reframed: - A **constraint is a polarized link** between two endpoint resources (see [polarized-links](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/polarized-links.md)). The factor graph **is** the link topology. - **"Bidirectional coherence"** = the constraint pushes **both** endpoints, not one — the Wheeler-Feynman advanced+retarded ledger ([advanced-wave](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/advanced-wave.md)). Error flows up the link *and* back down; both ends adjust. - **"Least action"** = relaxation to the minimum of the collective error surface — exactly the [Hubler self-assembling wires](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/self-assembling-wires/ecology.md) settling under structured demand. Stiffness = information matrix; robust loss = the softness. - **"Peer-to-peer of the hosting endpoints"** = each constraint is **hosted by its endpoints** (the resources/URIs it links), not by a central solver. The optimization is distributed across the parciante nodes that hold the endpoints — relaxation by message-passing over links, not a monolithic batch solve. (Local solves + neighbor exchange ≈ distributed/incremental BA.)

## Schema implications (for the unified pose sidecar) Therefore the sidecar must NOT express a pose as a hard fact. It expresses an **estimate + its constraints**: ```jsonc // imagePose/<id>.json (per-frame or per-image) { "id": "<frame id>", "datetime": "2025-01-08T20:41:03Z", // capture time (soft too: clock_offset below) "estimate": { // current MAP pose — the surface's present minimum "Latitude": 34.107, "Longitude": -118.579, "Elevation": 2100, "heading": 212, "pitch": -18, "roll": 0, "fov": 50, "fovy": 30 }, "covariance": { /* 6-DoF block or stddevs */ }, // how soft THIS estimate is "provenance": "recovered-prior", // native-pose | recovered-prior | none "clock": { "source": "yt-dlp-publish", "offset_s_estimate": null, "soft": true }, "constraints": [ // the links — every one weighted, none absolute { "type": "adsb-prior", "weight": 0.3, "href": ".../adsb-ab4ea1.json#t=20:41:03" }, { "type": "gcp", "weight": 5.0, "world": [-118.58,34.11,40], "uv": [641,402], "by": "calibrator:manual" }, { "type": "tie", "weight": 1.2, "uv": [710,388], "peer": "<other frame id>", "peer_uv": [402,377] } ], "residual": 0.0 // reprojection error at current estimate } ``` - `estimate` is mutable and re-derived; `constraints[]` is the durable truth. - A track sidecar (`adsb_track`) is the **time-series of `adsb-prior` endpoints** the renderer draws as a path and the camera follows. - Calibrators append/reweight `constraints[]`; the solver re-relaxes; `estimate` + `residual` update.

## Immediate vs future - **Now:** treat `air7-track.json` as the `adsb-prior`; draw the path; **slave the camera to it** (camera pose(t) = the prior, identity stiffness for now). This is the degenerate one-constraint case. - **Future:** add geopoint + UV-UV calibrators; promote the single prior to a soft node in the full least-action surface; distribute the relaxation P2P across the constraint endpoints. Related: [rewiring-cognition](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/rewiring-cognition.md) · [downstream-pattern](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/downstream-pattern.md).

## References (bead cross-links) - Bead: 874fce5b · [canonical](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/)