Skip to content

Stop TES core-data misses from clearing retweet and reply ids - #94

Open
AdemVessell wants to merge 1 commit into
xai-org:mainfrom
AdemVessell:fix/tes-miss-preserve-retweet-ids
Open

Stop TES core-data misses from clearing retweet and reply ids#94
AdemVessell wants to merge 1 commit into
xai-org:mainfrom
AdemVessell:fix/tes-miss-preserve-retweet-ids

Conversation

@AdemVessell

@AdemVessell AdemVessell commented Sep 3, 2026

Copy link
Copy Markdown

Bug

Thunder and Phoenix retrieval set retweeted_tweet_id / in_reply_to_tweet_id on the candidate before TES hydration.

CoreDataCandidateHydrator treats a TES miss (Ok(None) or a missing map entry) as Ok(PostCandidate::default()). CachedHydrator caches that empty payload. update() then assigns None over the source-populated ids.

author_id was already merge-safe (if candidate.author_id == 0). The graph fields were not. CoreDataHydrationFilter keeps the candidate because author_id is never cleared, so the wiped ids reach ranking. AgeFilter derives age from the snowflake id, not core data, so it does not drop the card either.

A TES miss is not "this is not a retweet." Downstream:

  • On a TES miss, vf_candidate_hydrator.rs only submits the underlying post to VF when retweeted_tweet_id.is_some(). Wiped, that post is never visibility-filtered — bypassing AuthorBlockViewer, AuthorIsSuspended, AuthorIsDeactivated, ContainNsfwMedia, ReportedTweet, TweetIsBounced on the original. should_drop_ancillary skips its retweet check and AncillaryVFFilter keeps the candidate. The retweet card itself still reaches VF; the original does not.
  • RetweetDeduplicationFilter keys retweeted_tweet_id.unwrap_or(tweet_id), so duplicate retweets of one source post all survive
  • in-network RT/reply OON rescore is skipped
  • retweets become cold-start eligible
  • VM ranker is fed 0 instead of the source id

Fix

Keep the miss as Ok(default) so it can still be negative-cached. update() no-ops on that empty payload so Thunder/Phoenix ids survive. A real TES hit still assigns, including None, so TES remains authoritative when it says the post is not a retweet.

is_tes_miss_payload is a structural stand-in for provenance ("this payload came from a miss"). The hydrator trait is Vec<Result<C, String>>; a CacheValue enum would be cleaner but is a framework change. A real TES hit always carries author_id, so the six-way conjunction does not skip a payload that should apply.

Tests

  • Empty TES payload does not clear Thunder graph ids
  • TES success can still clear them
  • Hydrate-on-miss stays Ok (negative cache) and update_all leaves ids

The public export does not include a Home Mixer Cargo manifest, so cargo test still needs X's build environment.

Thunder/Phoenix populate retweet and reply ids before TES hydration.
A TES miss was applied as PostCandidate::default(), which wiped those
ids while leaving author_id set, so the candidate survived hydration
filtering and ranking treated retweets as originals.
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.

1 participant