New essay about adding comments to the site, referencing Aaron Swartz's
advice and the tension between enjoying the quiet and wanting conversation.
Also disables the reactions widget — comments only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reads the saved theme from localStorage instead of relying on
preferred_color_scheme, which only checks the OS setting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uses GitHub Discussions (Announcements category) with pathname mapping,
lazy loading, and theme syncing with the site's dark/light mode toggle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Flask blueprints aren't used in production — engine.py with
Responder is what Fly actually runs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The /<path:path> catch-all in content_bp was swallowing /api/oembed
even with the api blueprint registered first. An explicit route on
main_bp always wins over the catch-all.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server no longer makes HTTP requests during markdown rendering. Bare URLs
render as placeholders with fallback links, and JS fetches oEmbed data
asynchronously via a new /api/oembed proxy endpoint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of maintaining a hardcoded list of oEmbed providers and endpoints,
fetch the target page and look for <link rel="alternate" type="application/json+oembed">
discovery tags. Any site with proper discovery (photos.kennethreitz.org, WordPress, etc.)
now works automatically. Includes negative caching for non-oEmbed URLs.
Also adds oEmbed embed of photos.kennethreitz.org to the photography page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrote with stronger opening, woven philosophical depth, expanded
architecture section (multi-tenant to single-tenant pivot, Alpine/JWT
to HTMX/sessions evolution), new "What the Mirror Shows" section on
the recursive loop, cross-links to related essays, and reduced em
dashes throughout.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Technical deep dive on photos.kennethreitz.org — pipeline, AI metadata,
geography, deduplication, and what happens when you make 20k photos searchable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per gi0baro's benchmarks, nginx halves dynamic throughput (1120 vs 2300 req/s)
while only marginally improving static serving. Granian's --static-path-route
serves photography and static files directly with 7-day cache headers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nginx serves photography images and static assets directly from disk,
proxies everything else to Granian with response caching. Adds gzip
compression and request buffering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>