Every pack in the published feed was dated 2026.08.21 because that is
when I last ran the ingest by hand. The client-side update machinery
shipped in 0.1.2 works well against a source that never moves, which
means it would have kept every installation confidently green on data
that aged a day for every day that passed — and the staleness warnings
added in the same release would have started telling users the truth
about a problem we caused.
tools/refresh-definitions.sh runs the steps that already existed
(ingest-osv.py, build-pack, index.json) with the properties a published
feed needs:
- Never publishes an empty feed. If every pack fails to build it
exits non-zero and leaves the previous one live. An agent that
installed an empty feed would report a clean machine with no
indicators loaded, which is worse than one keeping yesterday's.
- Packs are written before index.json, and each lands via rename.
The index is what tells an agent a pack exists, so writing it first
would advertise files that are not there yet, and a rename means a
fetch mid-run never sees a half-written pack.
- Old packs stay on disk; the index advertises only the newest per
ecosystem. An agent that has been offline for a while still has a
URL that resolves.
- One ecosystem failing does not cost the others.
The first dry run built a pack called stage-bfsqqa-2026.08.21.pack:
the staging directory was inside the work directory, and the loop
treats every directory in there as an ecosystem. Staging now lives
outside it, and directory names are filtered as well.
The timer runs at 05:20 UTC with Persistent=true, so a builder that was
off does a catch-up rather than silently skipping a day — that being
the exact failure that produces a stale feed nobody notices. The
service runs as the publishing user rather than root: it needs the
signing key and write access to one directory, and a build pipeline
running as root to write a web directory is a bigger target than the
thing it protects.
Verified: the timer is enabled, a real run republished all six packs
and 235,577 indicators, and a client installed from the result.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>