Files
echolot/docs/build-status.md
T
mrambossekandClaude Opus 5 d3e35ecead Add branding: Focus mark, wordmark, banner, social preview
- assets/branding/: icon (SVG + 512px PNG for Gitea avatar), adaptive-icon
  foreground/background layers, path-only wordmark for dark/light grounds,
  1200x300 README banner, 1280x640 social preview (SVG + PNG)
- README: banner hero
- build-status: branding decision log (includes the pending website section
  from the parallel web/ session, interleaved in the same file)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 10:52:12 +02:00

4.9 KiB
Raw Blame History

Echolot — build status & next steps

Last updated: 2026-07-29.

Decided

  • Name Echolot; domain echo-lot.app; 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.
  • Tiers: app (no root), shizuku in v1 (wireless-ADB pairing), root future.
  • License (decided 2026-07-30): all code GPL-3.0-or-later; the specs in docs/ CC-BY-4.0. Rationale: the moat is the no-root platform research, which is trivially liftable into a proprietary repackage — copyleft is the only option that prevents that, and the F-Droid / network-engineer audience reads GPL as a trust signal rather than friction. The specs go permissive on purpose: a wire protocol only becomes a standard if anyone can implement it. Not AGPL for the server — the ASP loophole it closes is speculative here, while blanket corporate AGPL bans would hit exactly the enterprise network teams most likely to self-host. Sole copyright holder, so relicensing the server to AGPL later stays possible. Open: substitute a real legal copyright holder for "Echolot contributors" in the SPDX headers.

Specs (in docs/, alongside this file)

  • feature-catalog-and-feasibility.md, measurement-schema.md, probe-protocol.md. Considered draft-complete and reviewed by the user.

Capability prober — DELIVERED (as zip, 2026-07-29)

Full Kotlin/Compose project scaffolded: app.echo_lot.prober, minSdk 26 / target+compile 35, AGP 8.7.3, Kotlin 2.0.21, Compose BOM 2024.10, Shizuku api+provider 13.1.5, kotlinx-serialization. Probes implemented: link.snapshot, icmp.ping4/6 (unprivileged ICMP datagram), sockopt.matrix (TTL/TOS/RECVERR/MTU_DISCOVER), trace.errqueue_reachable, multinetwork.request_and_bind, local.mdns_discover, peer.ble_advertise, shizuku.command_battery (ip neigh / ip -6 route / ip addr / ip monitor / dumpsys network_stack DHCP+IpClient / dumpsys wifi). JSON export via share intent; results carry verdict + raw evidence.

Could NOT be compiled in the cloud sandbox: dl.google.com (Google Maven) and services.gradle.org are proxy-blocked, and no device is reachable for on-device runs. Build + iterate locally (Android Studio / Claude Code). Wrapper is pinned to Gradle 8.14.3.

Website — web/ (2026-07-30)

Single-page site for echo-lot.app on Cloudflare Workers: static public/ from the edge, a small Worker for the stable short URLs (/apk, /apk.sha256, /fdroid, /source) and /api/latest. Version info is resolved from the Gitea releases API at request time (edge-cached 5 min), so tagging a release is the only publish step — the homepage shows the latest version/date/size via progressive-enhancement JS and falls back to pre-release copy otherwise. Auto light/dark via prefers-color-scheme: dark = sonar display, light = chart-recorder printout, same amber-accent token system. Deploy: npx wrangler deploy from web/, or CI via .gitea/workflows/deploy-site.yml (needs CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID secrets); full story in web/README.md. Open: favicon/wordmark are placeholders until the branding assets land (in progress in a parallel session).

Branding — assets/branding/ (2026-07-30)

Identity chosen: the Focus mark — a quiet lattice of nodes with exactly one under examination (amber) inside teal viewfinder brackets. Tone is surgical measurement, not scanning (sonar-sweep visuals and the "sound out your network" tagline were explicitly rejected); tagline is "measure, don't guess". Palette: abyss #071522, tile #0E2433, instrument teal #35E0C4, finding amber #FFB454, foam #E8F4F2 — teal is always the instrument, the single amber point is the finding. The wordmark is hand-drawn monoline SVG paths (zero font dependency); the second "o" is the signature teal ring + amber ping. Assets: icon.svg (+ icon.png 512² — Gitea avatars reject SVG), icon-adaptive-{foreground,background}.svg (108dp adaptive-icon layers, art inside the 66dp safe circle), wordmark-on-{dark,light}.svg, banner.svg (1200×300, wired into the repo README), social-preview.svg/.png (1280×640, for the Gitea/GitHub social-preview slot). The website's placeholder favicon/wordmark can now be replaced from these.

Next steps

  1. Build locally, run on several physical devices (varied Android versions/vendors), collect the JSON reports — especially the real per-device Shizuku dump formats.
  2. If trace.errqueue_reachable = PARTIAL, add a C-over-JNI errqueue shim (recvmsg+cmsg parse) as a :native module and a real traceroute.udp4 probe.
  3. Start the Go server skeleton (enrollment + profile + sessions + UDP echo with observation blocks + canary-DNS reference records) per probe-protocol.md.
  4. Fold confirmed capabilities into the production core-probe / core-shizuku modules.