# RideForm V0 execution state

Source: `docs/plans/2026-10-01-1011-feat-torso-motion-logger-plan.md`; original brief: `docs/requirements/ios-v0-brief.txt`.

## Authority and landing

James authorized full implementation, native subagents, independent verification, dedicated local repository, and verified local commits. No push. Handoff is installable app plus all available local evidence; full experimental Definition of Done awaits physical iPhone evidence.

Engine: native subagents, dependency-ordered units, shared workspace with exclusive ownership. No CE engine configuration in this newly initialized repository. Coordinator owns integration, authoritative tests, and commits.

## Inventory and tooling

Initial RideForm files: only offered plan and brief. Parent repository has unrelated WIP; untouched. Dedicated repository branch `feat/ios-v0` initialized. Swift 6.4, Xcode 27 beta (27A5194q), iOS/watchOS 27 SDKs. Active system developer directory is CommandLineTools; use explicit DEVELOPER_DIR. No available simulator runtime on initial inspection; investigate/install while core is implemented.

## Tasks

- [x] U1 portable schema, package, Xcode shell
- [x] U2 acquisition, clocks, sampling statistics
- [x] U3 neutral/axis calibration
- [x] U4 durable storage and exact export
- [x] U5 recording lifecycle, UI and cues
- [x] U6 reproducible analysis and candidate metrics
- [x] U7 review and diagnostics
- [ ] U8 physical acceptance (automated checks, installation and garage/Watch documentation complete)
- [x] Independent review, fixes, final software verification and local commit

## Research gates pending James

Physical sign/mount checks; actual sampling and matched fused-only/combined trials; Files/AirDrop on iPhone; roughly 50-transition garage trial with independent labels. No hardware result inferred from simulator or requested intervals.

## Tooling progress

- iOS 27 runtime (24A5355p) downloaded and installed successfully. Simulator operations require sandbox escalation. Native package tests can use /tmp scratch builds.
- Independent verifier notes: validate Mach clock mapping; preserve Apple raw attitude and prove canonical transform separately; required-reason privacy manifest for uptime use.

## U1 integrated evidence

- Worker RED: missing model symbols; GREEN 5 XCTest tests, 0 failures. `docs/validation/u1-evidence.md`.
- Coordinator: iOS Simulator shell build succeeded (`/tmp/rideform-u1-build.log`); Xcode-selected core tests passed 5/5 (`/tmp/rideform-u1-authoritative-core-xcode.log`).
- Initial coordinator core run with CommandLineTools could not resolve XCTest; durable `scripts/test-core.sh` now selects installed Xcode explicitly.

## Connected-device authorization

James connected iPhone by USB and explicitly requested installation when appropriate. Device: iPhone 16 Pro, iOS 27.2, Developer Mode enabled, paired/available. Existing Apple Development identity/team available; signing probe started. Install and launch only after integrated app checks. Device identifiers are kept in local /tmp tooling receipts, not required in public docs. Physical mounting and garage protocol still pending human participation.

## U2 integrated evidence

- Core suite: 8 XCTest tests, 0 failures (`/tmp/rideform-u2-core.log`).
- Simulator integration TEST SUCCEEDED (`/tmp/rideform-u2-app-tests-fixed.log`, xcresult under /tmp/rideform-derived/Logs/Test/). Tests exercise clock checks, both convention directions and accepted stop rows.
- Initial simulator linkage failed because Debug built both architectures while package built active only; fixed standard ONLY_ACTIVE_ARCH Debug setting, then GREEN.
- Development signing probe on connected physical destination BUILD SUCCEEDED (`/tmp/rideform-signing-probe.log`); app not installed yet.
- U1 independent report `docs/validation/u1-independent.md` passed; source SHA matches 85935f8.

## Next dependency frontier

U3 calibration active. U4 follows U3; then U5 workflow and U6 analysis can run concurrently with disjoint ownership against committed U4. U7 follows both. U8 includes automatic physical foreground acquisition smoke now possible over USB, plus documentation and independent exported-artifact checks; mounted sign/controlled movements remain James gates.

## U3 and capture corrections

