---
title: Motorcycle Lean Estimate - Plan
type: feat
date: 2026-09-15
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
---

# Motorcycle Lean Estimate - Plan

## Goal Capsule

- **Objective:** A rider can assess whether photographs support a meaningful lean difference from the reference rider and use that evidence in a coaching discussion.
- **Means:** Reviewed wheel-axis annotations, explicit photo-reference geometry, and gated numerical comparisons (KTD1–KTD5).
- **Authority:** This is a follow-on to `docs/plans/2026-09-14-1438-feat-paired-review-feedback-plan.md`. The feasibility, privacy, and evidence constraints in `../docs/plans/2026-09-14-0936-feat-track-day-body-position-plan.md` remain binding. IDs here are local to this feature.
- **Execution:** Begin with U1 source-only feasibility. Implement deterministic geometry and persistent data behavior test-first; verify interactions in the native Mac app.
- **Stop conditions:** Failed feasibility blocks dependent numerical coaching. Report an unmet measurement outcome rather than treating a plausible line or successful geometry test as validation.
- **Delivery:** Local implementation and verification; private images and derived artifacts stay local. Publishing or sharing photos is outside this plan. Coaching validation remains a rider/coach decision.

---

## Product Contract

### Summary

Add inspectable, editable photo-based wheel-lean estimates and eligible paired differences to the existing reviewer. Use Rider and Reference rider in the interface. Evaluate P05 and P06 first, distinguishing visible image angles from physical motorcycle lean.

### Problem Frame

The rider observes similar or greater motorcycle lean than the reference rider despite reporting equal speed during lead-follow riding. They want to examine whether the reference rider's upper-body position helps achieve the turn with less motorcycle lean. Current feedback describes posture but has no wheel or motorcycle inclination measurement.

The photographs are separate exposures with different subjects, apparent headings, and positions in the turn. Same-speed context does not establish matched radius, corner phase, banking, camera geometry, or causal explanation. The feature must help investigate the observation without predetermining which rider leans more.

### Key Decisions

- **Reviewable estimates.** Governs R1–R4. (session-settled: user-approved — chosen over automatic-only measurements: visible corrections and explicit evidence limits make the result inspectable.)
- **Separate observation and interpretation.** Governs R5–R6. Preserve the user's same-speed context while requiring evidence for the proposed explanation.
- **Neutral display labels.** Governs R7. Rider and Reference rider replace personal names in application-owned rider labels.

### Requirements

**Measurement and evidence**

- R1. Let users place and edit a visible front-wheel inclination axis on the intended motorcycle, independently of human joint detections.
- R2. Composite the wheel-axis line, reference direction, angle arc, and degree label directly over each rider's photo, with editable handles for adjusting the evidence; image-vertical measurements are labeled 2D wheel lean, not physical motorcycle lean.
- R3. Allow a reviewed orientation reference with provenance, including the same stationary background feature marked in both photos even when its true inclination is unknown; distinguish this shared proxy from a level reference or validated calibration.
- R4. Display a paired difference only when both measurements use compatible reviewed methods and the user has reviewed wheel/view/reference comparability; uncertain or unobservable evidence explains why the difference is unavailable.

**Feedback and context**

- R5. Integrate eligible observations into provisional coaching with annotation sensitivity and perspective limitations visible; a wheel proxy cannot produce a risk score, traction percentage, prescribed angle, or physical lean claim.
- R6. Record similar-speed context as user-reported, and keep body-position explanations conditional on separately reviewed posture and turn context.

**Identity and lifecycle**

- R7. Show Rider and Reference rider consistently in Single, Compare, sidebar, inspector, and application-generated measurement/coaching labels while preserving stable source identities and watermark text.
- R8. Commit, undo, save, reopen, and invalidate lean evidence with the same source integrity and unsaved-state protections as joint reviews; preserve raw detections and original photos.
- R9. Keep all private lean annotations and feasibility artifacts under ignored local storage; synthetic verification must run without private photos.

