This site runs on Hugo 0.167.0, built on a self-hosted Hetzner server and served through Cloudflare. Images are hosted on R2 (static.philippdubach.com) with automatic resizing and WebP conversion.

Analytics run on a privacy-friendly, self-hosted GoatCounter instance, no cookies, no fingerprinting. The newsletter is delivered through a self-hosted Listmonk. Source code lives on a self-hosted Forgejo git remote. Outbound mail flows through Resend over standard SMTP.


Updates

October 2026

Public Hugo Starter. The public starter repository includes this site’s layouts, plain CSS, shortcodes and build checks. It uses placeholder content. Tracking and newsletter signup are disabled.

Related Reading Context. Each recommended title now has a short sentence that explains its relevance to the current article. Hugo renders both from the authored link registry. Release checks verify the destination, order, context text and screen-reader reference. Existing article dates stay unchanged.

Article Design. Article titles use larger, upright type. Key takeaways and Related Reading use open layouts with thin neutral rules. Read Next and disclaimers have quieter styling. The newsletter uses a soft red band, a red Subscribe button and the heading “New essays, once a month.” The shared styles support mobile, dark mode and forced-colour settings without adding fonts or libraries.

Archive Copy Review. Reviewed the writing and project archive for filler, repeated summaries and inflated phrasing. Kept technical details, quotations, links and personal judgments. Publication and update dates remain unchanged; edited posts with Git-derived update dates now store their existing dates explicitly.

Category Summaries. Category introductions are shorter and use relevant phrases from the saved Google and Bing query reports. The summaries use plain language and retain every existing article link. Search and social descriptions use the same topic choices.

Article and Research Navigation. Existing category labels in article headers now link to their category archives. The five research commentary links display the linked essays’ titles, resolved from the canonical articles in both HTML and Markdown. Category wording, essay destinations and the writing-page filters remain unchanged.

Lab Sitemap. The lab sitemap now lists only the landing page and registered podcast pages, with one entry per canonical URL. Removed five external LinkedIn entries and duplicate podcast entries; the current sitemap contains five unique lab URLs. Outbound newsletter links remain on the landing page.

Newsletter Generator Markup. Newly generated issues reuse their existing date/title line as a styled H1 and include an escaped description and a canonical URL for the dated public archive copy. The title line retains its original inline layout. Published the same heading and metadata repairs to all seven existing public archive copies, preserving their original text, image sources and link destinations.

Search Metadata Experiment. The AI coding productivity article now uses “AI Coding Productivity: Evidence and Bottlenecks” for its search and social title, with a description of its METR, DORA and code-review discussion. A source review corrected the METR follow-up’s task-time estimates and selection effects, distinguished DORA’s 2024 and 2025 findings, and qualified the article’s general productivity claims. The headline, original publication date and recommendations are preserved; the revision is dated 4 October. This is a combined factual and metadata update, so subsequent results cannot isolate a title effect. Search providers may choose different titles and snippets; results will be compared after recrawling.

IndexNow Reliability. Notifications now compare rendered main content, titles and descriptions with the previous accepted state. Footer link changes are detected even when article dates stay the same. The server verifies public pages and the key before submission, checkpoints accepted batches, and retries failures every 15 minutes without rebuilding. An unchanged release sends nothing; acceptance does not guarantee indexing.

Internal Linking. Read Next now uses one canonical-target resolver across HTML, Markdown, RSS and JSON Feed. Builds reject missing, ambiguous, unpublished and self-referencing recommendations. The release checks also catch redirecting internal links and missing fragments, and export a link graph for editorial review. Contextual links and Related blocks were reviewed across the published archive; repeated and tangential recommendations were reduced, and the two self-links were replaced with relevant articles.

