Ascending integer bumped per deployed change; shown in the header and as
proberBuild in the JSON report so a report is attributable to an exact
build. buildConfig feature enabled for BuildConfig.VERSION_CODE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- IcmpProbe: attempt the echo on the default network AND each active
network (Network.bindSocket + per-network DNS). Run 1's ping6 EAGAIN was
topology (v6 only on cellular), not capability — now the report shows
which networks carry which family instead of a bare ERROR.
- New traceroute.udp4 (TracerouteProbe): actual UDP traceroute reading
ICMP time-exceeded via Os.recvmsg(MSG_ERRQUEUE) with cmsg parsing —
reflection per repo convention (API surface exists ~34+). If this
returns hops, the C-over-JNI shim is unnecessary on that device.
sock_extended_err layout constants documented in OsAbi.
- MulticastProbe: 10 s window; meta-query PLUS concrete types
(_http._tcp, _googlecast._tcp) — run 1 showed the meta-query alone
returning 0 on a network with live services; capture names + failure
codes as evidence.
- ShizukuProbe: ip monitor window 2s -> 5s, gateway ping in background to
provoke a NEIGH transition instead of hoping for ambient churn.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
multinetwork now SUPPORTED (wifi+cellular bound concurrently; the cellular
request surfaced a second dual-stack PDN), Shizuku battery 7/7 in 2.9s
(was 4/7 in 34s), rtt_ms locale-clean. Remaining probe improvements
(per-network ping6, longer mDNS/ip-monitor windows) noted in build-status.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- AndroidManifest: add CHANGE_NETWORK_STATE — requestNetwork threw
SecurityException, multinetwork.request_and_bind could never run.
- IcmpProbe: format rtt_ms with Locale.ROOT — Austrian locale produced
"38,1" in the JSON report.
- ShizukuRunner/ShizukuProbe: bind the UserService once per battery
(execBatch) instead of per command; the per-command bind/unbind raced
Shizuku and 3/7 commands died on SHIZUKU_BIND_TIMEOUT.
Archive the report at echolot-prober/reports/, record findings in
build-status.md. Notable: errqueue path fully reachable on Android 16 —
the native shim may be unnecessary on modern devices.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Found on the OnePlus 15 (CPH2747): rotating after a run emptied the result
list — results lived in a MainActivity field and the run in lifecycleScope,
so a config change dropped collected results and cancelled remaining probes.
Both now live in ProberViewModel (viewModelScope + application context; no
probe needs an Activity). A lost run means a lost export, so this matters
for a collection tool.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Code: GPL-3.0-or-later (LICENSE, SPDX headers on all .kt/.aidl).
Specs in docs/: CC-BY-4.0 (docs/LICENSE). Rationale in build-status.md;
server decided GPL (not AGPL).
- Root README for the public repo.
- web/: Cloudflare Worker site for echo-lot.app. /apk resolves the newest
APK from the Gitea latest-release API at request time (edge-cached 5 min),
so tagging a release is the only publish step. /fdroid, /source, and a
manual DOWNLOAD_URL fallback are wrangler vars.
- .gitea/workflows/release.yml: tag-driven (v*) signed semver APK builds for
the future production app in echolot-app/. Parked; the prober is
deliberately not CI-built.
- Fix UserService.kt: drop the explicit secondary constructor that
conflicted with the implicit primary (never compiled before — first
local build caught it). Prober now builds: :app:assembleDebug OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Monorepo root for Echolot. Contains the no-root capability prober
(Kotlin/Compose, app.echo_lot.prober) and the four design docs that act
as the contract for the production app and the Go server.
LICENSE is deliberately absent — still undecided, see docs/build-status.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>