Refresh the Flutter snapshot: v3 tickets V3-04 through V3-16, plus a fresh installable APK

V3-04 through V3-07, V3-10, V3-16 shipped complete; V3-11/V3-12/V3-14 shipped code-complete pending device/account verification; V3-08/V3-09 deferred behind a new V3-17 (self-hosted OSRM investigation). 316 tests passing, up from 221.

The APK is a fresh release build (debug-signed, no release signing config exists yet) with two build fixes applied: core library desugaring enabled for flutter_local_notifications, and sentry_flutter bumped to 9.27.0 (8.14.2's bundled Kotlin plugin was incompatible with this project's Kotlin 2.4.0 toolchain).
This commit is contained in:
2026-08-19 13:36:04 -05:00
parent 14289befb0
commit 4c634354bd
48 changed files with 4436 additions and 224 deletions

View File

@@ -0,0 +1,61 @@
# V3-13 — Real-ride measurements: elevation, battery, map lifecycle
**Phase** Quality · **Depends on** the real-ride checklist · **Size** M · **Status** Blocked on riding
## Goal
Answer three questions that no amount of code can answer, then act on the answers.
## Context
Three items have been carried since v2 because **nothing but a real ride settles them**.
Grouped into one ticket because they share a prerequisite: riding, with instruments.
## The three questions
### 1. Is elevation gain actually wrong?
~30 m of phantom gain per ten stationary minutes against **synthetic ±8 m uniform noise**.
Real GPS altitude error is *correlated* — it wanders rather than jitters — so the true
behaviour is unknown.
**Do not tune this blind.** Record a flat ride and see what it reports. Only then consider
a longer smoothing window, a larger threshold, or the barometer — which most phones have
and which is far more accurate than GPS altitude.
The port has an advantage the native app did not: `tool/parity/run.sh` proves the algorithm
is bit-identical to the Kotlin original, so any change can be measured against a known
baseline rather than guessed at.
### 2. What does it actually cost in battery?
Never measured, on either app. And V3-04/V3-05 make it worse: a lit screen and continuous
map rendering are a different order of cost from a background service.
Measure three configurations over a multi-hour ride: pocketed with no map, pocketed with
the live map on, and mounted with the screen awake.
### 3. Does the map leak?
`flutter_map`'s lifecycle was wired carefully but never leak-tested across repeated
navigation. The native repo flagged the osmdroid equivalent as a known hazard.
## Implementation
1. Run the checklist in [../port/REAL-RIDE-CHECKLIST.md](../port/REAL-RIDE-CHECKLIST.md)
2. Record elevation on a known-flat route; compare against a barometric or surveyed source
3. Battery: note the percentage at start and end for each configuration, with duration
4. Memory: navigate rides → detail → back fifty times with DevTools attached, watching
for monotonic growth
5. **Write the numbers into this file.** The point is a record, not a vibe.
## Acceptance criteria
- [ ] Flat-ride elevation gain recorded, with a verdict: acceptable or not
- [ ] Battery cost per hour recorded for all three configurations
- [ ] Memory across fifty navigations recorded, with a leak verdict
- [ ] Any resulting code change is justified by a number written down here
## Tests
Measurement, not tests. Any fix that follows gets its own regression test, and elevation
changes must be re-checked against the parity harness.
## Risks
The temptation to tune elevation on a hunch. The v2 backlog says do not, twice, and the
existing bound was already shown to pass on seed luck.
## Out of scope
Fixes themselves. This ticket produces evidence; the fixes are separate work.