Skip to content

v0.2.0 — the dashboard shows the whole engine

Choose a tag to compare

@Vitrus-Dev Vitrus-Dev released this 16 Sep 12:21
· 12 commits to main since this release

The first tagged release. 0.1.0 was the initial publication of the core and was never tagged; this is the same engine with a schema fix, a dashboard that shows all of it, and a fourth build gate.

Fixed — upgrading a self-hosted database could break adding a site

sites.privacy_mode was added to the schema after the table first shipped. CREATE TABLE IF NOT EXISTS is a no-op on a table that already exists — it does not reconcile columns — so the column was present on every fresh install and on none of the upgraded ones. The gap only surfaced on write, as an opaque 500 internal_error with nothing in the UI to explain it.

If you self-host and installed before that column existed, adding a site has been failing. Upgrading to 0.2.0 fixes it on the next start: SqliteStore.init() now checks PRAGMA table_info and adds missing columns explicitly. No data is touched — the existing rows keep their values and get the default.

Four tests build a pre-column database and pin the behaviour, including a double init() so a restart cannot crash on boot.

The self-hosted dashboard now shows the whole engine

It rendered six cards and the digest. The engine had always computed far more, and the documentation said so — which made "no metric is held back from this repository" look false to anyone who actually checked. Only the screen was missing.

Now on the page, each with the evidence control it always had:

  • Performance — Core Web Vitals at p75, slowest pages
  • Errors — grouped by message and page, and by browser and OS
  • Traffic — top, entry and exit pages, channels, referrers, UTM campaigns
  • AI — AI sources, their landing pages, and which of your pages AI crawlers read
  • Behaviour — custom events, field-level form abandonment
  • Audience — country, device, browser, OS, language, screen

The section list is derived from the bundle at runtime, so a metric added to metrics/queries.ts appears without anyone remembering to update the page, and a metric no section claims renders under More rather than vanishing.

New gate: gate:inline-js

The dashboard's JavaScript is generated inside a TypeScript template literal. One mis-escaped quote kills the entire script while the page still renders perfectly — no error, no console trace, nothing works. Every text-matching test passes, because the text is in the HTML.

The gate parses every inline script instead of searching it. It caught a real mismatched quote while this release was being written.

README

  • A dashboard preview, generated rather than screenshotted. A screenshot goes stale the first time a label moves and nobody notices for months — and a screenshot full of invented numbers presented as real would be the worst possible advertisement for a product whose argument is that numbers should carry their evidence. The word "illustration" is inside the artwork, not in a caption that a re-screenshot would crop away.
  • A dated comparison against GA4, Plausible, Umami, Rybbit and Databuddy — including the rows where each of them is the better choice, and a note that they all classify AI assistants as a channel. The narrower thing we are claiming is separating the crawler that read you from the human it sent.
  • A table of contents, community links, and correct test counts.

The table is deliberately short: it lists only differences that can be stated without qualification. An earlier draft claimed Umami had no MCP server; checking found their official one. A half-verified cell is exactly the kind of claim this project exists to stop making.

Upgrading

git pull && bun install && bun run build:tracker

Schema migrations run on start. Nothing else to do.


198 tests, two golden-set evals and four gates, as one command: bun run gates.