### Acceptance Examples

- AE1. In P05, a reviewed wheel axis produces a labeled 2D result even without a reviewed scene reference; no ground-relative or paired claim appears by default. Covers R1–R4.
- AE2. In P06, the target is the white-helmet rider on the silver bike at image right, not the large foreground red bike. Covers R1, R4.
- AE3. If plausible line placements yield overlapping difference bounds, the report says the ordering is unresolved; it never asserts the rider uses more lean. Covers R4–R5.
- AE4. Changing the reference line invalidates comparison approval and dependent coaching; Undo restores the prior evidence and eligibility. Covers R3–R4, R8.
- AE6. A shared background feature that slopes in both photos can support a relative wheel comparison without asserting that the feature is level; different portions of a curved road edge do not qualify by resemblance alone. Covers R3–R5.
- AE5. Reopening an older review retains joint edits and coaching; a name-label change does not alter source hashes or require a new detector run. Covers R7–R8.
- AE7. Selecting lean review shows the measured angle on the photo. Dragging a wheel or reference handle previews the revised arc and number; release commits the edit, refreshes dependent results, and saves it. Undo and reopening restore the corresponding overlay. Covers R1–R2, R8.

### Scope Boundaries

First delivery measures an apparent wheel-axis angle, with optional reference adjustment, including a shared stationary background feature whose true inclination is unknown. It does not recover a 3D motorcycle frame, center of mass, tire force, speed, radius, or hidden anatomy. The reference rider remains the app's provisional comparison baseline, not measurement ground truth.

#### Deferred to Follow-Up Work

General automatic wheel detection, camera calibration UI, calibrated physical lean, telemetry import, new head/torso displacement metrics, exports, and session-wide lean trends. U1 includes a bounded assessment of automatic line proposals; production automation requires separate validation rather than expanding this delivery.

### Success Criteria

On P05 and P06, the user can inspect the actual wheel/reference evidence and understand why a comparison is eligible or withheld. At least one pair must support a repeatable, useful apparent-angle comparison for numerical-comparison utility to pass. An inconclusive result is scientifically acceptable but does not count as achieving that utility outcome. Physical-lean accuracy and coaching validity are reported separately.

---

## Planning Contract

### Existing Evidence

`Sources/PoseCore/PairAnalysis.swift` computes reviewed elbow/knee included angles. `PairFeature` in `Sources/PoseCore/PairReview.swift` assumes every feature maps to three human joints; wheel inclination needs a separate measurement type. Pair contexts bind to frame identity, source hash, panel geometry, manifest, and detector report.

`Sources/PoseReview/ReviewerModel.swift` publishes document/report snapshots after committed edits and protects interactions with session, canvas, and frame identity. Its undo stack currently handles joint edits. `Sources/PoseReview/JointCanvas.swift` uses source pixels through `ReviewCoordinates`; panel coordinates are not detector-crop coordinates.

`Sources/PoseCore/ReviewSession.swift` currently reads schema 1–2 and atomically saves schema 2 under a revision-checked lock. `Sources/PoseCore/PhotoCoaching.swift` and several model mutations explicitly assign schema 2. Those assignments need coordinated changes when schema 3 is introduced.

`docs/highres-feasibility.md` and `docs/photo-coaching-verification.md` establish the current evidence limits and authored-coaching precedence. No existing lean accuracy benchmark is available. No strategy, concepts, solutions, or configured pack files were found for this scope.

Source-only inspection of the larger-source P05/P06 images found visible tire/rim/fork features and multiple motorcycles. P05 has corresponding road/grass boundaries and P06 has distant background structures worth checking for the same stationary segment; neither is yet verified as a reliable shared orientation reference. The visible road edges and distant background do not establish a calibrated local road normal. Existing rider crops omit parts of the tire in some images, so the tool must use the full panel. No lean measurements or automatic detector experiments were performed during planning.

### Key Technical Decisions

