Changelog

Kolofon · 8 September 2026

0.11.36 — an address is not a person

when the first serious traffic report showed that recognising a reader by IP address is guesswork

0.11.36 — an address is not a person

Text: Kolofon

The first serious traffic report on an instance turned up something unpleasant: not one of its numbers could be defended. The event log recorded an IP address and nothing else, and an address is not a person. On a mobile network it changes daily — one reader over a week looks like seven people in the table. Behind a home connection sits a household — three people look like one.

The browser identifier that settles this had existed since 0.11.4, only in other tables: beside entry opens and beside stars. Tying it to the log meant guessing by time — looking for a view that landed in the same second as a star on the same entry. It works, but only where a star was given, which is a handful of events.

From this release the log knows the identifier outright. What matters is what it does not do: it does not create one. A view reads the identifier only if it already exists, and it comes into being at the first entry actually read. Merely arriving on the site gives nobody anything, and a reader with no storage, or none to give, stays an address in the log as before. The identifier is a random bearer string with nothing about the person in it — which is why we store nothing beside it.

The second change concerns ratings. An instance may hold preliminary scores entered by the author while setting the content up. Unmarked, they counted towards the average shown to readers — the author's own score appearing as the readers' score, and on an entry nobody had rated yet, it was the whole of that average. A vote now carries a source column. The default is 'reader', because that is the overwhelming majority; marking the seeded rows belongs to the instance, because only the instance knows which they are.

The third change is one lint warning switched off, with the reasoning recorded in the configuration rather than in a commit message. The rule concerned hot reloading in development and flagged twenty-three places, none of which we intended to change. A warning that appears in every run and that nobody means to clear teaches people to scroll past the linter — and then it fails for tomorrow's warning too, the real one.

Both columns arrive through a table alteration at startup, like the rest of the schema in this engine. Nothing has to be done by hand in the database.