Make price tracking optional and off by default
Generalize copy — remove VWCE mentions
Switch poll loop to per-instance dispatched jobs
URL-pattern pre-filter: skip non-HTML extensions before page row creation
URL normalization on pages.url (strip tracking params, canonicalize)
URL submission: tighten validation (max length, reject loopback/private IPs)
UrlDiscoveredListener: add tries and failed() handler
Exclude permanently failed pages from search results
Write posted_at from fediverse post to pages row
Search page: full-text query UI and results
Add keywords_tsv column and tsvector indexing pipeline
Test environment hardening: APP_KEY override and Postgres test runs