- U3 coordinator core suite:13 XCTest tests/0 failures (`/tmp/rideform-u3-authoritative-core.log`). Saved neutral/axis samples, oblique transforms, inverse convention, standard shortcut signs, stillness/retry guards.
- Integrated simulator suite:9 app tests/0 failures (`/tmp/rideform-u3-app-tests.log`).
- U2 independent P2 findings fixed with observed RED/GREEN regressions: immediate convention invalidation; uncancellable serial control queue separate from sensor queue; stale generation suppression. Reports `u2-independent.md`, `u2-fix-evidence.md`. Stop acceptance boundary explicitly documented; no zero hardware-callback-loss claim.

## Independent U3 follow-up

Independent Python-matrix expected fixtures passed966 q/sign evaluations (483cases), angle error <1e-13rad, vector error <2e-14. Verifier reproduced moving-neutral controller stuck path: a bad early sample leaves Continue disabled and masks movingNeutral as tooShort. Scoped regression fix active; U4 continues disjoint storage paths.

## U4 integrated evidence

- Final coordinator core19/0 failures (`/tmp/rideform-u4-final-core.log`); prior integrated app13/0 plus final repository targeted2/0 (`/tmp/rideform-u4-final-app.log`).
- Worker RED recovery count regressions observed then GREEN; real-disk write failure retry and exact export tests pass. Independent checker ZIP6files/8CSV tables/10rows/291cells passed bit-exact floats.
- Representative master/export artifacts `/tmp/rideform-u4-export-731D6117-20D5-403E-B579-873668230EFA` (coordinator) and `/tmp/rideform-u4-export-2DCFBC03-B42C-4B8F-AD25-43E36E46B1AE` (independent inspected).
- User now requests first usable preview installed before all analysis/review finishes; prioritize U5 early install after workflow smoke. Full implementation remains authorized, U6/U7/U8 continue.

## U5/U6 parallel wave

Clean baseline ae8be83. U5 owns App recording/UI/cues + lifecycle/UI tests; U6 owns core analysis/fixtures/metrics documentation. No shared schema writes. U5 preimplementation test snapshot copied to /tmp/rideform-u5-red-snapshot for coordinator RED before controller implementation. U6 uses isolated scratch core snapshots for proof-first math. First usable preview installation requested by James will happen after U5 workflow smoke without waiting for full U7 review.

## Installed recording preview

U5 frozen preview passed16 app tests and full simulator UI workflow, including share cancellation, second recording, interruption, relaunch and reopening. Evidence `docs/validation/u5-evidence.md`, `/tmp/rideform-u5-preview3-tests.log`. Exact tested snapshot signed successfully (`/tmp/rideform-preview-device-build.log`) and installed on connected iPhone (`/tmp/rideform-preview-install.json`). Codesign verification passed. Launch rejected by iOS security pending developer trust (`/tmp/rideform-preview-launch.json`); James given Settings → General → VPN & Device Management trust instructions. No physical launch or sampling success claimed. Charts/analysis/diagnostics are still forthcoming; preserve preview sessions during subsequent updates.

U6 worker frozen:32 core tests passed in isolated snapshot (`/tmp/rideform-u6-all.log`); authoritative shared run and independent analysis verification next. U7 dependency frontier now open. Physical mounting/sign and garage trial remain pending.

## U7 frontier and independent findings

U5 verified preview committed9738e07; U6 authoritative integrated32 core tests passed (`/tmp/rideform-u6-authoritative-core.log`) and committede993b5c. No pushes. U7 worker owns review/diagnostics and recording integration. Expanded ownership to SessionClock/privacy manifest/sensor API doc for justified fixes.

Independent U5 TSAN harness reproduced unsynchronized ClockMapping array copy race (exit134, `/tmp/rideform-u5-clock-race.swift`, `.log`). U7 fixing synchronized mapping storage/access; must rerun harness and app checks before next device update. Privacy declaration needs8FFB.1 for exported in-app event absolute timestamps alongside35F9.1 timers; official Apple wording checked. Report `docs/validation/u5-independent.md`.

Independent U6 reported master symlink-parent escape for nonexistent sidecar filename (P1), omitted even-N spectral Nyquist bin (P2), and missing segment-boundary onset uncertainty (P2). Reproducer `scripts/verify-analysis.py`, RED artifacts `/tmp/rideform-u6-independent-v151ozwg/report.json`. Scoped fix and independent GREEN needed. Main writing U8 garage/Watch documentation while U7 implements. Full finishing simplify/review gate still pending; unit commits are progress artifacts, not final shipping approval.