Feed Compatibility. RSS and JSON Feed now render articles with reader-friendly images, captions, links and media fallbacks, without website forms, dialogs or interactive controls. All embedded URLs are absolute, including article footnotes. Article IDs and publication dates stay unchanged. The main RSS feed is advertised on every page; Writing, Projects and category feeds match their public indexes. Feeds share the configured 25-item limit, include categories and use chronological ordering. RSS gets a content-derived update date and a compact feed icon. The edge serves the registered feed MIME types and permits browser-based readers through CORS, while retaining caching and conditional requests. A narrow Cloudflare rule skips Browser Integrity Check only for read requests and CORS preflights on the 15 public feed URLs, so generic clients such as Python’s standard-library reader can subscribe. Other paths retain the check; request logging remains enabled. The production release gate validates every generated feed. These changes follow Kevin Cox’s RSS feed recommendations.

Lighthouse Audit. Audited eleven representative pages on mobile and desktop with Lighthouse 13.5.0, including images, audio, equations and interactive components. Body images now share a width-based srcset, with sizes accounting for the reading column, sidebar and mobile gutters; smaller figures can select smaller files on desktop as well as mobile. A live sitemap check found two current category pages hidden by obsolete edge redirects. Those redirects were removed, and the release gate now rejects canonical pages that the edge would redirect.

Mobile Typography. Headings now use text-wrap: balance, with text-wrap: pretty for prose and article links. Short links such as “About Philipp →” stay together. The browser chooses the breaks at each screen width, reducing single-word final lines where supported without inserting fixed line breaks.

Theme Transition. Replaced the circular dark-mode wipe with the browser’s native View Transitions crossfade: 180 ms, ease-out. Theme changes remain immediate for reduced-motion preferences and browsers without the API. The switch thumb uses its own transition snapshot and one smooth slide, with no scaling on press. Saved preferences and the switch’s accessible state stay in sync, including during repeated clicks.

CSS Audit. Removed unused styles and redundant overrides, corrected desktop navigation and footer alignment, and fixed dark-mode printing and forced-colors menu styles. Newsletter inputs use a 16 px font to avoid automatic iPhone zoom. The model picker’s buttons and sliders now have 44 px targets and grid tracks that can shrink on narrow screens. Chromium and WebKit checks covered mobile widths, text scaling, overflow and theme switching.

Hugo 0.167.0 Upgrade. Development moved from 0.165.0 and production from 0.166.0 to the same tested release. The upstream production archive was SHA-256 verified before installation. The supported version is pinned in hugo.toml; production builds reject a different version. Route and asset comparisons, schema checks and isolated builds passed before deployment, with the previous binary retained for rollback.

Production Release Gate. The server now runs the full validation suite against each immutable candidate release before changing the live symlink. The checks cover theme resolution, menu markup, SEO and schema, layout, feeds and local assets, unit tests, and migration invariants. Node 24.19.0 runs the dependency-free gate directly. A failed check leaves the previous release serving; cache purge, IndexNow and public responses are verified after deployment. The installed builder is tracked in the repository and the runbook matches it.

September 2026

Publishing Cleanup. Pushes to Forgejo became the deployment trigger, with GitHub retained as a backup mirror. GitHub Actions, GitHub Pages, the dispatch Worker and automatic Bluesky/Twitter posting were retired. A host timer provides scheduled rebuilds; successful deployments purge the Cloudflare cache and submit recently changed URLs to IndexNow.

Hugo 0.166.0 Upgrade. Production moved to 0.166.0 after checksum and compatibility checks. Four articles received explicit slugs to preserve their existing slash-containing URLs. Canonical routes and generated redirects stayed unchanged.

May 2026

Hetzner Cutover. Apex DNS moved from GitHub Pages to a self-hosted box after a full restore-from-backup drill on a parallel staging instance. Hugo now builds on the host itself, triggered by a push webhook on the internal git remote.

Self-Hosted Stack. Reverse proxy with automated TLS, managed databases for the supporting services, nightly off-site backups to object storage with monthly integrity checks and alerts on failure. The newsletter system runs on the same box; signups dual-write so an outage on any single component doesn’t drop them.

Edge Hardening. Added Cloudflare Cache Rules for HTML, feeds, and static assets, plus rate limiting on admin login paths. The security-headers Worker was updated so origin redirects propagate cleanly through the edge instead of being silently flattened.

