mrambossekandClaude Fable 5 3333788d9e
server-release / image (push) Successful in 15s
server-test / test (push) Successful in 32s
server-release / release (push) Successful in 32s
throughput: paced downstream rate, with the qualifier that makes it honest
A throughput number reports the smallest limit on the path, and the sender's own
ceiling is one of the candidates. If the server was asked for 50 Mbps and 50
Mbps arrived, the network was never the constraint and "50 Mbps" says nothing
about it. So the result always carries limited_by and measures_network, and a
finding is raised only when the path is actually implicated.

Loss is computed against the *sender's* count, not the requested rate: the
server reports what it put on the wire, and the gap is the loss. A receiver
alone cannot tell "the network dropped it" from "the sender never sent it", and
guessing turns a healthy server-side limit into a phantom network fault. The
count is stored per action, not per packet — half a million packets of structs
would turn a measurement into memory exhaustion.

Sending is paced rather than flat out. An unpaced burst measures the server's
NIC and the first queue it meets, then collapses into loss that reads as a
network fault. The schedule is absolute rather than sleep-per-packet, which
would accumulate scheduler error and drift the rate down over a ten-second run.

Throughput gets its own grant budget sized from the request, so every other
action stays bounded at 8 MiB. When the byte cap binds before the clock does,
the *duration* is shortened and reported, rather than the run being truncated
halfway: promising thirty seconds and delivering twenty-one is the same
information with a surprise attached, and it keeps "the clock ended the run" as
the normal case — the only case where the rate is a clean property of the path.

That last behaviour came out of a test that failed honestly: 30 s at 100 Mbps
needs 375 MB against a 256 MB cap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 14:05:23 +02:00

echolot — measure, don't guess

Echolot

Free software for detecting and debugging local network issues from an Android phone — built for people who actually know what a neighbor table is.

Most "wifi analyzer" apps show you signal bars. Echolot aims at the layer where home and office networks actually break: duplicate DHCP servers, broken IPv6 RAs, MTU black holes, NAT64 weirdness, multicast that dies at the AP, DNS that answers differently than it should. It records what it observed, separates observation from interpretation, and exports the whole run so you can argue with it later.

Status: pre-release. The capability prober runs on real hardware; the production app and the probe server are not built yet.

Repository layout

docs/              design docs — the contract for everything below
echolot-prober/    capability prober: validates the no-root feasibility matrix on real devices

The Go probe server and the production app land here as siblings.

Design docs

The three specs are draft-complete and reviewed; treat them as the contract.

Doc What it defines
docs/feature-catalog-and-feasibility.md Full feature list + the no-root feasibility matrix
docs/measurement-schema.md Archived/exportable measurement JSON (observation vs finding, two-clock rule, anonymization)
docs/probe-protocol.md Client↔server wire protocol (pinned TLS control plane, binary UDP data plane, STUN, canary DNS)
docs/build-status.md Running log of decisions and next steps

Privilege tiers

Every result records which tier produced it:

  • app — no root, no special setup. The bulk of the functionality.
  • shizuku — ADB-shell privileges via wireless pairing, no root. Shipped in v1.
  • root — future optional module.

Licensing

Part License Why
All code (app, prober, server) GPL-3.0-or-later The value here is the platform-API research; copyleft keeps derivative apps free
docs/ (the specs) CC-BY-4.0 A wire protocol and a measurement format should be implementable by anyone, without license anxiety

Full texts: LICENSE (GPLv3) and docs/LICENSE (CC BY 4.0). Sources carry SPDX-License-Identifier headers.

If you want to build a compatible server or client, the protocol and schema docs are deliberately permissive — go ahead.

Building

See echolot-prober/README.md. Short version, from echolot-prober/:

echo "sdk.dir=/path/to/Android/sdk" > local.properties
./gradlew :app:assembleDebug
S
Description
No description provided
Readme GPL-3.0
1.3 MiB
2026-08-02 14:58:41 +02:00
Languages
Kotlin 61.6%
Go 36.2%
HTML 1%
Shell 0.5%
Python 0.4%
Other 0.2%