## Latest verification frontier

U6 fixes frozen:observed3test/9assertion RED, isolated39tests GREEN, focused16GREEN, independent10/10 PASS (`/tmp/rideform-u6-independent-rvzo5kem/report.json`). Derived algorithm now `rideform-analysis-2`; update CLAUDE notes on finalization. U7 synchronized clock TSAN100000-copy GREEN (`/tmp/rideform-u7-clock-race.log`), preliminary diagnostic core36GREEN. U8 Watch fixture1GREEN and complete portable core WatchOS10SDK typecheck GREEN (`/tmp/rideform-u8-core/`). App/end-to-end tests awaiting authoritative runtime.

Initial U7 integrated compile failed Transition ambiguity, fixed by explicit RideFormCore.Transition. Second compile failed optional sampling Double formatting at SessionReviewView93; U7 fixing. Logs `/tmp/rideform-u7-initial-build.log`, `/tmp/rideform-u7-full-tests.log`. U7 owns narrow MotionCapture fixture mode propagation and bounded existing UI test reveal updates. U8 tests frozen after explicit convention inspection fixture correction.

Unexpected concurrent changes to `Calibration.swift` and `CalibrationTests.swift` (version2, gyro threshold0.15, timedOut/new neutral handling) appeared outside all active workers' ownership. All three workers deny making them. Preserve as unidentified/user work; James asked asynchronously to coordinate. Do not commit/revert them or claim whole-worktree calibration verification until ownership resolved. Coordinator core41test run saw1movingNeutral failure in that new test (`/tmp/rideform-u6-fixes-authoritative-core.log`) while concurrent edit was in progress. Other verification continues.

Installed preview profile expires2026-10-08 15:46:09UTC (read-only CMS profile inspection); re-run Xcode with same bundle to refresh signing. Developer trust launch step remains pending without a confirmed physical launch.

## Desktop recovery and calibration usability

2026-10-01: James authorized autonomous continuation and the spoken calibration changes after the desk-test diagnosis. Old CLI task unexpectedly retained an active writer; identified by its open task lock and RideForm cwd, then stopped gracefully. All files retained. It completed analysis fix commit f16531e before shutdown. Desktop owns integration from here.

Implemented rolling neutral policy 2, bounded small-motion tolerance, early dispersion checks, spoken countdown/automatic LEFT-CENTER-FORWARD-CENTER, explicit retries/timeouts and optional recording after the success announcement. Manual mode remains. Integrated recovered review/diagnostics/export with cancellation-safe analysis and cached display traces. 41 core and 29 app tests pass; independent analysis checker green. Full evidence and remaining UI/install/review receipts: `docs/validation/calibration-desktop-update.md`. Physical calibration, audio, signs, sampling and garage acceptance remain James's gates.

Build 0.1 (2) installed over the existing app; device inventory confirms build 2. Strict bundle signature verification passed. Automatic launch returned device Locked, so James must unlock and open RideForm. Final source review completed with no outstanding findings (`docs/validation/desktop-review.json`); optional external Claude coverage unavailable due DNS failure. The earlier unidentified calibration changes were this desktop task’s changes, now explicitly adopted and verified under James’s autonomous continuation instruction.

All four UI workflows pass across final runs, including chart/filter/reopen with heading-based scrolling. Final software delivery is complete; next action is James’s mounted spoken-calibration check and the physical evidence protocol. No push.

## Build 3 return-to-center fix

James reported two waits after LEFT → CENTER. Reproduced rejection of a small offset/jitter return by the old 0.06 rad gate. Added 0.10/0.12 rad entry/exit hysteresis, preserved original neutral, clarified FORWARD next, and added a 6-second spoken reminder/15-second specific timeout. Full app suite 31/31 passed, then final calibration 11/11 plus recording UI passed after extra boundary/neutral-preservation coverage. Independent Swift review: no findings. Device build 3 signed and installed; physical reproduction/acceptance remains James’s next action. Evidence: `docs/validation/return-to-center-fix.md`.

## Build 4 audio in every calibration step