Cron Reliability. Scheduled rebuilds moved off GitHub Actions cron (drifts 30+ min, occasionally skips during platform incidents) onto a Cloudflare Worker that fires workflow_dispatch on a deterministic schedule. Builds still run on Actions; only the trigger moved. Cadence increased from 3× daily to every 3 hours, so max publish delay for future-dated posts dropped from ~7h to ~3h.

Hugo 0.161.1 Upgrade. Bumped from 0.157.0. Byte-identical output, zero deprecation warnings. Added a local diff harness that builds with two Hugo versions and diffs the output, used to validate the bump as a no-op. Newer Hugo internals let 8 of 9 post-render regex passes in the markdown variant template go away, one of them was actively harmful, corrupting Wikipedia URLs like Universal_Serial_Bus_\(USB\) into garbled text.

Index Redesign. Articles and projects now share the same structure: hero dropped, the featured row is the masthead (red overline, thin red rule, large headline), hairline divider, filter chips reframed as “browse the archive” rather than page nav. Featured card image now requests a 1200×630 landscape source matching the CSS aspect ratio (was getting a portrait stretched sideways, which clipped faces).

Markdown Variant Maturity. Markdown alternates now emit clean output via output-format-aware sibling shortcodes. HTML pollution never enters the markdown stream. YAML preamble parseable by every major LLM tooling SDK. Section gate dropped so /about/, /research/, /subscribe/ ship real markdown content too.

Worker Audit. Three parallel reviews (perf, reliability, security) of the Hugo site and Cloudflare Workers shipped fixes for several social-automation bugs: Bluesky’s 300-char post limit was being silently exceeded when an appended URL pushed length over budget, leaving stuck-loop posts; cron ticks could race the same article; the bluesky worker was fetching each article URL twice per post. Added a sanitizer at a Worker boundary so a downstream consumer using innerHTML can’t execute script regardless of how the rendering side is written.

Template Hardening. readnext shortcode now warns at build time when the slug doesn’t match a post, instead of silently rendering nothing. FAQ aggregation extracted to a cached partial. Homepage and projects ItemList JSON-LD capped at 20 entries (Google rich-result band). posts.json prefers .Description over .Summary to skip 86 of 87 markdown renders at build time.

Decommissioning. Removed two unused projects (a post composer and a URL shortener). Deleted source from the repo, then deleted the corresponding Pages projects and KV namespaces.

Accessibility. Sidebar wordmark aria-label now starts with the visible text per WCAG 2.5.3 (voice-control users saying “click philippdubach” can now activate it). Newsletter card meta switched to a secondary text token for 7.0:1 contrast on the pink tint (was 3.91:1, below AA).

April 2026

Agent Readiness. Shipped three coordinated changes so AI agents and content-aware crawlers can discover and consume the site through standardized protocols. Every response now carries a Link: header (RFC 8288) advertising machine-readable resources. A new /.well-known/api-catalog endpoint returns an RFC 9264 Linkset enumerating those endpoints (RFC 9727). Content negotiation works: requesting any page with Accept: text/markdown returns a markdown variant with the right Content-Type and a token-count header for LLM context-window planning. The robots.txt declares Content-Signal directives per draft-romm-aipref-contentsignals.

Worker Refactor. The security-headers Worker grew from one file into a handful of focused modules with unit-test coverage. The cache module addresses a limitation: Cloudflare’s edge cache doesn’t honor Vary: Accept by default, so the Worker uses the Cache API to keep HTML and Markdown variants isolated under the same URL. Origin fetches HTML or rewrites to a markdown variant based on the client’s Accept header.

March 2026

Hugo Upgrade. Upgraded from Hugo v0.128.0 to v0.157.0. Migrated deprecated .Site.AllPages to .Site.Pages in the sitemap template and .Site.Data to site.Data across navigation, structured data, and research templates. Removed a dead readFile security config key from hugo.toml. No breaking changes, zero deprecation warnings.

February 2026

