- Stats.hs: median uses (!!) directly after the empty-case equation,
dropping the unreachable empty-fallback arm.
- Stats.hs + BibExtras.hs: switch lazy readFile to strict readFile'
(System.IO). Lazy IO leaves handles open until the value is forced;
errors surface at unpredictable points and the em-dash fallback in
Stats can hide real I/O failures. Strict reads fail at the read.
- Stability.hs: stabilityFromDates uses 'last dates' directly, since
the (newest:_) pattern guarantees non-empty input.
versionHistoryRangeField and versionHistoryRangeEndField bind the
matched list as 'es' and call 'last es', dropping the
reconstruction of (newest : more) just to call last on it.
- Tags.hs: parentOf is a 3-arm case (\[\], \[_\], segs) instead of a
length-based guard around 'init segs'.
- Catalog.hs: renderGroup re-orders so the structurally-guaranteed
(e:_) arm is matched first; the empty arm stays as a coverage stub
with a comment noting it's unreachable per groupBy's contract.
- Utils.hs: trim uses dropWhileEnd instead of double-reverse.
All sites were runtime-safe before; the changes make the safety
structural and shorter to read.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Emit a minimal robots.txt that points at the sitemap.
- Emit sitemap.xml covering every dated content page (essays, blog,
fiction, poetry, music) with absolute <loc> and frontmatter-derived
<lastmod>. Standalone pages (about, colophon, etc.) are
intentionally omitted: they're reachable via the main nav, lack
date: frontmatter, and would force a fallback lastmod that
misrepresents staleness.
- Replace the magic 'drop 8' offset in essay routing with
stripPrefix "content/". Same behavior, but reads structurally and
fails closed if the prefix ever changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the library infrastructure without visible change to the rendered
page: a 'featured:' list in each portal's tag-meta sidecar drives shelf
curation (up to 5, default cap 4, recency fills the rest), a content/
library.md snapshot feeds a '\$library-intro\$' slot for a leading
blockquote, and '\$<slug>-has-more\$' gates expose whether the unfiltered
portal overflows the shelf. Items are now loaded once and partitioned
by primary portal rather than scanned per-section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>