James requires no silent calibration waits. Every active stage now repeats a specific waiting instruction after four host seconds of silence while spoken guidance is enabled, independently of sensor callbacks. No overlap, sample pause or deadline reset. All 34 integration tests passed, followed by a real-timer repeating-guidance regression and the full recording UI workflow. Independent Swift review found no blockers. Signed build 4 installed and verified in device inventory; physical audio remains James’s check. Evidence: `docs/validation/calibration-audio-feedback.md`.

## Build 5 recoverable calibration and logs

Added bounded spoken retries preserving neutral and usable leans, specific terminal reasons, and separate persisted calibration logs with a Share calibration log control. The original physical rejection reason is unknown; build 4 did not retain attempt logs. 38 app tests, full log-sharing/recording UI workflow and final log-reopen check passed. Independent review finding on pending snapshots was fixed; final source review has no findings. Build 5 installed after James reconnected the iPhone; device inventory confirmed build 5 and launch succeeded. Next action: mounted attempt with log evidence. Details: `docs/validation/calibration-retries-and-logs.md`.

## Build 6 Watch companion

James authorized Watch development while away. Added the brief’s torso-mounted Watch recorder with shared capture/calibration/storage, speech and haptic cues, foreground interruption saving, basic local review and exact-archive transfer to the iPhone inbox. This does not supply a wrist remote for phone calibration. Watch integration and UI workflows passed, 40 iPhone integration tests passed, and final transfer regressions plus full iPhone UI suite passed. Independent Swift review’s staging-file leak was fixed; final review has no findings. Signed device build and deep strict signature verification passed. Build 6 is committed locally, not pushed or installed; build 5 remains on the iPhone for current calibration feedback. Evidence: `docs/validation/watch-companion.md`. Next physical steps: install on a paired Watch and test audio, off-wrist runtime, interruption save and archive receipt before mounted comparison trials.

## Build 7 final-return investigation

Phone attempt logs identified a redundant final return timeout (6–9° offset), plus two earlier sensor-convention rejections after successful center returns. Removed the final return pose gate while keeping its spoken instruction and original fitting samples. A device-only diagnostic proved the second cause: real Core Motion matrices are transposed relative to active quaternion rotation; the validator wrongly treated that as corrupt data. Fixed capture-wide representation consistency, retained gravity validation and legacy decoder support. The exact phone sample failed before and passed after correction. A second physical capture verified all 100 samples with no mismatch. Final source review has no findings; 41 core tests, 44 iPhone integration tests and Watch workflow passed. All four final iPhone UI workflows passed. Signed build 7 installed successfully and device inventory confirmed version 7. Local commit only; no push. Full mounted calibration remains James’s acceptance check. Details: `docs/validation/final-center-return.md`.

James reports capture succeeded after build 7. This confirms his calibration/capture attempt completed, not the full mounted sign/garage protocol. He cannot find the Watch app. The installed iPhone artifact contains RideFormWatch.app with matching companion identifier and build 7; both CoreDevice and Xcode currently discover the physical iPhone but no physical Watch. Watch device discovery/provisioning and installation remain outstanding.

Watch deployment completed: Xcode Device Hub pairing exposed Developer Mode; James enabled it and paired his Ultra 2. Initial integrity failure was an eligibility problem: both prior profiles listed only the iPhone. Rebuilt for the actual Watch with automatic device registration, verified Watch UDID membership and strict signature, installed build 7 and launched successfully. Device inventory confirms Watch build 7; watchOS27.2 and Developer Mode enabled. Rebuilt phone companion’s embedded Watch profile to match. Receipts: `/tmp/rideform-watch-physical-build.log`, `rideform-watch-physical-install.json`, `rideform-watch-physical-launch.json`, `rideform-watch-physical-apps.json`, and `rideform-watch-paired-phone-install.json` under `/tmp`. No source changes or new motion-validation claims.

### 2026-10-01 — Watch audio feedback and usability (build 8)

