# Watch save finalization — build 16 candidate

## Evidence and causal boundary

The build 14 physical trial persisted 60,273 motion rows over 604.818 seconds. The capture-stop callback completed; saveStarted was logged, but saveFinished was not. The manifest remained incomplete. The writer's finalize path flushed pending bytes, then called SessionIO.load to reconstruct every full sample solely to obtain timestamps for sampling statistics.

A build 15 read-only Watch replay logged reading the 72,214,803-byte motion file in 0.371 seconds, followed by no completion of its whole-file Data.split. The probe did not obtain extended runtime, so this does not establish whether memory pressure, CPU cost, or loss of execution caused that replay to stall. Live profiling twice timed out establishing its Watch connection. No OS termination or memory-limit cause is claimed.

A bounded-reader experiment reduced Mac load time but barely changed peak memory because decoded payloads were still retained. It was removed. Temporary phase logs and device-specific replay code were also removed from production source; investigation snapshots remain under /tmp.

## Change

SessionWriter retains sensor/receipt timestamps only after each successful encoding, alongside its existing accepted/written accounting. Finalization first flushes all pending bytes, computes exactly the existing sampling statistics from those timing arrays, then atomically persists the final manifest. It never reloads the motion payload. Failed writes retain timing for retry; nonfinite rejected samples never enter statistics; successful sealing releases timing. Approximately 16 bytes per accepted encoded sample are retained before array overhead, rather than constructing all payload objects at stop.

WatchSavedView now reads only the small manifest for status, count and duration. It no longer reloads and analyzes the whole master immediately after saving. Incomplete counts are explicitly labelled checkpointed. Raw originals, formats, immutable completed masters and analysis algorithms are unchanged.

## Matched replay on Mac

Both old and new writer implementations received the exact 60,273 physical motion rows with checkpoint backpressure, writing separate temporary destinations. Each decoded output row equals its source, and all stream statistics/counts match exactly.

| Measure | Before | After |
| --- | ---: | ---: |
| Finalization | 1.523942 s | 0.050156 s |
| Peak resident memory, entire replay | 235,618,304 bytes | 92,897,280 bytes |
| Entire replay elapsed | 3.07 s | 1.49 s |

These are Mac measurements, not Watch performance claims. Logs: `/tmp/rideform-writer-before-resources.log`, `/tmp/rideform-writer-after-resources.log`. Replays: `/tmp/rideform-save-replayed-before.rideform`, `/tmp/rideform-save-replayed-after.rideform`. Driver source: `/tmp/rideform-writer-replay.swift`, `/tmp/rideform-writer-replay-main.swift`. Original master remains `/tmp/rideform-runtime14-usertrial-master` and on the Watch.

## Verification and remaining gate

43 core tests pass, including a 60,000-sample finalization, exact per-stream statistics with validated clock mapping, nonfinite rejection, write failure/retry and immutable sealing (`/tmp/rideform-save15-final-core.log`). The large Mac case also passed before the change; it guards scale and correctness, not the device-only failure.

Five Watch integration and two Watch UI workflows pass, including the completed saved receipt (`/tmp/rideform-save15-final-watch.log`). Ten iPhone persistence, end-to-end, review/export and Watch-transfer tests pass (`/tmp/rideform-save16-ios.log`). Independent Swift review reports no blockers. Final production build is numbered 16 to distinguish it from diagnostic build 15.

Hardware verification remains pending: Watch install attempts failed with a tunnel connection error and timeout (`/tmp/rideform-save15-range-install.json`, `/tmp/rideform-save15-timing-install.json`). James was asked to reconnect/unlock the phone and Watch. The last confirmed Watch installation is diagnostic build 15, not this production fix. Do not claim the physical save issue resolved until build 16 is installed and a real recording reaches completed/saveFinished. No further ten-minute trial is needed merely to investigate the retained master, but an end-to-end long recording is the final acceptance check.

Final signed build succeeded at `/tmp/rideform-save16-final/Build/Products/Debug-iphoneos/RideForm.app` (embedded Watch version16). Strict deep signature verification passed with system trust-store access. Build log: `/tmp/rideform-save16-final-build.log`. Rechecking every local original-master SHA-256 matched the pre-investigation hashes. No build16 installation is claimed.
