CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
CI and images / frontend-build (push) Successful in 22s
CI and images / backend-lint-and-test (push) Successful in 34s
CI and images / integration (push) Successful in 2m39s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 5s
CI and images / smoke-web (push) Canceled after 0s
CI and images / promote (push) Canceled after 0s
#4392's third cause, and the only one of the three about whether a pair is SCORED AT ALL rather than how well. A drop's post_date is backdated to its first message, but FC cannot author the drop until that message has an embedding and the hourly grouper has run. So a drop created this minute lands wherever its messages were — days or weeks back in the feed. The sweep only looked at announcements published within twice the window of NOW, so by the time the drop existed its neighbours were already outside the horizon, and nothing brought the sweep back to them. Measured on the live instance: a pair scoring 0.800 with `associations: []` and an empty queue. The two scoring fixes in the previous commit would not have helped it, because nothing scored it. So the sweep now also gathers announcements sitting beside any drop whose `last_grew_at`/`downloaded_at` is inside the horizon — the drop's own clock rather than its backdated position. Capped at MAX_RECENT_DROPS so a backfill authoring thousands at once does not quietly become the full-library rescan the manual button exists for, and the id set is sorted before the loop because a sweep visiting posts in a different order each run is one whose failures cannot be reproduced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR