feat(fediverse): fetch remote reply threads (cached, stale-while-revalidate)
A local post's "From the fediverse" section only had replies that were delivered
to us; replies-to-replies living on other servers were missed. A background crawl
now pulls the AS2 replies collections of the replies we have and caches any new
ones in ap_interactions. It never runs in a page request — the view renders from
cache and a stale post triggers a background refresh for the next view. Bounded
(depth 3 / 30 fetches), polite (serial), PULL only, respects blocks + SSRF guard.
- src/services/ActivityPubService.js — crawlThread() (bounded BFS over reply
collections), collectReplyItems() (paged AS2 collection reader), and the
maybeCrawlThread() stale-while-revalidate entry (per-post TTL + in-flight lock,
timestamp in app_settings).
- src/routes/posts.js — the post view fires maybeCrawlThread(post.id) after
rendering interactions (non-blocking, gated on apEnabled).
- test/thread-crawl.test.js — entry exists, no-seed no-op, TTL gate.
Co-Authored-By: Claude <noreply@…>