Files
echolot/echolot-app
mrambossekandClaude Opus 5 4aaaa5f5d4 app: probe the server this device is enrolled with, not ours
The canary-DNS zone and the STUN host were compiled in as c.echo-lot.app
and fmr-1.echo-lot.app, so every copy of the app measured against this
particular deployment whatever server its owner had enrolled with. On
someone else's install those two tests describe our infrastructure and
report the result as a fact about their network.

The zone comes from the server's own profile, which has advertised
canary_zone all along — the app simply never read it. It is cached in
settings because the canary probe runs at device tier, before anything
has contacted the control plane, and a probe that had to make a call
first would fail on exactly the networks worth measuring. The STUN host
is derived from the configured server URL rather than stored, since a
second copy of the server's name goes stale the moment someone
re-enrolls elsewhere.

With no server configured both now report SKIPPED. StunProbe previously
would have reported FAILED on a blank host, which reads as a finding
about the network when the truth is that no packet was ever sent — the
same conflation between "measured nothing" and "measured a fault" that
the ICMPv6 finding had.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 23:20:52 +02:00
..

Echolot app

The production Android client (spec). Native Kotlin + Jetpack Compose. Multi-module; built bottom-up from a verifiable protocol spine.

Modules

Module Type Status
core-protocol pure Kotlin/JVM done — client half of probe-protocol.md, verified live against the server
core-measurement pure Kotlin/JVM planned — measurement-schema.md types
core-probe Android lib planned — app-tier probes, ported from echolot-prober
core-shizuku Android lib planned — dual-path executor (UserService + newProcess fallback)
app Android app planned — Compose UI

core-protocol is deliberately Android-free so it builds and unit-tests on any JDK (no Android SDK) and can run integration tests against a live server.

core-protocol

Implements the control plane (SPKI-pinned enrollment/profile/sessions via HttpsURLConnection — Android-API-1 compatible, hostname verification off because trust is the pin), the HKDF-SHA256 session-key schedule, and the binary ELT1 UDP data plane (HMAC gate, ECHO + observation block, MTU probe) — byte-compatible with the Go server.

./gradlew :core-protocol:test              # unit tests (crypto vectors, wire round-trip)
scripts/test-fmr.sh                         # live end-to-end test against the deployed server

test-fmr.sh mints an enrollment token over SSH, enrolls via the public control plane, computes the SPKI pin from the served cert, and runs LiveServerTest — proving the client speaks the wire protocol to the real server (enroll → profile → session → echo+observation → MTU → observations). The live test self-skips when ECHOLOT_LIVE_* env vars are absent, so unit runs and CI stay green offline.