- Retrieved both short physical diagnostic masters to `/tmp/rideform-watch-feedback-data`; neither completed the 30-second stationary interval. One received phone ZIP under `/tmp/rideform-phone-watch-delivered` matched its Watch original exactly.
- Latest AirPods-attempt log in `/tmp/rideform-watch-airpods-attempt` proves full calibration success (21:07:22–21:08:03Z), despite unclear audible progression.
- Added Test audio, persistent speech diagnostics, prominent Watch stage labels and settings separation. Watch-only system-managed speech replaces per-prompt app audio-session activation; speaker audibility still requires James's check.
- Regression: held-ready-announcement audio-test interruption reproduced in `/tmp/rideform-watch8-ios-red.log`; guard passes in `/tmp/rideform-watch8-ios-green.log` (10 lifecycle tests). Watch audio-log preservation/capture/UI checks: `/tmp/rideform-watch8-final-tests.log`; final speech build checked separately in `/tmp/rideform-watch8-speech-tests.log`.
- Device builds: `/tmp/rideform-watch8-device.log`, `/tmp/rideform-watch8-phone.log`. Watch install/launch: `/tmp/rideform-watch8-install.json`, `/tmp/rideform-watch8-launch.json`. Companion install: `/tmp/rideform-watch8-phone-install.json`.
- Independent Swift review found and verified correction of the ready-announcement interruption; no remaining findings. Pending: physical speaker confirmation, a complete stationary/drill trial, off-wrist runtime and mounting/sign checks.
- James confirmed build 8 Test audio works in AirPods and accepted that output for now. Speaker playback after actual Bluetooth disconnection remains unverified. `/tmp/rideform-watch8-audio-check` contains the request/start/finish evidence (shared app session Bluetooth, volume 0.4); `/tmp/rideform-watch8-apps.json` confirms installed version 8. Final Watch suite passed 2 integration tests and 1 UI test.

### 2026-10-01 — Watch frontmost runtime trial (build 9, in progress)

James prioritizes Watch self-consistency and sustained chest-mounted collection; phone equivalence is not an acceptance gate for current use. Investigate noise/drift independently after runtime is established.

Apple documents inactive frontmost execution separately from background suspension. The Watch app incorrectly stopped on both. The real scene-handler regression failed on build 8 behavior (saved state, no new samples after inactive) in `/tmp/rideform-watch9-red.log`. Build 9 ignores inactive for stopping, records ACTIVE/INACTIVE/BACKGROUND lifecycle events, and retains interrupted save on actual backgrounding. All Watch integration/UI tests pass in `/tmp/rideform-watch9-green.log`. iPhone scene behavior is unchanged.

Settings trial: per-app Return to Clock → After 1 hour; James confirms settings ready including off-wrist preparation. Do not confuse bright display duration, Always On presentation, foreground execution and uninterrupted Core Motion delivery. Test without Xcode debugger and without polling the device during capture. Proposed physical trial: ten minutes stationary, no touch/Crown/cover-to-dismiss, then Stop & save; inspect raw timestamps and lifecycle intervals rather than the visible timer alone. If delivery stalls despite frontmost settings, this hypothesis is insufficient and supported extended runtime must be evaluated for the actual activity.
- Build 9 device builds and installs succeeded: `/tmp/rideform-watch9-device.log`, `/tmp/rideform-watch9-phone.log`, `/tmp/rideform-watch9-install.json`, `/tmp/rideform-watch9-phone-install.json`. Independent Swift review found no remaining findings. Physical trial instructions delivered; awaiting saved recording. Do not claim continuous capture verified until the master is inspected.

### Build 9 physical trial result — settings-only runtime insufficient

James returned after ten minutes and reported no Stop & save control. Retrieved `/tmp/rideform-watch9-runtime-data/Sessions/061B8AF9-5694-47D8-9D27-2B701EB6987E.rideform`: 2,405 actual motion rows spanning 24.126596 seconds. INACTIVE at host uptime 2633.484411 (~15.59 seconds after start); final receipt at 2642.061520 (~8.58 seconds later). Manifest remains incomplete; no BACKGROUND, END or finalization evidence. Do not interpret checkpoint lossCount=0 as proof of no loss after its final checkpoint.

Accessible system crash logs contain no recent RideForm report. A process (PID567) was present when inspected; bringing that same process to foreground without terminating it did not add rows/events or finalize the master (`/tmp/rideform-watch9-runtime-reopened`). These observations cannot distinguish an earlier termination/relaunch from other lifecycle/state failure. Original partial master is preserved on Watch and in the local copies. The frontmost/settings-only hypothesis failed this physical acceptance test; do not claim ten-minute collection. Next: establish actual runtime/lifecycle stop reason and evaluate a supported session appropriate to the activity; improve incomplete-session visibility/recovery on Watch.

### Runtime investigation — autonomous off-wrist probes (ongoing)

