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>
67 lines
3.5 KiB
Markdown
67 lines
3.5 KiB
Markdown
# Echolot — context for Claude Code
|
|
|
|
This repo is the **capability prober** for the Echolot project: an F/OSS Android app for detecting
|
|
and debugging local network issues (target audience: network engineers). The prober validates the
|
|
no-root feasibility matrix on real hardware before the production app is built.
|
|
|
|
## Project facts
|
|
|
|
- **Name:** Echolot. Domain echo-lot.app. URI scheme `echolot://`. Namespace `app.echo_lot.*`
|
|
(hyphen→underscore; appIds/packages can't contain hyphens). Prober appId: `app.echo_lot.prober`.
|
|
- **Stack:** native Kotlin + Jetpack Compose. No Flutter (all value is in platform APIs;
|
|
Flutter would be a Dart skin over a full Kotlin app + F-Droid build friction).
|
|
- **Tiers:** `app` (no root), `shizuku` (ADB-shell privileges via wireless pairing, shipped in v1),
|
|
`root` (future module). Every result records which tier produced it.
|
|
- **License:** undecided (GPLv3 vs Apache-2.0). LICENSE is a TODO before going public.
|
|
|
|
## Design docs (source of truth, in `docs/`)
|
|
|
|
- `docs/feature-catalog-and-feasibility.md` — full feature list + no-root feasibility matrix.
|
|
- `docs/measurement-schema.md` — the archived/exportable measurement JSON format (observation vs
|
|
finding separation, two-clock rule, columnar trains, anonymization types).
|
|
- `docs/probe-protocol.md` — client↔server wire protocol (pinned-TLS control plane, binary UDP data
|
|
plane with anti-amplification HMAC, STUN, canary DNS reference records).
|
|
- `docs/build-status.md` — running log of decisions, what is delivered, and the next steps.
|
|
|
|
The three specs are draft-complete and user-reviewed; treat them as the contract. `build-status.md`
|
|
is the mutable one — update it as work lands.
|
|
|
|
Keep prober result IDs aligned with the measurement-schema test-type registry.
|
|
|
|
## Layout
|
|
|
|
Monorepo. The prober is one deliverable; the Go server and the production app land as siblings.
|
|
|
|
```
|
|
docs/ design docs (above) — apply repo-wide, not just to the prober
|
|
echolot-prober/ the capability prober (self-contained Gradle build)
|
|
app/src/main/java/app/echo_lot/prober/
|
|
MainActivity.kt Compose host, runs probes sequentially
|
|
probe/ Probe interface + all app-tier probes + OS ABI helper
|
|
shizuku/ AIDL UserService + ShizukuRunner (shell command exec)
|
|
export/Report.kt JSON report + share intent
|
|
ui/ProberScreen.kt result cards colored by verdict
|
|
```
|
|
|
|
## Conventions
|
|
|
|
- Every probe returns a `ProbeResult` — never throws to the caller (MainActivity wraps anyway).
|
|
- Uncertain OS API paths (getsockoptInt, recvmsg, nat64Prefix) are reached via reflection/runCatching
|
|
and reported, not assumed — the prober's purpose is to discover what exists.
|
|
- Hardcoded Linux sockopt ABI numbers live in `OsAbi.kt` with rationale; do not "fix" them to
|
|
OsConstants names that don't exist.
|
|
|
|
## Build
|
|
|
|
From `echolot-prober/`: `./gradlew :app:assembleDebug` (needs local Android SDK; set `sdk.dir` in
|
|
`echolot-prober/local.properties`). The Gradle build is rooted there, not at the repo root.
|
|
First build downloads AGP/Compose/Shizuku from Google Maven + Maven Central.
|
|
|
|
## Likely next steps
|
|
|
|
1. Run on physical devices; collect JSON reports across Android versions/vendors.
|
|
2. If `trace.errqueue_reachable` is PARTIAL, add the C-over-JNI errqueue shim (recvmsg + cmsg parse)
|
|
as a `:native` module and a real `traceroute.udp4` probe.
|
|
3. Fold the confirmed capabilities + Shizuku dump-format samples back into the production
|
|
`core-probe` / `core-shizuku` modules.
|