Internet 4.0

Case study

malin.kiev.ua: a city transport site measured against the ten principles

Malyn is a town in Zhytomyr Oblast, Ukraine, north-west of Kyiv. Its stop boards and bus timetables live on malin.kiev.ua. In October 2026 we checked the site against the manifesto, principle by principle, and fixed what we could. This page says what was done, what was done half-way, and what we chose not to do.

Site: malin.kiev.ua · Code: github.com/drivling/kyiv-malyn-booking · License of the code and the data: OwnNet Source License 1.1 · Status as of 19 October 2026.

Where it started

A reviewer of this manifesto pointed at principle 5: every essential system must degrade gracefully and function without central servers. If the stop boards of malin.kiev.ua do not open without a network, a strong sentence on this site turns against its author. On 15 October 2026 the check was honest: no service worker, no app manifest, the timetable lived only in the open tab. Four stages of work later the site is different — and this page is the last stage: saying exactly what is true now.

Ten principles, honestly

Statuses: done — verified on the production site and has an address you can open; partly — the code exists, but known limits remain; n/a — the principle is about hardware.

Principle Status What it rests on
1. Digital ownership is real ownership partly The installed app and the saved timetable keep working when our server is down — and when the domain itself stops answering: the boards, the timetables and the diagram open from the browser's own cache (checked with the host stopped: smoke, “Без домену”); the whole database can be taken away as GTFS or JSON. The limits are plain: only in the browser where it was installed, for as long as that browser keeps the cache, with no updates and no live data. The domain and the hosting are still ours.
2. Devices must work without permission n/a There is no hardware. The transport section needs no account and installs from the browser without an app store: Chrome's own banner on Android, a three-step card on iPhone.
3. Software is infrastructure done Open standards all the way: GTFS Static (MobilityData validator: 0 errors), OpenAPI 3.1 with a help page, RSS, iCalendar per route (example), HTTP caching with ETag.
4. Data belongs to the individual done The timetable — yes: GTFS and JSON under a stated license, with a revision journal of every change. A person's own data too: on the profile page (Telegram login) one button downloads everything the site and the bot know about you as one JSON file, another erases the account (name, phone and Telegram are wiped at once, future bookings and listings withdrawn, past trips kept without a link to you); the same in the bot as /mydata and /deleteme. The planner's saved stops live only in the browser and can be saved to a file, restored or cleared without any server. What is stored and for how long — in the privacy policy.
5. Offline first done for /transport Stop boards, route timetables, the route diagram and the trip planner of /transport open without a network and without the backend after the first visit; what a person taps on the board (arrival reports, sticker scans) waits in a queue and is sent when the network returns. The map tiles, the intercity board and booking need a network — see below.
6. Interoperability is a right done The feed is submitted to Transitland and the Mobility Database (under review); stop and route ids are a published contract, and a merged stop answers with a 301 (redirect map).
7. Transparency over trust done The code of the site, the backend and the bot is public, every decision is written down (see “Documentation, honestly”), every change to the data leaves a row in the journal. The bundle carries subresource integrity (the page source shows integrity="sha384-…"), and /about#build prints the hash of the loaded build, the BUILD_ID of the service worker and the revision of the saved data — the same values anyone can read with curl -s https://malin.kiev.ua/transport-sw.js | grep BUILD_ID and at /transport/revisions.
8. Repair, modify, fork partly We do not forbid it: the repository and the data are open under OwnNet Source License 1.1, which allows repair, modification and forking on the same terms, and the repository is complete. We neither make it easier nor call for it — there is no “run your own copy” guide and none is planned; that is a decision, not a gap we intend to close.
9. Protocols over platforms done for /transport The data leaves the site through GTFS, RSS, iCal and plain HTTP — nobody needs our app or our bot to use it; the Telegram bot is one channel among several. The rideshare board still takes its source from Viber and Telegram groups, but publishes on the open web.
10. Digital sovereignty is civil sovereignty partly The database was collected by residents, not bought from a platform; the city can take the feed for free and host it itself. The hosting is rented (Railway, Cloudflare): the data and the code are portable, the infrastructure is not ours.

Where the data comes from

There was no structured timetable for Malyn. The author of the site stood at the “Prozhektor” stop and did not know which buses stop there or when the next one comes. What was public — stop names, a rough list of routes, photographed timetable sheets from the city council — was collected by hand, structured and checked on site; QR stickers on the stops now lead to the board of that stop. The story is told by the local paper: “I stood at the stop and did not know which bus to wait for” (malyn.media, 7 October 2026) and its follow-up (14 October 2026).

That hand-made database is why the license is OwnNet rather than Creative Commons: free for people, education, the city and small business; derived databases stay under the same terms; corporations and paid apps need an agreement. The price is known and accepted: Google Maps and Apple Maps do not take feeds with such terms. The bare facts — that bus 5 leaves at 7:10 — belong to nobody; the license covers the collected database, not the facts.

What works without a network, and what does not

Without internet and without our server (after one online visit, in a browser tab or in the installed app “Yak doikhaty” — “How to get there”): the stop board, the route timetable, the trip planner between stops, the route diagram. A status bar tells the truth — “No network — timetable as of …” or “Server not responding — showing the saved timetable”; when the network is back the data refreshes itself, and a new site version never breaks an open page.

Needs a network: the map background (OpenStreetMap tiles are not cached — their usage policy; the diagram replaces the map), the intercity board (rideshares, minibuses, trains are live data), booking, help, the admin area, and the very first visit. “Timetable” means the planned table as of the last sync, not the live position of buses — the site never had that.

What we deliberately did not do

  • Offline map: OpenStreetMap tiles are not cached, by their policy; the route diagram does that job.
  • Google Maps and Apple Maps: they require a license without share-alike; we kept the OwnNet terms for the hand-made database.
  • GTFS-Realtime: there is no data about where the buses are — only passengers' “the bus is here” reports on the site.
  • Intercity trips in GTFS: the feed covers the city buses only.
  • A “run your own copy” guide: the license does not forbid forking and repair and the repository is public — that is enough; we neither make it easier nor call for it.

Documentation, honestly

Each stage was run from a “recovery file” in the repository: the problem as found, the decisions with their reasons, a checklist, and the findings — including what went wrong. They are the documentation of this case: offline boards and the app, offline writes, open data and the license decision, open protocols, revision journal, verifiable build, this page. For people who want the data: transport-open-data.md.