James authorized remote investigation with the Watch off wrist. Build 10 added separate launch/lifecycle journals and a DEBUG-only two-minute diagnostic launch flag. First run opened only: project Debug omitted SWIFT_ACTIVE_COMPILATION_CONDITIONS=DEBUG. The journal exposed this; corrected the build setting and added Watch UI acceptance that --runtime-probe starts capture without a tap. Build 11 probe actually captured 12,052 rows (~121.14 sensor seconds) but remained finalizing with an incomplete master and END marker. No inactive transition was observed; WKApplicationState remained active, so this does not reproduce the prior dimmed-state failure or prove ten-minute runtime. Master copied to `/tmp/rideform-runtime11-master`; journals `/tmp/rideform-runtime11-journal-late`.

Build 12 separates capture-stop callback from writer-finalize entry/completion in runtime evidence. Probe deadline now uses ContinuousClock; journal records mach_continuous_time alongside absolute uptime and wall time to avoid confusing sleep-excluding time with elapsed duration. Cancellation logs and uses sceneInterrupted to clear pending diagnostic preparation as well as stop an existing recording. Build 12 physical probe produced only 14 initial rows and no heartbeat; its journal does not establish the stop cause. System log collect requires administrator authentication unavailable noninteractively; did not change permissions or request a password.


### Build 14 — bounded runtime check prepared

Build 13 requested WKExtendedRuntimeSession with the physical-therapy category for the app's stationary guided range-of-motion exercises. Remote launch was rejected with WKExtendedRuntimeSessionErrorDomain code 3: app must be active and before applicationWillResignActive. Reported WKApplicationState=active alone is insufficient evidence of eligibility. Journal: `/tmp/rideform-runtime13-journal`.

Build 14 provides a visible “10-minute runtime check” button, starting the runtime request synchronously in user interaction. It records fused diagnostics without calibration, automatically stops after ten minutes and retains the grant through final save. Grant loss interrupts capture; failed calibration releases its grant after speech, retries reacquire it, and finalization retires probe timers with a generation guard. Separate runtime journals record grants, expiration, scene events, sensor counts and save boundaries. This is a candidate fix; a user-tap physical trial remains required. No claim of general or indefinite background riding support.

Final verification: 5 Watch integration and 2 UI tests passed (`/tmp/rideform-runtime14-final-tests.log`), 11 iPhone lifecycle/diagnostic tests passed (`/tmp/rideform-runtime14-ios-tests.log`), final signed companion build passed (`/tmp/rideform-runtime14-phone-final.log`). Independent Swift review reports no remaining findings. Original physical masters remain preserved. No push.

Build 14 installed successfully on both physical devices; receipts `/tmp/rideform-runtime14-install.json` and `/tmp/rideform-runtime14-phone-install.json`. James has been asked for the required Watch button tap; the ten-minute granted-runtime trial has not yet started or been verified.

### Build 14 physical trial — acquisition passes, save finalization fails

James tapped the runtime check; real runtime grant succeeded. After entering inactive, acquisition continued uninterrupted for 604.818 seconds: 60,273 rows at 99.653 Hz, no sample gaps or sequence breaks. Automatic stop and capture-stop callback succeeded. Finalization began but did not finish; master remains incomplete and original is preserved. Copied full 72 MB master locally. This resolves the ten-minute inactive acquisition gate for one trial, not end-to-end save or general background riding. Details and receipts: `docs/validation/watch-runtime-build14.md`. Next: diagnose finalization using the retained physical master; no need to repeat the long acquisition trial merely to reproduce save behavior.

### Build 16 save candidate — software verified, physical connection pending

Removed full-payload reload from SessionWriter.finalize; retain encoded sample timing for identical statistics instead. Watch saved receipt reads only manifest metadata. Matched physical-data replay on Mac reduced finalization1.524→0.050s and peakRSS236→93MB, with identical rows/statistics.43 core,5 Watch integration,2 Watch UI and10 iPhone persistence/export/transfer tests passed. Independent Swift review has no blockers. Temporary diagnostics removed. Hardware mechanism remains unproven; two Watch install attempts failed from lost connection, and James has been asked to wake/unlock/reconnect. Last confirmed Watch build15 is diagnostic; production16 is prepared. Details: `docs/validation/watch-save-finalization.md`. No push.