- KTD1. **Two-point wheel-axis proxy, selected manually.** Use a visible wheel-plane inclination cue following the rim/tire's long orientation; record the chosen cue and uncertainty. A short edge tangent, fork rake, or shading boundary alone does not establish the wheel plane. Compare candidate cues during U1 and freeze one repeatable annotation protocol before production work. Keep wheel annotations separate from joint edits. Implements R1–R2.
- KTD2. **Support a shared background proxy without assuming it is level.** Offer image vertical, an assumed level reference, and a paired shared-feature reference as distinct bases. In shared-feature mode, mark the same two identifiable points on a stationary feature in each full panel and bind the two lines by a common feature identity. Compare wheel orientation relative to that feature in each photo. The feature's unknown absolute slope need not be set to zero or called a horizon; under sufficiently similar views, its common orientation can cancel in the relative comparison. A road edge is usable only when the same local segment can be identified, not two different tangents of a curve. Different viewpoints can change projected feature orientation, so review correspondence and perspective explicitly. Watermarks, screenshot edges, moving objects, and unrelated parallel-looking lines are ineligible. This is an image-plane relative proxy, not ground calibration: see [MIT's Single View Metrology chapter](https://visionbook.mit.edu/3d_scene_understanding_single_view.html). Physical lean stays unavailable in this release. Implements R2–R4.
- KTD3. **Undirected line geometry with explicit sensitivity.** Measure the acute angle from the chosen upright axis, 0° upright to 90° horizontal, independent of endpoint order. Work in source pixels and degrees. Reject nonfinite, coincident, out-of-panel, or uncertainty-dominated segments. For shared-feature comparisons, retain signed line orientations modulo 180° and use a consistently unwrapped difference of wheel-minus-background orientations; do not subtract acute magnitudes that can lose direction. Reject ambiguous wrapping near the branch boundary. Label this value relative wheel inclination difference, with positive meaning rotation toward image right relative to the matched feature, rather than a physical more/less-lean verdict. Store a positive endpoint uncertainty radius for both lines. Bound angular perturbation from their endpoint disks, propagate conservatively, and label the interval annotation sensitivity rather than statistical confidence or total accuracy. Unknown systematic perspective error remains separately visible. Implements R2–R5.
- KTD4. **Lean-specific comparison approval.** Require a reviewed common cue, camera/view and wheel-heading comparability, and compatible reference bases. Independent image-vertical measurements need an explicit comparable-camera-roll judgment. Store approval against a digest of both current lean annotations and their source binding; any evidence edit makes it unreviewed. The delta is Rider minus Reference rider, with conservative bounds; describe an ordering only when the entire interval has one sign. Shared-feature mode reports relative orientation per KTD3; changing either matched feature line invalidates the pair approval. Unknown turn direction permits magnitude measurements but withholds inside/outside interpretation. Implements R4–R6.
- KTD5. **Keep live lean evidence separate from authored photo notes.** Add a dedicated lean evidence row next to provisional coaching, avoiding stale numbers embedded in authored text or displacement of its three-point budget. Show user-reported similar speed alongside the observation. The existing source-bound body-position notes may provide discussion context, but the app must not infer causation from a lean delta. ChampSchool discusses body position as a way to reduce required bike lean at a given radius; that motivates the feature, not validation of these photos. See [Why Body Position Matters at the Track](https://ridelikeachampion.com/why-body-position-matters-at-the-track/). Implements R5–R6.
- KTD6. **Schema 3 in the existing review document.** Add per-frame lean annotations and lean-specific pair context without altering immutable source fields. Read schema 1/2 with empty defaults and reject future versions. First save of each older schema preserves its exact bytes in an exclusive schema-specific backup under the existing lock before replacement. Preserve the established no-follow, regular-file, byte-match, and revision-conflict protections. Remove hard-coded downgrades across all mutation/import paths. Old binaries must reject schema 3 rather than silently drop lean fields. Implements R8–R9.
- KTD7. **Role-derived display names.** Centralize Rider/Reference rider presentation without changing manifest rider names, frame IDs, hashes, or raw role values. Audit application-owned copy; do not rewrite historical documents, arbitrary user prose, or photographic watermarks. Implements R7.
- KTD8. **Non-destructive on-photo measurement overlay.** Render R2 in the existing canvas above the photo, using the same source-to-display transform as its editable endpoints. Translate the chosen reference direction to the wheel-axis anchor to draw the angle arc without moving the actual reference annotation. In shared-feature mode, label the arc as wheel-to-feature orientation per KTD3, never degrees from vertical. Keep the label legible and inside the viewport with a leader when needed. A drag previews the local geometry immediately; the coaching report remains explicitly pending until commit. Any automatic proposal made available later uses this same editable presentation with its unreviewed provenance visible. Original image pixels remain unchanged. Implements R1–R2, R8.

### High-Level Technical Design

Data flow and ownership:

```mermaid
flowchart TB
    C[Full-panel canvas: wheel and reference lines] --> M[ReviewerModel: frame-bound committed edits]
    M --> D[ReviewDocument schema 3]
    D --> S[ReviewStore: backup, revision lock, atomic save]
    D --> A[LeanAnalysis: angle, sensitivity, eligibility]
    A --> V[Single and Compare lean evidence row]
    P[Authored photo coaching] --> V
```

Annotation lifecycle:

```mermaid
stateDiagram-v2
    [*] --> Missing
    Missing --> Draft: place line
    Draft --> Reviewed: confirm visible cue
    Reviewed --> Draft: edit evidence
    Reviewed --> Unavailable: uncertain or obscured
    Unavailable --> Draft: replace cue
    Draft --> Missing: clear
```

Comparison gates:

```mermaid
flowchart TB
    A{Both reviewed axes valid?} -->|No| X[Explain missing evidence]
    A -->|Yes| B{Reference bases compatible?}
    B -->|No| X
    B -->|Yes| C{Current comparability approval?}
    C -->|No| X
    C -->|Yes| D[Show delta and sensitivity interval]
    D --> E{Interval excludes zero?}
    E -->|No| F[Ordering unresolved]
    E -->|Yes| G[Describe basis-specific relative difference]
```

Commit and refresh sequence:

```mermaid
sequenceDiagram
    participant User
    participant Canvas
    participant Model
    participant Store
    User->>Canvas: Drag endpoint
    Canvas->>Model: Preview pending
    User->>Canvas: Release
    Canvas->>Model: Commit captured frame target
    Model->>Model: Invalidate approval and recompute snapshot
    Model->>Store: Save new revision
    Store-->>Model: Saved or explicit unsaved error
```

### System-Wide Impact

Lean edits need undo entries that coexist with joint changes and remain targeted after pane changes. A stale interaction cannot commit into a newly loaded session. Retry detection preserves lean annotations because it changes pose evidence, not the underlying photo; source or panel changes reject saved bindings.

All schema-writing paths, including the photo-coaching importer, must preserve lean fields. The CLI may reuse core validation for future automation; adding a general annotation import command is deferred. Save failures keep the in-memory report consistent and visibly unsaved, following current navigation protection.

### Risks and Deferred Implementation Questions

U1 owns the execution-time decision about cue repeatability and available orientation references. A result that supports only uncorrected image angles must remain labeled that way. A failure to find any repeatable cue blocks U2–U5; U6 labeling remains independently useful.

Front-wheel steering and camera yaw can change the proxy independently of frame lean. Manual comparability is a review judgment, not calibration. Screenshots supply no validated camera intrinsics; physical accuracy requires independent calibration or synchronized instrumented reference data in future work.

The annotation-sensitivity algorithm and comparison protocol must be fixed before inspecting computed rider ordering. This prevents tuning the measurement to confirm the original hypothesis.

---

## Implementation Units

### U1. Establish source-only wheel measurement feasibility

**Goal:** Decide whether P05/P06 support repeatable visible wheel-axis annotations and a useful apparent comparison.
**Requirements:** R1–R6, R9; AE1–AE3.
**Dependencies:** None; consult the parent plan's U1 constraints first.
**Files:** New `docs/lean-feasibility.md`, ignored `artifacts/lean-feasibility/`, and new `Tests/PoseCoreTests/LeanFeasibilityTests.swift`.
**Approach:** Inspect the manifest-selected original panels before any model proposals. Record intended bike, candidate cue, endpoint uncertainty, plausible alternative placements, and reference evidence. Specifically evaluate the same stationary background segment across each pair, including correspondence, curvature, occlusion, and perspective; lack of a true horizon alone is not a failure of this shared-proxy path. Use at least two independent annotation passes with earlier values and computed ordering hidden. Set the comparison protocol before evaluating deltas. Assess local edge/line proposals in a bounded offline experiment only after annotations exist; retain manual annotation as the delivery path.
**Patterns to follow:** `docs/highres-feasibility.md`, `Tests/PoseCoreTests/FeasibilityTests.swift`.
**Test scenarios:**

- Without `POSE_PRIVATE_MANIFEST`, the private check explicitly skips.
- P06 selects the intended background motorcycle and uses the full panel, not the old human crop.
- Both annotation passes fall inside the recorded sensitivity bounds; disagreement requires wider bounds or unavailable status.
- A nonlevel but correctly matched stationary line supports a relative-reference trial while remaining ineligible as calibrated ground evidence.
- Different road-edge tangents, unmatched structures, and watermark lines fail the shared-feature gate.

**Verification:** Produce a per-pair go/no-go decision with reasons. Separate proxy repeatability, paired utility, automatic-proposal usefulness, and physical accuracy. Do not claim production automatic detection or coaching validation.

### U2. Add pure lean geometry and eligibility

**Goal:** Compute auditable apparent angles and paired differences.
**Requirements:** R2–R5; AE1, AE3, AE6.
**Dependencies:** U1 repeatable-cue gate.
**Files:** New `Sources/PoseCore/LeanAnalysis.swift`, new `Sources/PoseCore/LeanReview.swift`, new `Tests/PoseCoreTests/LeanAnalysisTests.swift`.
**Approach:** Implement KTD1–KTD4 as pure geometry and evidence evaluation; use a dedicated lean report rather than extending the three-joint feature catalog.
**Execution note:** Write failing deterministic geometry tests first.
**Test scenarios:**

- Vertical, diagonal, horizontal, and reversed endpoints produce 0°, 45°, 90°, and unchanged magnitudes.
- Translating, uniformly scaling, or rotating both measurement and reference preserves the relative angle; a rotated measurement alone changes it.
- Nonfinite, coincident, out-of-panel, and uncertainty-dominated inputs withhold results.
- A synthetic shared line with unknown nonzero slope and independent image-roll changes preserves the expected signed relative wheel difference.
- Reversing either shared-line endpoint order leaves the result unchanged; near-wrap ambiguity withholds ordering.
- Interval propagation includes extreme allowed endpoint placements and never wraps near 0°/90° incorrectly.
- Missing approval, mismatched reference basis, and overlapping delta bounds produce their distinct unavailable/unresolved outcomes.

**Verification:** Synthetic geometry proves arithmetic and eligibility only; no private data dependency.

### U3. Persist lean evidence without losing existing reviews

**Goal:** Safely save and restore lean data alongside existing annotations.
**Requirements:** R8–R9; AE4–AE5.
**Dependencies:** U2.
**Files:** `Sources/PoseCore/ReviewSession.swift`, `Sources/PoseCore/PairReview.swift`, `Sources/PoseCore/PhotoCoaching.swift`, `Sources/PoseCore/LeanReview.swift`, new `Tests/PoseCoreTests/LeanReviewTests.swift`, `Tests/PoseCoreTests/PhotoCoachingTests.swift`.
**Approach:** Apply KTD6 and validate lean fields on both load and save. Bind annotations to frame/source geometry and invalidate stale comparison digests. Preserve all existing contexts, retry records, joint history, and immutable evidence.
**Execution note:** Establish failing compatibility and data-preservation tests before changing serialization.
**Test scenarios:**

- Schema 1 and 2 load without writes and first save creates the correct byte-identical backup before schema 3 replacement.
- Backup mismatch, symlink, write failure, or stale revision leaves the previous review intact.
- Invalid coordinates, orphan frame IDs, foreign bindings, malformed uncertainty, and future schemas are rejected.
- Photo-coaching import into schema 3 preserves lean data and does not downgrade the document.
- Round-trip reopening restores evidence and regenerates the same derived report.

**Verification:** Older reviews remain recoverable; current data survives every writer. Document rollback using the preserved older-schema file, with later edits retained separately.

### U4. Add wheel and reference editing to the native reviewer

**Goal:** Make each measurement visibly inspectable and correctable.
**Requirements:** R1–R4, R8; AE1–AE2, AE4, AE6–AE7.
**Dependencies:** U2–U3.
**Files:** `Sources/PoseReview/JointCanvas.swift`, `Sources/PoseReview/ReviewerModel.swift`, `Sources/PoseReview/PairComparisonView.swift`, new `Sources/PoseReview/LeanReviewView.swift`, `Tests/PoseReviewTests/ReviewerModelTests.swift`.
**Approach:** Add an explicit lean-edit mode with wheel/reference endpoint placement, confirmation, uncertainty, clear, and unobservable actions. In Compare, let the user select a shared feature, mark its matching endpoints in both photos, and inspect both reference lines together. Reuse source-coordinate mapping and captured interaction identity. Extend undo to interleave joint and lean edits. Keep lean lines independently toggleable and keyboard-editable; display the currently selected rider and cue.

Implement the on-photo composition in KTD8 in both Single and Compare, visible by default when lean review is active. Wheel and reference handles must be directly selectable on the photo; the feedback row supplements this overlay. Missing or invalid geometry shows placement guidance without a fabricated arc or angle.
**Test scenarios:**

- Dragging either pane changes only its captured frame, including after focus changes.
- Escape, mode change, session change, or pane replacement cancels draft interaction.
- Zoom, scrolling, and nonzero panel origins preserve source coordinates; annotations can extend beyond human detector crops.
- Interleaved joint and lean Undo restores the right evidence and approval state.
- Save failure retains matching unsaved results and blocks unsafe navigation using the existing behavior.
- Covers AE7. Drag previews update the on-photo arc and number together; release, Undo, and reopening keep the overlay consistent with the committed evidence and report.
- Both image-vertical and shared-feature modes draw the arc against their actual reference basis and label it accordingly.
- At Fit and zoomed sizes, both panes retain legible degree labels and usable handles; hiding joint markers does not hide the lean overlay.

**Verification:** Native interaction review in Single and Compare confirms the composited lines, arc, degree label, direct handle editing, keyboard adjustment, and P06 selection; source hashes remain unchanged.

### U5. Integrate live lean evidence with provisional coaching

**Goal:** Present useful numerical evidence without manufacturing a riding verdict.
**Requirements:** R4–R6, R8; AE3–AE4.
**Dependencies:** U4.
**Files:** `Sources/PoseCore/PairAnalysis.swift`, `Sources/PoseCore/ProvisionalCoaching.swift`, `Sources/PoseReview/PairFeedbackView.swift`, `Sources/PoseReview/ReviewerModel.swift`, `Tests/PoseCoreTests/ProvisionalCoachingTests.swift`, `Tests/PoseCoreTests/PairAnalysisRevisionTests.swift`, `Tests/PoseReviewTests/ReviewerModelTests.swift`, `docs/feedback-rule-catalog.md`.
**Approach:** Apply KTD4–KTD5 in a dedicated evidence row. Show rounded whole degrees with sensitivity bounds, basis, source revision, comparable/unreviewed status, and optional user-reported speed context. Do not apply existing elbow thresholds to lean. Recompute after lean/context commits and Undo; preserve authored-note direction handling.
**Test scenarios:**

- Positive, negative, and zero-crossing delta intervals yield basis-specific wording: magnitude ordering for upright references and signed relative wheel rotation for shared-background references, per KTD3.
- An unpaired photo displays only its own measurement and never borrows a reference.
- Unknown direction withholds inside/outside interpretation while allowing eligible magnitude comparison.
- Similar-speed context never enables comparability, risk scoring, or a causal body-position claim.
- Editing reference evidence removes approval and live comparison immediately; reopening reproduces the saved state.
- Existing authored notes remain separate and contain no cached lean numbers.

**Verification:** P05/P06 utility review checks that the user understands the proxy and its withheld claims. Numerical comparison passes only under the Product Contract's success criteria.

### U6. Apply neutral rider labels and document the feature

**Goal:** Use consistent role labels and explain the new evidence workflow.
**Requirements:** R7–R9; AE5.
**Dependencies:** Label work can proceed independently after U1; final documentation depends on U4–U5.
**Files:** `Sources/PoseReview/PoseReviewApp.swift`, `Sources/PoseReview/PairComparisonView.swift`, `Sources/PoseReview/PairFeedbackView.swift`, `Sources/PoseReview/ReviewerModel.swift`, `Tests/PoseReviewTests/ReviewerModelTests.swift`, `README.md`, new `docs/lean-review-verification.md`.
**Approach:** Apply KTD7 and document line selection, reference basis, comparison approval, unavailable results, and schema rollback. Audit generated strings for personal names while preserving source identity.
**Test scenarios:**

- Existing personal-name manifests render Rider/Reference rider across the named UI surfaces.
- Reversed source-panel order and unpaired sessions retain correct roles.
- Label changes leave serialized identities, source hashes, photo pixels, and watermarks unchanged.

**Verification:** Native visual audit and a targeted presentation test confirm the labels; documentation describes the delivered capability and remaining feasibility limits.

---

## Verification Contract

- Run `scripts/swift.sh test` using the project toolchain; use the documented `--disable-sandbox` option when SwiftPM's nested sandbox prevents the established local test workflow. Deterministic geometry/data tests begin failing before implementation.
- Private feasibility checks require `POSE_PRIVATE_MANIFEST` and explicitly skip when absent. Source annotations precede automatic proposals; public tests use synthetic geometry.
- Build with `scripts/build-review-app.sh` and verify Single/Compare placement, zoom, pane switching, cancel, Undo, reopening, and save failures in the native app.
- Verify schema backups, old-file preservation, importer round trips, and source hashes. Keep private logs, coordinates, screenshots, and computed photo results in ignored storage; committed documentation contains only methods and aggregate gate outcomes.
- Record arithmetic correctness, annotation repeatability, comparison utility, and coaching validity separately. A successful build or visible wheel line passes neither physical-angle accuracy nor coaching validity.

---

## Definition of Done

- U1 has an explicit feasibility outcome; each implemented unit meets its verification and traced requirements.
- At least one real pair satisfies the comparison-utility criterion, or the unmet outcome is reported with dependent work stopped rather than marked complete.
- Displayed values identify their proxy, reference basis, sensitivity, and revision; unsupported physical/risk claims remain absent.
- Each available lean measurement is composited directly onto its photo and can be adjusted there, with consistent preview, commit, Undo, and reopen behavior (R2, KTD8).
- Existing reviews are preserved, schema upgrade/rollback is documented, and neutral labels do not modify identity evidence.
- Appropriate package tests and native checks pass. No abandoned detector experiments or dead code remain in the production diff.
- Private source photos and derived artifacts remain local and originals/watermarks are preserved. Rider/coach validation is reported as pending unless independently completed.
