# Return-to-center calibration fix — build 3

2026-10-01. Baseline 48c7ac0, clean working tree. James reported two stalls after LEFT → CENTER on build 2. No raw recording of those physical attempts is available, so this is a reproduced failure mechanism consistent with the report, not proof of their exact measured posture.

The old return gate required every sample for 0.6 seconds within 0.06 rad (3.4°) of the original neutral. A modest residual offset or boundary jitter restarted the hold; the guide then waited silently up to 30 seconds. Existing tests returned within about 0.6°, so they missed this case. Return-to-center checks readiness for the next step; it does not recalibrate neutral. The intended next step is FORWARD, followed by CENTER and final fitting. No RIGHT calibration stage is needed to fit the two independent gesture axes.

The return gate now enters at 0.10 rad (5.7°), allows small excursions up to 0.12 rad (6.9°), and still requires 0.6 seconds with rate at most 0.15 rad/s. A larger excursion, gap or excessive rate clears the hold and requires reentry. The original neutral samples remain unchanged. Collection thresholds are saved in calibration configuration. Prompts name the next step, give a reminder at 6 sensor seconds and fail explicitly at 15 seconds. Reminder completion cannot reset the stage clock or stop collection. Existing independent host-time sensor/speech watchdogs remain.

## Verification

- RED: offset/jitter return and wait/timeout assertions fail on build 2 source (`/tmp/rideform-return-red.log`).
- GREEN: all 31 app integration tests passed after the fix (`/tmp/rideform-return-green.log`).
- Additional final tests cover crossing the exit boundary/reentry and unchanged saved neutral. All 11 final calibration tests and the full spoken-calibration/record/save/export/cancel/relaunch UI workflow passed (`/tmp/rideform-return-final-tests.log`, TEST SUCCEEDED).
- Independent Swift source review: no findings. Reviewed hysteresis, reset on gaps/motion, reminder lifecycle and stale completion guards. The reviewer ran no builds or tests; authoritative runs belong to the coordinator. Reminder completion after advancement/cancel relies on existing speech-sequence guards plus existing lifecycle regressions; no new real-audio timing evidence is claimed.
- Scoped simplification/self-review kept the existing state machine, one reminder flag and the existing hold buffer. No new abstraction or dependencies.
- Signed device build succeeded (`/tmp/rideform-return-device.log`).

Mounted calibration and audible prompting remain physical checks. If it still waits, the new reminder and explicit center failure distinguish a return-gate rejection from silent inactivity; the exact device trajectory is still needed to establish a different root cause.

Delivery: codesign verification passed; install succeeded over the existing app and phone inventory reports 0.1 (3). Receipts: `/tmp/rideform-return-install.json`, `/tmp/rideform-return-inventory.json`. Launch was blocked by the phone’s lock screen (`/tmp/rideform-return-launch.json`); unlock and open RideForm. No physical success claimed.
