Commit Graph

34 Commits

Author SHA1 Message Date
Levi Neuwirth 7f7c029601 Marks I 2026-05-07 23:51:14 -04:00
Levi Neuwirth 0379dda908 Degrade gracefully on corrupt backlinks JSON
If data/backlinks.json fails to parse, every page that uses the
backlinks context aborts with 'fail'. The JSON is build-generated;
corruption is unlikely but not impossible (interrupted writer, disk
issue). Switch to noResult so the affected pages render without the
backlinks block instead of failing the whole build. The next clean
build regenerates the JSON.

Note: commonplace.yaml and now.yaml deliberately keep fail-fast —
they're hand-edited and silent fallbacks would mask author typos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:08:54 -04:00
Levi Neuwirth 725fa17f6a Tighten partial patterns and switch to strict file reads in build/
- 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>
2026-05-07 15:08:47 -04:00
Levi Neuwirth a818b7df9b Add robots.txt and sitemap.xml; tidy essay-route prefix-strip
- 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>
2026-05-07 15:08:33 -04:00
Levi Neuwirth 6286c82389 more prominent related pages 2026-05-03 14:01:14 -04:00
Levi Neuwirth f41311a3eb Inline code reference previews 2026-05-02 10:40:43 -04:00
Levi Neuwirth cd94227acb Spec dilemma 2026-05-01 21:22:01 -04:00
Levi Neuwirth 42ba2bf972 Current rework 2026-04-26 19:42:47 -04:00
Levi Neuwirth 6585573dae States/Context/Embeddings fixes 2026-04-26 11:22:57 -04:00
Levi Neuwirth 913a374fb2 Professional content refactor 2026-04-22 11:46:57 -04:00
Levi Neuwirth c877d8c9c6 library: sidecar-driven curation plumbing
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>
2026-04-20 21:19:36 -04:00
Levi Neuwirth 908136b646 Navigation refactor 2026-04-19 14:35:41 -04:00
Levi Neuwirth 237380c4be date data 2026-04-17 15:15:04 -04:00
Levi Neuwirth 1a532f881b major visual changes - dingbats, footer, etc 2026-04-17 12:48:22 -04:00
Levi Neuwirth acb3ae7066 visual enhancements 2026-04-15 22:25:38 -04:00
Levi Neuwirth e005380362 subdomain svg correction 2026-04-13 10:26:25 -04:00
Levi Neuwirth 41bbbd799b favicon, logo, internal popups 2026-04-12 14:57:01 -04:00
Levi Neuwirth e25a311dd9 filters + epistemic popups 2026-04-12 10:40:58 -04:00
Levi Neuwirth d113671e96 epistemic redo 2026-04-11 19:40:58 -04:00
Levi Neuwirth 1be9c7f3d1 wikilinks fix 2026-04-11 15:45:46 -04:00
Levi Neuwirth e5ed6a3bb4 library sorting 2026-04-11 15:10:48 -04:00
Levi Neuwirth 256808d2b2 sync semantic embeddings 2026-04-11 14:35:01 -04:00
Levi Neuwirth a358c8b246 audit: Haskell build system correctness + Patterns.hs + Stats blaze rewrite 2026-04-10 17:41:13 -04:00
Levi Neuwirth c864e2f9cc makefile corrections + esoteric math rendering 2026-04-05 12:00:07 -04:00
Levi Neuwirth 02b7694bfe forgejo links 2026-04-05 11:32:50 -04:00
Levi Neuwirth 9a01c602bc auto: 2026-04-05T01:18:45Z 2026-04-04 21:18:45 -04:00
Levi Neuwirth 9a3a5b62b6 type annotations for stats integers 2026-04-03 20:33:56 -04:00
Levi Neuwirth aee326bfec New page 2026-03-30 20:45:03 -04:00
Levi Neuwirth b06b1e741c popup improvements, citation fix 2026-03-29 08:02:04 -04:00
Levi Neuwirth a5495035be epistemic v2 2026-03-26 09:10:35 -04:00
Levi Neuwirth 728afd4c68 affiliation, cabal helper script 2026-03-26 08:14:50 -04:00
Levi Neuwirth 5cfbfbc0ef GPG signing, embedding pipeline, visualization filter, search timing, sig popups
- GPG page signing: dedicated signing subkey in ~/.gnupg-signing, sign-site.sh
  walks _site/**/*.html producing .sig files, preset-signing-passphrase.sh caches
  passphrase via gpg-preset-passphrase; make sign target; make deploy chains it
- Footer sig link: $url$.sig with hover popup showing ASCII armor (popups.js
  sigContent provider; .footer-sig-link bound explicitly to bypass footer exclusion)
- Public key at static/gpg/pubkey.asc
- Embedding pipeline: tools/embed.py encodes _site pages with nomic-embed-text-v1.5
  + FAISS IndexFlatIP, writes data/similar-links.json; staleness check skips when
  JSON is newer than all HTML; make build invokes via uv, skips gracefully if .venv absent
- SimilarLinks.hs: similarLinksField loads similar-links.json with Hakyll dependency
  tracking; renders Related section in page-footer.html
- uv environment: pyproject.toml + uv.lock (CPU-only torch via pytorch-cpu index)
- Visualization filter: Filters/Viz.hs runs Python scripts for .figure (SVG) and
  .visualization (Vega-Lite JSON) fenced divs; viz.js renders with monochrome config
  and MutationObserver dark-mode re-render; viz.css layout
- Search timing: #search-timing element shows elapsed ms via MutationObserver
- Build telemetry timestamps removed from git tracking (now in .gitignore)
- spec.md updated to v9; WRITING.md updated with viz, related, signing, build docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:14:49 -04:00
Levi Neuwirth 26c067147a Build telemetry 2026-03-19 15:27:12 -04:00
Levi Neuwirth 714824a0b5 initial deploy! whoop 2026-03-17 21:56:14 -04:00