How a daily report pipeline produces self-contained HTML archives — deterministic naming, zero-dependency files, auto-discovery, and a browsable timeline.
A daily report is only useful if it reliably appears, is shareable, and stays reviewable months later. The naive approach — a server that renders a page on demand — fails all three in different ways: the page is only as alive as the server, the link breaks when the deployment changes, and last month’s report is a database query away rather than a file you can point someone at. This post is the pipeline that produces the UK Gilt Daily Report: a scheduled job that turns market data into a single self-contained HTML file, named so the archive builds itself. Every design decision below exists because of one requirement — the artifact must outlive the pipeline that made it.
The pipeline is a batch job, not a service:
fetch → compute → render → publish
A batch shape matters because reports are the same every day — there is no request-time computation to justify a server. The job runs on a schedule, writes one file, and exits. The scheduled tasks post is the layer that makes the schedule trustworthy — cron timezone pinned, failures alertable, no overlapping runs.
The report is generated as one self-contained HTML file. No server-side template, no database lookups at read time, no external CSS or JS beyond a pinned, hash-verified Chart.js from a CDN. Three consequences fall out:
The trade-off worth naming: self-contained HTML files are bigger than pages — the sample is over a megabyte because it carries everything inline. That is the price of portability, and for a daily report it is trivial.
The filename is the file’s metadata, and it is load-bearing:
gilt-report-2026-08-19.html
Three rules make the archive work:
gilt-report-YYYY-MM-DD.html — sortable lexically, parseable trivially, and matching a glob. The archive page and every future consumer derive all metadata from the pattern.Because the naming is deterministic, the archive needs no registry. The listing page enumerates the folder at build time — glob for gilt-report-*.html, sort by name descending, and everything displayed (the date label, the day of week, the “Latest” badge, the report count) is derived from the filename. Publishing a report is a file copy: rename, drop in, done. No database row, no config edit, no risk of the registry and the folder drifting apart.
The same discipline applies to malformed files: anything not matching the pattern is ignored, and an unparseable date is rejected rather than rendered as a plausible-looking wrong date. The archive’s correctness comes from the filename being a contract, not a hint.
The reports do double duty. Each file is a snapshot of the market on that date — and equally a snapshot of the engine on that date: its calculation version, its layout, its feature set. Keeping every report means the evolution of the tool is visible side by side, and a piece of feedback can reference a stable link to the exact version it was about. “It was different on the 19th” is answered by opening the 19th. That property — older versions stay reachable and comparable — is what turns a daily job into a timeline, and it falls out of the naming rule for free.
Every alternative has a hidden cost. A database-backed page needs the database and the server alive forever, and “what did the report look like in June” is a migration away. A PDF is shareable but not inspectable — you cannot click a row and expand a bond’s detail. Self-contained HTML is the intersection: permanent, portable, interactive, and openable by anyone with a browser. For a report that must be both correct and provable, the artifact being a plain file is the feature.
The pipeline is deliberately small — a scheduler, a batch job, a naming convention, and a folder that enumerates itself. Each piece is replaceable, and the whole thing degrades gracefully: if the job fails, yesterday’s file is still there, still correct, still linkable. That is the property you actually want from a daily report pipeline — not a dashboard, but an archive that never lies about its history.
The /gilt-reports/ archive is the pipeline in production — a single sample report so far, with the naming and discovery already doing the work. If you’re building a daily report pipeline and want the artifact and archive design right the first time, reach out.