"me-web?" 0.7.0: the name in quotes, copy buttons, and every translation rewritten in plain words
Build / Desktop, server and tools (push) Successful in 1m19s
Release / Every platform, the server, the release (push) Successful in 9m34s

- The name is now always written in quotation marks, each language with its own: “me-web?”, «me-web?», „me-web?“, « me-web? », 「me-web?」. Without them the question mark read as the end of a sentence. In Arabic, Hebrew and the other right-to-left languages the question mark no longer jumps to the wrong side of the name.
- Your addresses, your router, your network, the reverse name, the route and the code of a submission you sent now sit in a small box with a copy button, ready to paste into a message to your provider or anywhere else.
- Every translation except English and Italian was rewritten for people who are not technical: everyday words first, the technical term in brackets, and one word for one thing across the whole app. They are still machine drafts; "Suggest a correction" is welcome in any language.
- A few lines are plainer in English and Italian too: the test servers for calls, and the server in the middle that carries a call when two homes can't connect directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-15 22:49:40 +02:00
1 parent d18caed157
commit 320936c688
260 files changed
+23662 -18072

No files matched your search

+15 -12
View File
@@ -18,6 +18,7 @@ dotnet run tools/strings.cs -- check # every language agai
dotnet run tools/strings.cs -- set Key values.json # one key, every language at once
dotnet run tools/strings.cs -- merge keys.json # many keys: {"Key": {"en": "…", "it": "…"}}
dotnet run tools/strings.cs -- import fr fr.json # one language's drafts: {"Key": "…"}
dotnet run tools/strings.cs -- quote # put every “me-web?” between its language's quotation marks
dotnet run tools/knowledge.cs # provider map -> artifacts/knowledge/ip2asn.bin
dotnet run tools/languages.cs # regenerate data/languages.json from CLDR
dotnet publish src/MeWeb.Desktop -c Release -r win-x64 --self-contained -p:PublishSingleFile=true \
@@ -65,7 +66,8 @@ The Android release key: alias `meweb`, certificate SHA-256
| `src/MeWeb.Desktop` | desktop head (`meweb` executable), Windows manifest |
| `src/MeWeb.Android` | Android head (`software.arasaka.meweb`), resources, manifest |
| `src/MeWeb.Server` | `meweb.arasaka.software`: `/api/info`, `/api/ip`, the download page `/` and `/privacy` (en, it), `/download/{platform}` from the latest Gitea release, the probe (`/api/probe/ticket`, `/api/probe/{id}`) and shared findings (`/api/share`, files under `/var/lib/meweb/shares`, swept after `KeepDays`) |
| `data/languages.json` | 113 languages: code, autonym, English name, `rtl`, `reviewed` or `draft` |
| `data/languages.json` | 113 languages: code, autonym, English name, `rtl`, `reviewed` or `draft`, and `quotes`, the language's own quotation marks from CLDR (fixed by hand where CLDR has none or is wrong) |
| `data/glossary/<code>.json` | per language, the plain words chosen for about forty recurring ideas (provider, router, port, name server, …), so a card never calls one thing by two names; written with the translations and read by whoever reviews them |
| `data/isps/*.json` | provider profiles: AS numbers, and per fact a value, who said it (`basis`), the source URL and the month |
| `data/observed.json` | notes counted from shared findings and accepted by a person: per AS number and line (`home`, `mobile`), IPv4 shared or public, IPv6 offered or not, port 25, each with how many networks agree; embedded in every release |
| `src/MeWeb.Server/ObservedNotes.cs` | every six hours (with the share sweep) counts the shared findings into `/var/lib/meweb/observed.json` on the box: one vote per /24 or /48, the latest check of each network, the publisher's own network left out; nothing is served |
@@ -95,7 +97,7 @@ The Android release key: alias `meweb`, certificate SHA-256
- **Ask the outside STUN server first.** When `stun.meweb` is the caller's own public address (the owner's line), the
first binding hairpins inside the FRITZ!Box with the port preserved and the next destination reuses that mapping,
so the order `stun.nextcloud.com` then `stun.meweb` is what reads a symmetric NAT as hard.
- **Shared findings are files, not Mongo.** The box's Mongo has auth on and me-web? has no user there; a file per
- **Shared findings are files, not Mongo.** The box's Mongo has auth on and “me-web?” has no user there; a file per
submission under the unit's `StateDirectory`, with only the delete token's SHA-256, needs no credentials.
- **An address inside right-to-left text reorders around `→`.** `Texts.Isolate` wraps every literal value in U+2068/U+2069.
- **On mobile data there is no router of the user's.** Android reports a gateway for the cellular link, so
@@ -113,15 +115,6 @@ The Android release key: alias `meweb`, certificate SHA-256
- **The route is drawn, never trusted.** `Route.Trace` (8 TTLs) feeds the path's wires: hops after the first, up to
the first public one, sit before the shared exit or the provider; public ones carry their AS number into the
internet; unanswered runs collapse to "…". The NAT verdict never reads them (see the 100.64 pitfall).
- **A measuring node is the same server with `Site__Node=true`.** It answers `/api/info`, `/api/ip`, the probe and the
speed test; the page, privacy and downloads redirect to `meweb.arasaka.software`, shares and network data answer
404. The app times every entry of `Endpoints.Nodes` against `Endpoints.Main` (three TCP connects each) and uses the
closest for the speed test and the outside test only if it is under 70% of the main server's time; echo, STUN,
shares and updates stay on the main server. `Endpoints.Nodes` is empty until a machine exists. Adding one is a
release, never a config change, because the app must name every host it contacts: the `Endpoints.Nodes` entry
(place, `{id}.meweb`, `v4.{id}.meweb`, `v6.{id}.meweb`, the hosting company), a paragraph in `PrivacyPage.cs` in
both languages naming the host and its country, DNS through the portal, and on the node `Knowledge__Enabled=false`
and `Probe__Refuse` set to the node's own addresses.
- **A note from shared findings never ships without a person.** The consent screen and the privacy page promise
"only totals without addresses, after a person has reviewed them, from at least five networks agreeing four in
five"; `ObservedFact.Ready` is that rule, `tools/observed.cs accept` the review. Hand-written profile facts win over
@@ -165,9 +158,19 @@ The Android release key: alias `meweb`, certificate SHA-256
the central 66 of 108 units around its smallest enclosing circle; a change to the drawing goes into all three files.
The plain `mipmap-xxxhdpi/icon.png` is only for Android 7.x.
- **Release notes are the commits since the previous tag.** `tools/release.cs` writes "What's new" from each
commit's subject (without the `me-web? x.y:` prefix) and body, dropping trailers and any line that mentions Claude;
commit's subject (without the `"me-web?" x.y:` prefix, quoted or not) and body, dropping trailers and any line that mentions Claude;
the release step needs `fetch-depth: 0` for the tags. So a commit body is written for the people who download the
release: plain words, one bullet per change they would notice.
- **The name is always quoted, in each language's own marks.** “me-web?” in English, «me-web?» in Italian, „me-web?“
in German, « me-web? » (no-break spaces) in French, 「me-web?」 in Japanese: unquoted, the question mark reads as the
end of a sentence ("What me-web? found"). `tools/strings.cs check` fails on a bare name; `AppName` is the title. In
right-to-left languages the `Localizer` wraps the name in U+2066/U+2069 (left-to-right isolate), the English fallback
included: without it Avalonia lays out ”me-web?“ alone on a line as `me-web?”“`, and inside a sentence the `?`
jumps to the other end of the name. A left-to-right mark after the name was tried and does not fix the lone title.
- **Values worth copying are read-only text boxes with a copy button inside** (`Views/CopyField`): addresses, the
router, the network, the reverse name, the route, the STUN answers and a submission's code. The box is
left-to-right in every language and copies the raw value, never the bidi marks `Texts.Isolate` adds to display
text. Which facts get one is the `Copyable` list in `FactViewModel`.
- **The macOS apphost is ad-hoc signed by the .NET 10 SDK even on Linux** (`LC_CODE_SIGNATURE` present); Apple
Silicon refuses unsigned arm64 code, so never strip it.
- **The Windows single-file publish drops native `.pdb` files beside the exe**; only `meweb.exe` ships.