Files
mrambossekandClaude Fable 5 14e5fad1b2 engine: downstream MTU and downstream train in the measurement document
Three facts the client cannot produce alone, kept deliberately separate:
mtu.pmtud_down (largest datagram that arrives unfragmented — meaningful only
because the server sets DF), mtu.frag_delivery (whether larger ones arrive once
fragmentation is allowed), and train.udp_downstream (loss, reordering and
arrival spacing in the download direction, which a round trip cannot separate
from upstream loss).

ServerMeasurement now runs them on the same ProbeSession as the echo train. It
had to: a fresh session restarts client-side sequence numbers and the server's
anti-replay window discards the lot, so the re-primed source is never recorded
and every granted send goes to a socket that has already closed. That produced
four confidently-wrong FAILED tests and a RED verdict on a healthy network.

Live against fmr: path MTU 1500, fragments to 4000, 100/100 downstream, GREEN.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 10:54:38 +02:00
..

Echolot website (web/)

Minimal single-page site for echo-lot.app, served from Cloudflare Workers. Static files in public/ are served straight from the edge; the tiny Worker in src/index.js only runs for paths that aren't files:

Path Behavior
/apk 302 → newest .apk asset of the latest Gitea release (QR-code friendly)
/apk.sha256 302 → the matching .sha256 asset
/api/latest JSON {version, published_at, apk, sha256} — the homepage's version readout
/fdroid, /source 302 → the URLs configured in wrangler.jsonc vars

The latest release is resolved from the Gitea API at request time (edge-cached 5 min), so publishing a release — git tag v0.2.0 && git push origin v0.2.0, which triggers .gitea/workflows/release.yml — is the only release step. The site never needs a redeploy for a new version, and empty/unreachable values fall back to the homepage instead of 404ing.

Light/dark follows the OS (prefers-color-scheme), no toggle, no JS required for it. Colors come from the branding palette (teal = instrument, single amber point = finding).

public/assets/ (favicon, wordmark, social preview) are copies of ../assets/branding/ — that directory is the source of truth; re-copy after any branding change.

Deploy

Everything is driven by wrangler, config in wrangler.jsonc. No build step, no node_modules to commit.

One-time setup

  1. In the Cloudflare dashboard, add echo-lot.app as a zone (and point the domain's nameservers at Cloudflare). The routes in wrangler.jsonc use custom_domain: true, so wrangler creates the DNS records for echo-lot.app and www automatically on first deploy — the zone just has to exist in the same account.
  2. Auth, either flavor:
    • Interactive: npx wrangler login (opens the browser once, stores an OAuth token).

    • API token (also what CI uses): dashboard → My Profile → API Tokens → create from the "Edit Cloudflare Workers" template. Then:

      $env:CLOUDFLARE_API_TOKEN  = "..."   # PowerShell; export ... on POSIX
      $env:CLOUDFLARE_ACCOUNT_ID = "..."   # dashboard → Workers & Pages, right sidebar
      

Deploy

cd web
npx wrangler@4 deploy

That's it — uploads src/index.js + the public/ assets, wires the custom domains. Useful extras: npx wrangler dev (local preview at localhost:8787), npx wrangler tail (live logs), npx wrangler versions list.

CI deploy (Gitea Actions)

.gitea/workflows/deploy-site.yml runs wrangler deploy on every push to main/master that touches web/. It stays inert until you add two repo secrets (Settings → Actions → Secrets): CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (same values as above).

Cloudflare's raw REST API (PUT /accounts/:id/workers/scripts/...) exists, but the assets upload needs a manifest/session dance that wrangler already implements — use wrangler even in automation.

Config knobs (wrangler.jsoncvars)

  • GITEA_REPO_API — Gitea repo API base; releases must be publicly readable.
  • DOWNLOAD_URL — manual /apk fallback while Gitea is unreachable.
  • FDROID_URL — set when the F-Droid listing exists; until then /fdroid loops home.
  • SOURCE_URL — public source mirror for the footer + /source.

Vars are plain (non-secret) config; change + wrangler deploy to apply.