API-dokumentationen har fulgt med hele vejen — der er en prøve, der fejler, hvis en rute ikke står i openapi.yaml, og den fangede mig fire gange i går. Brugervejledningen har ikke fulgt med, og det er den, folk læser. Nyt: en side om beskeder — hvad der udløser en, hvorfor gentagne rettelser bliver slået sammen, push pr. apparat og mærket på ikonet. En om at åbne links i en anden browser, som mest af alt handler om, hvad en webside ikke kan: hverken se hvilke browsere der findes eller vælge mellem dem. Og en om tællingen af installationer, som ikke stod nogen steder overhovedet — en melding, der er slået til som udgangspunkt, har en pligt til at være skrevet ned, også når ingen har spurgt. Rettet: AI-siden beskrev to funktioner, hvor der nu er syv, og listen over hvad der sendes hvorhen var derfor forkert som en påstand om noget privat. Noter-siden manglede deling med en e-mailadresse og hvad `@Sofie` gør. Mail-siden manglede den anden vej ind i indbakken. Konfigurationen sagde stadig, at versionstjekket kun kunne se efter. Og tagbeskeden når nu frem. Den ER annonceringen — skrevet på produktets eget sprog til dem, der bruger det — og udgivelsen på GitHub blev fyldt med en autogenereret liste over commit-overskrifter i stedet, som er skrevet til dem, der læser koden. Nu står teksten øverst og listen under den. Linjen med linket til udgivelsen selv tages af: en side, der linker til sig selv, hjælper ingen. Dokumentationen bygges nu også på en PR. `mkdocs build --strict` fejler på et link til en side, der ikke findes, og at bygge først efter merge er at få det at vide på main. Co-Authored-By: Claude Opus 5 <[email protected]>
3.6 KiB
The install count
verdande reports that it exists. Two values, once a day:
{
"instance_id": "01a0806d-3601-7000-ad76-057f1f684881",
"version": "v0.44.1"
}
That is the whole message. No IP is stored by the collector, no hostname, no domain, no account, no counts of anything you have made, nothing about what you use it for. The payload is small enough to be printed in full on the settings page, and it is printed there — a promise about telemetry is worth exactly as much as your ability to check it.
On by default, off in one click
The alternative that was considered first was compulsory, and the argument against it is practical rather than principled: it cannot be enforced. The domain can be blocked, the binary can be patched, and a fork removes it in its first commit. So mandatory buys nothing over on-by-default while costing the trust the rest of this program works for.
Which is why the first administrator to sign in is told, unprompted, with the real id, the real version and the real address in front of them, and two buttons. On by default is only defensible if it is said out loud without being asked; a settings page where it is stated fully is not the same thing, because that page is opened by people who already suspect there is something to read.
Settings → Data afterwards: one switch. An explicit "off" survives upgrades.
!!! note "This disagrees with the update check, on purpose"
`VERDANDE_UPDATE_CHECK` is off unless you ask for it, and its reasoning is that
a self-hosted app reaching out unbidden has broken the deal its operator made by
self-hosting. That is the same situation as this one, and the two defaults do
not agree. The case for treating them differently: the update check reveals an
instance to a third party (GitHub) and returns something you can act on, while
this returns nothing and goes to the project. Whether that is a distinction or
an excuse is a judgement call, and it was made deliberately.
What the collector cannot see, and what it can
A request has a source address whether or not anybody writes it down. The collector stores none and logs none, and the code is arranged so the address never reaches a function that could — the table has nowhere to put one. But the request passes through a reverse proxy and a tunnel on the way, and those keep their own logs. "We send no IP" would be a half-truth; what is true is that nothing here records one.
The ping is not authenticated either, so anybody can post a made-up id and inflate the count. That is an accepted trade: a token would have to ship inside every install anyway.
Running your own count
Somebody running a fleet points Settings → Data → Modtagerens adresse at their
own instance, and ticks Denne instans er tælleren there. Until that is ticked,
POST /api/v1/beacon answers 404 rather than accepting quietly — an instance
nobody made a collector must not become a bucket anyone can post into.
The collector's page then shows totals, active in 7 and 30 days, and a breakdown by
version. Publishing that number at /api/v1/beacon/count is a second, separate
opt-in, and it has a floor under it (25 by default): a number that falls cannot be
published as a fact — a bad release, a DNS change that quietly stops the pings, or
lost rows all look like "fewer people use this now" — and a small number mostly says
how little it takes to move it.
When it cannot reach
The reason is written down and shown on the settings page. A beacon that cannot reach its collector otherwise fails in complete silence: it tries again tomorrow, the page says "last sent" with a date that quietly gets older, and nobody notices.