Frontmatter Unification. Converted all 70 YAML frontmatter posts to TOML and added Key Takeaways to all 73 posts. Takeaways render as a visible summary box between the post header and content body, optimized for Generative Engine Optimization (GEO) so AI search engines can extract citation-ready passages.

Design Streamlining. Unified left-bordered aside components (key takeaways, newsletter CTA, disclaimer) to consistent 3px borders and aligned padding. Established a vertical spacing rhythm across post zones: key takeaways, content body, newsletter CTA, footer divider, related posts. Added breathing room around images (1.5rem padding). Refined key takeaways heading to 0.85rem uppercase label with square bullets.

Homepage Redesign. Rebuilt the homepage with a tabbed layout (Articles/Projects), year dividers, and thumbnail images served via Cloudflare Image Resizing. Consolidated navigation into a unified sidebar.

Security Headers Worker. Deployed a dedicated Cloudflare Worker on philippdubach.com/* that injects HSTS, CSP with frame-ancestors, COEP, COOP, and Permissions-Policy headers. GitHub Pages doesn’t process _headers files, so the Worker fills that gap. SHA-pinned all GitHub Actions and added Hugo binary checksum verification in CI.

Machine-Readable Feeds. Added JSON Feed 1.1 alongside RSS, a Posts API for programmatic access, and llms.txt/llms-full.txt for AI crawler discovery. All output formats configured in hugo.toml.

GoatCounter “Most Read” API. Built a Cloudflare Worker proxy that queries the GoatCounter API for the top 10 posts over the past 7 days. The footer’s “Most Read” section now fetches live data from this worker instead of a static list.

FAQ Section. New /faq/ section with per-category pages (Finance, AI, Tech, Economics, Medicine). Each post can define faq entries in frontmatter; Hugo aggregates them into browsable FAQ pages with FAQPage structured data for search engines.

Readnext Shortcode. Inline “Related” link to another post: {{< readnext slug="post-slug" >}}. Links are validated against live permalinks at build time.

RSS Feed Fixes. Stripped lightbox overlay elements from full-content RSS to prevent images appearing twice in feed readers. Added XSLT stylesheet for browser-friendly RSS rendering.

Cloudflare Cache Purge. GitHub Actions deployment now automatically purges the Cloudflare cache after each build.

Research Page. Dynamic /research/ page pulling publication data from data/research.yaml with SSRN links, DOIs, and structured data.

January 2026

Social Automation & AI Model Upgrade. Upgraded Workers AI model from Llama 3.1 8B to Llama 4 Scout 17B for better post generation. Added Twitter/X automation worker alongside Bluesky. AI generates neutral, non-clickbait posts with extensive banned word filtering.

UI/UX Polish. Fixed mobile footer spacing consistency. Increased homepage post spacing (3.75rem). Disclaimers now only display on individual posts, hidden on homepage. Centered related posts heading.

Content Organization. Introduced categories (Finance, AI, Medicine, Tech, Economics) and article types (Project, Commentary, Essay, Review). The current Hugo configuration generates category and tag archives; article types remain content classifications rather than a browsable /types/ taxonomy.

Disclaimer Shortcode. Six types: finance, medical, general, AI, research, gambling. Syntax: {{< disclaimer type="finance" >}}.

IndexNow Integration. Automated submissions via GitHub Actions for faster search engine discovery. Only pings recently changed URLs based on lastmod.

December 2025

Code Blocks. Syntax highlighting via Chroma with line numbers in table layout. GitHub-inspired color theme.

Newsletter System. Integrated email subscriptions via Cloudflare Workers + KV. Welcome emails via Resend.

Security & Performance Audit. Fixed multiple H1 tags per page. Hardened CSP with frame-ancestors. Added preconnect hints for external domains. Added seoTitle frontmatter for long titles.

November 2025

Shortcodes. HTML table shortcode. Lightbox support on images.

June 2025

SEO & Math. Open Graph integration for social previews. Per-post keyword management. LaTeX rendering via MathJax 3 (conditional loading).

May 2025

Full Rebuild. Migrated from hugo-blog-awesome fork to fully custom Hugo build.