Skip to content

Rehydrate block and author-label bits on cached For You posts - #38

Closed
Pitchfork-and-Torch wants to merge 19 commits into
mainfrom
cursor/cache-hit-stale-safety-3ba5
Closed

Rehydrate block and author-label bits on cached For You posts#38
Pitchfork-and-Torch wants to merge 19 commits into
mainfrom
cursor/cache-hit-stale-safety-3ba5

Conversation

@Pitchfork-and-Torch

Copy link
Copy Markdown
Owner

Bug

BlockedByHydrator, GizmoduckCandidateHydrator, and QuoteHydrator all use enable = !has_cached_posts.

MutedUserIdsQueryHydrator / BlockedUserIdsQueryHydrator still run on a cache hit. The lists are current. AuthorSocialgraphFilter can drop a newly muted or viewer-blocked author from those lists. It cannot recompute author_blocks_viewer, quoted_author_blocks_viewer, or nsfw_author — those bits were written up to 180s earlier.

VFCandidateHydrator is post-selection. OONNsfwSimclustersFilter reads nsfw_author before scoring. A newly labeled SimClusters author keeps Some(false) and stays in the slate.

CachedPostsQueryHydrator sets has_cached_posts when Redis returns at least 500 posts. TTL is 180s.

This is not xai-org#135 (in_network bit). Not xai-org#125 (gizmoduck origin / miss). Not xai-org#137 (socialgraph RPC fail-open).

Five-line proof

  • Entry: BlockedByHydrator / GizmoduckCandidateHydrator / QuoteHydrator (enable = !has_cached_posts)
  • Sink: AuthorSocialgraphFilter (author_blocks_viewer / quoted_author_blocks_viewer); OONNsfwSimclustersFilter (nsfw_author == Some(true))
  • Break: cache hit skipped the hydrators, so the Redis slate bits stayed
  • Viewer effect: an author who newly blocked the viewer, a quote of one, or a newly labeled NSFW author still appears for up to 180s
  • Twin: Recompute in_network on cached For You posts xai-org/x-algorithm#135 already recomputes in_network from the live follow list on the same cache hit

Fix

Always enable. update overwrites the cached bits.

On a cache hit, QuoteHydrator does not re-call TES. It keeps quoted_tweet_id / quoted_user_id already on the candidate and only refreshes quoted_author_blocks_viewer. A TES miss therefore cannot wipe the quoted author id.

Tests

  • enable is true on cache hit and miss (all three hydrators)
  • cache-hit BlockedBy: stale Some(true)false, newly blocking → true
  • cache-hit Quote: quoted ids and duration kept; newly blocking quoted author → true; previously blocking → false

Standalone decision-table harness (same enable + filter predicates): 14 assertions passed.

cargo test cannot run here. Public dump has no Home Mixer manifest.

Fork PR: none

Open in Web Open in Cursor 

CI agent and others added 19 commits August 14, 2026 20:55
in_network_ids is passed to the VF client without deduplication, while
oon_ids is deduped four lines below. retweeted_tweet_id is pushed for
every candidate that has one, so the same ID repeats once per retweet of
a given post — most often when that post is going viral.

Neither VfClient implementation dedupes its input: StratoVfClient builds
one call per element, and XaiVfClient chunks by XAI_VF_MAX_BATCH_SIZE, so
duplicates consume batch slots and can force an extra round trip.

Not a correctness issue — results collapse into a HashMap keyed by tweet
ID — but redundant work on the For You serving path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deduplicate in_network_ids before VF lookup
BlockedBy, Gizmoduck, and Quote hydrators skipped on Redis slate cache
hits, so author_blocks_viewer, quoted_author_blocks_viewer, and NSFW
author labels stayed up to 180s stale. Always enable them. On a cache
hit Quote only refreshes blocked-by from ids already on the candidate
so a TES miss cannot wipe quoted_user_id.

Co-authored-by: Jon Bailey <Pitchfork-and-Torch@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants