Port Telemetry, Format, RideStatistics; add cross-language parity harness
T03 — telemetry.dart, format.dart, live_telemetry.dart, plus pure domain models (Trip/Segment/TrackPoint/RideStats) with no persistence dependency, so Drift can map to them in T08 rather than the domain depending on the database. T04 — ride_statistics.dart including ElevationAccumulator, ported structurally faithfully: moving average, reversal hysteresis, gainIncludingPending, and the finish() reconciliation against lastRaw. T07 (early, because T04 forced it) — tool/parity/ drives identical fixtures through the real Kotlin files and the Dart port, then diffs. Result: every value byte-identical, including noisy_gain=38.959594555022136 to the last digit. The sole difference is run_avg_speed, where Kotlin's 32-bit Float widens to double with artefacts Dart's binary64 does not reproduce. Documented, not papered over. That harness settled a real question. The ported elevation test failed at 50.9m against Kotlin's 35m bound, which looked like a porting bug. It was not: Kotlin's and Dart's Random(42) are different streams. On a shared LCG fixture both produce 39.0m -- which would also fail Kotlin's own bound. The native guard passes on seed luck rather than on a property of the algorithm. The Dart test now uses the shared LCG, asserts bit-equality with Kotlin, and sets its bound from measured behaviour (25 seeds spanned 24.7-46.7m). 52 tests passing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
51
tool/parity/run.sh
Executable file
51
tool/parity/run.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Cross-language parity harness (T07).
|
||||
#
|
||||
# Drives the SAME fixtures through the native Kotlin implementation and the Dart port,
|
||||
# and diffs the output. This is the port's strongest correctness guarantee: it proved the
|
||||
# elevation accumulator is bit-identical across both languages.
|
||||
#
|
||||
# Requires: kotlinc (brew install kotlin) and a JDK 17-21.
|
||||
#
|
||||
# NOTE: never redirect the build to /dev/null. A v2 sweep once returned four identical
|
||||
# results because a quoting bug corrupted the source while the compile error hid behind
|
||||
# a redirect. If every value looks suspiciously equal, suspect the harness first.
|
||||
set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
NATIVE="${RIPPR_NATIVE:-$HOME/dojo/rippr}"
|
||||
WORK="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
|
||||
if [ ! -d "$NATIVE" ]; then
|
||||
echo "Native repo not found at $NATIVE. Set RIPPR_NATIVE." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The files actually under test are copied verbatim from the native repo — never
|
||||
# reimplemented. Only the Room-annotated holders and one Telemetry constant are stubbed,
|
||||
# so the algorithm files compile without androidx or org.json on the classpath.
|
||||
cp "$NATIVE/app/src/main/java/com/rippr/geo/Geo.kt" "$WORK/"
|
||||
cp "$NATIVE/app/src/main/java/com/rippr/stats/RideStatistics.kt" "$WORK/"
|
||||
cp "$HERE/stubs.kt" "$HERE/telemetry_stub.kt" "$HERE/main.kt" "$WORK/"
|
||||
|
||||
echo "== compiling Kotlin oracle =="
|
||||
( cd "$WORK" && kotlinc Geo.kt RideStatistics.kt stubs.kt telemetry_stub.kt main.kt \
|
||||
-include-runtime -d parity.jar 2>&1 | grep -v '^warning:' || true )
|
||||
|
||||
JAVA_BIN="${JAVA_HOME:+$JAVA_HOME/bin/}java"
|
||||
"$JAVA_BIN" -jar "$WORK/parity.jar" | grep '=' | sort > "$WORK/kotlin.txt"
|
||||
|
||||
echo "== running Dart side =="
|
||||
( cd "$HERE/../.." && dart run tool/parity/probe.dart ) | grep '=' | sort > "$WORK/dart.txt"
|
||||
|
||||
echo "== diff =="
|
||||
if diff -u "$WORK/kotlin.txt" "$WORK/dart.txt"; then
|
||||
echo "PARITY OK - byte-identical on every key"
|
||||
else
|
||||
echo
|
||||
echo "Differences above. Expected and accepted: run_avg_speed and any other"
|
||||
echo "speed-derived value, where Kotlin's 32-bit Float widens to double with"
|
||||
echo "artefacts Dart's uniform binary64 does not reproduce. Anything else is a bug."
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user