Joshua Shay Kricheli NeuroSymbolic AI
v2 v1

Release · v3.14.10

Stop the URL sanitizer killing every publication…

fix(v3): stop the URL sanitizer killing every publication link

fix v3.14.10 July 25, 2026 Joshua Shay Kricheli 81277c1

Details

Every link in the v3 Selected Publications section was a dead `href="#"`, so
clicking one (e.g. arXiv under the TPP paper) only scrolled the page to the top.
27 links across all 9 publications were affected — arXiv, ACM, IEEE, OpenReview,
Code, Video, Poster, Presentation, Research Gate, Proceedings, News Article.
Cause: `v3RenderPubLinks` routed each URL through `dbSafeExternalUrl`, whose
scheme allow-list is http/https/mailto. But the renderer runs BEFORE
`applyDbLinks`, so its URLs are still unresolved `db://<key>` placeholders — the
unknown `db:` scheme collapsed to '#'. That both killed the link and hid it from
the resolver, which selects on `[href^="db://"]` and so could never repair it.
Fix: add `dbSafeLinkHref`, the placeholder-aware variant, for renderers that emit
markup before resolution. It passes a `db://` placeholder through untouched and
scheme-checks everything else exactly as before. Resolution itself is unchanged
and still sanitizes the URL it writes into the DOM, so the security property is
preserved: no unsanitized URL ever becomes a navigable href. `db://` is now a
named constant shared by the helper and the resolver's selector so they can't
drift.
Tests: `v3RenderPubLinks` must emit placeholders intact (fails on the old code
with exactly the shipped `href="#"`), plus `dbSafeLinkHref` unit coverage
including the look-alikes `db:` and `DB://`, which stay rejected.
Verified against live Supabase data with the fixed bundle injected into the
production page: 27/27 links resolve — 21 external (all target=_blank, arXiv
click opens arxiv.org, no scroll) and 6 masked to the in-tab /view.html viewer
(click renders the PDF). Clean across dark/light x desktop/mobile x weather
on/off x all four seasons.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ZejPEHvD8ombiu37aHbGY

Files changed (4)

frontend/client/tests/db-assets-core.test.mjs +27 −2
frontend/client/tests/publication-list.test.mjs +18 −0
frontend/client/ts/components/publication-list.ts +7 −3
frontend/client/ts/core/db_assets.ts +20 −2