drift
Highlights
- Full-page Playwright screenshot of every watched target on a dumb interval-based schedule — same 'deliberately dumb, not push-based' precedent as keep watch's sweep, not a webhook or CI hook
- Pixel-diffs each new capture against the most recent prior successful one (pixelmatch/pngjs); a 0.5% noise threshold absorbs font-hinting/anti-aliasing jitter without hiding a real change
- A changed dimension (redesign, viewport behavior change) is reported as 'dimensions changed,' never coerced into a fake percentage
- Targets can be added by hand or bulk-seeded straight from goonk's own project frontmatter (liveUrl/title), so there's no second list of URLs to hand-maintain
- One capture at a time, sequentially, so a slow or hanging page can't starve the rest of the queue — and a brand-new target captures immediately rather than waiting on the next tick
- No auth by default, on purpose: this only ever holds screenshots of already-public pages, not private data
Every project in this family screenshots itself once, on the day its project page gets written, and then that screenshot just sits there — increasingly wrong as the actual site keeps changing underneath it. drift exists to catch that drift, plus the sharper failure mode: a CSS regression, a broken deploy, or a dead API silently leaving a widget empty, with nothing else in the stack positioned to notice.
It’s the same shape as trace — a single Node process, node:sqlite, no framework — pointed at Playwright instead of an event log. A scheduler tick, once a day, works sequentially through whatever’s overdue relative to each target’s own interval and takes a full-page capture; each new capture is pixel-compared against the last successful one for that target, with a small noise threshold so font rendering and anti-aliasing don’t read as false alarms.
Targets are seeded straight out of goonk’s own project frontmatter, so watching a new project doesn’t mean maintaining a second URL list by hand — add a liveUrl to a project page and it’s eligible to be watched.