◂ 일일 리포트2026-08-29 빌드
FEED RESEARCH · 일일 리포트

2026-08-27

목요일 · 읽는 데 약 44분
  • 읽은 자료 4
  • 정본 반영 2개 파일(services/x.md, radar.md)
  • 레이더 2
한 줄 요약X 4세대+8번째 드랍(0d3cdd8, 2026-08-25, +5,850/−586, 파일 47) — abuse-enforcement-service generic_actions 패스스루 신설(663줄 신규 + growthbook 동적 allowlist +126) + panda_reports_embedding_v10_rough_spam 신규 검출기 유입 + VM Ranker 경로 대폭 단순화 (author_diversity 값 모델 삭제 → dpp 서버 측 다양성으로, ranking_scorer::effective_head_weights 88줄·MPN 폴드백 128줄 제거) + Following 파이프라인 블록 관계 확장 (FollowingBlockedByHydrator 신규 + AuthorSocialgraphFilter 신설, 인용·리트윗 저자가 뷰어를 블록한 경우도 필터링) + Brazil2026ElectionFilter 계정 리스트 갱신(2026-08-25 기준, +3,379줄, TSE dadosabertos 원본 반영) + phoenix-rankall prefloor 스냅샷 배선(min_age 있는 window에 대해 prefloor_<window>.parquet 동시 로드) + Phoenix copy_port tokio::spawn 하드닝(rate-limit이 병렬 폴링 없이도 in-flight cap을 지키게, 회귀 테스트 2개 신규). Meta·Netflix 신규 없음. arXiv cs.IR triage에서 WeChat/Tencent Tlow (flow-based item tokenizer, 프로덕션 CTR +10.32% 글로벌·+11.64% 신규 아이템) + TAGR (익명 대형 live-stream 광고 플랫폼, revenue +16.1%) 2건 통과.

1. X 4세대+8 드랍 — AES 일반 액션 패스스루 + VM Ranker 대폭 단순화 + Following 블록 확장 + Brazil 계정 갱신 + prefloor 스냅샷 + copy_port 하드닝

자료 xai-org/x-algorithm@0d3cdd8 — 2026-08-25T23:20:04Z 커밋(파일 47, +5,850/−586). 커밋 메시지는 세대 시리즈 관행대로 "Open-source X Recommendation Algorithm" 한 줄이라 커밋 내용은 파일 diff로만 판독. 이번 드랍은 규모(5,850줄)로는 4세대+4(+3,303) 이후 가장 크지만 그 중 3,379줄은 Brazil 2026 election 필터의 계정 데이터 갱신 — 코드 신규성보다는 6개 서브시스템에 나란히 배선이 들어간 폭 넓은 드랍이다.

배경 X For You 타임라인의 4세대 오픈소스 릴리스는 2026-08-13 헤드라인 드랍(47c1bcd, +363,246/−11,640) 이후 격일~매일 후속 커밋이 붙는 상태다. 이 문서 기준 아홉 번째 후속(4세대+8)이 오늘의 대상. 08-25 23:20 UTC 커밋을 어제(08-26) 배치가 놓쳤고 오늘 27일 배치에서 캐치업. 이전 4세대+7(d011592)이 VF 검증(reference_compare)·브랜드 안전 tier 확장(HighRisk)·PTOS 심판 3카테고리로 안전 스택을 세로로 심화했다면, 이번 4세대+8은 enforcement·랭커·Following·Brazil 컴플라이언스·Phoenix rankall·Phoenix 학습 인프라 여섯 곳에 나란히 손을 댔다.

README의 표제도 바뀌었다: ## Latest Updates## Notable Updates. 그 아래 August 14th 섹션의 Brazil 항목에는 *(Account list updated August 25, 2026.)* 문구가 붙었다. 명명 변경은 "이 섹션이 항상 최신은 아니고 특기할 만한 변경 위주로 유지된다"는 의미로 해석 [추정] — 매일 후속 커밋이 붙는데 README를 매일 갱신하지 않겠다는 선언.

1-1. abuse-enforcement-service/service-lib/src/generic_actions.rs (663줄 신규) — 스코어러가 직접 액션을 요청하는 일반 패스스루

AES 배경 abuse-enforcement-service/ (AES)는 4세대 헤드라인에서 처음 통째로 공개된 서브레포로, 모델 스코어(BDSM 봇 헤드, LLM slop 라벨, PandaReports 등)를 받아 실제 계정 조치(label / bounce_captcha / bounce_arkose / spam_liveness_check / suspend)로 매핑하는 규칙 엔진이다. 종전 AES 규칙은 abuse-enforcement-service/service-lib/rules/enforcement_user.yaml / enforcement_post.yaml정적으로 인코딩됐다 — 어떤 라벨이 있으면 어떤 액션을 하라는 매핑을 CEL 표현식으로 명시. 예:

- id: anchor_campaign_suspend_cse
  when: '"anchor_campaign_suspend_cse" in score.labels'
  then: { kind: act_suspend_user, perm: true, policy: "Cse" }

이 방식의 한계는 새 스코어러를 추가할 때마다 AES YAML을 편집해야 한다는 점. 4세대+8이 이 결합을 끊었다. generic_actions.rs(663줄 신규)와 대응 YAML 규칙 두 개(act_requested_actions + platform_row_without_requested_actions)가 스코어러가 직접 requested_actions 리스트를 얹어 보내면 AES가 정해진 allowlist 통과분만 실행하는 일반 패스스루를 배선했다.

하드코딩 kind allowlist — 스코어러가 요청 가능한 액션 종류는 코드 상수로 고정:

pub const USER_KINDS: &[&str] = &[
    "suspend",
    "label",
    "bounce_captcha",
    "bounce_arkose",
    "spam_liveness_check",
];
pub const POST_KINDS: &[&str] = &["post_label", "suspend_author"];
pub const MAX_REQUESTED_ACTIONS_PER_MESSAGE: usize = 16;

user entity에는 5종, post entity에는 2종만 요청 가능. 클라이언트가 임의의 kind 문자열을 발명할 수 없다. 메시지당 액션 상한 16개.

이중 fail-closed 검증 on action_to_spec(entity_type, action, allowlist):

  1. hardcoded_kinds 통과 (아니면 "unknown_kind" or "entity_type_mismatch" — 다른 엔티티 타입의 kind면 후자로 구분)
  2. 동적 GenericActionAllowlist.kinds에 kind 포함 (아니면 "kind_not_allowlisted")
  3. suspend/suspend_author kind면 allowlist.suspend_policies에 policy 포함 (아니면 "policy_not_allowlisted")
  4. label/post_label kind면 (a) action.labels 비어있지 않음("no_labels"), (b) 모든 label이 allowlist.labels에 포함("label_not_allowlisted"), (c) ttl_msec >= 0("invalid_ttl")
  5. dedup — 같은 spec이 이미 리스트에 있으면 "duplicate_action"

거부된 액션은 드롭이 아니라 관측된다: SkippedRequestedAction { kind, head, reason, count } 구조체로 수집돼 outcome.info["requested_actions_skipped"]에 JSON으로 붙고, 별도 메트릭 GENERIC_ACTION_TOTAL{entity_type, kind, outcome=resolved|skipped, reason}으로 카운트. 즉 왜 요청이 통과 못 했는지가 그대로 로그로 남는다 — 스코어러 팀이 자기 요청이 왜 거부됐는지 즉시 볼 수 있는 관측성.

YAML에 규칙 배선enforcement_user.yaml:

- id: platform_row_without_requested_actions
  when: '"abuse_platform_requested_actions" in score.labels && size(score.requested_actions) == 0'
  then:
    kind: skip
    reason: platform_row_without_requested_actions

- id: act_requested_actions
  when: "size(score.requested_actions) > 0"
  then:
    kind: act_requested_actions

두 규칙이 짝을 이룬다: 스코어러가 "일반 액션 파이프라인이야"라고 자기 라벨(abuse_platform_requested_actions)로 선언했는데 실제 액션 리스트가 비었으면 skip하고, 하나라도 있으면 act_requested_actions decision을 통해 위의 검증 파이프라인으로 라우팅. enforcement_post.yaml에도 대칭 규칙만 하나 (post 쪽은 platform_row skip 없음).

Decision 확장 on abuse-enforcement-service/service-lib/src/lib.rs (+276/−19) — 새 Decision::ActRequestedActions variant. run_enforcement_inner가 이 variant를 만나면:

let (decision, mut requested_actions_skipped) = match decision {
    Decision::ActRequestedActions => expand_requested_actions_decision(
        facts.entity_type,
        &facts.score,
        &ctx.dynamic_config.generic_action_allowlist(facts.entity_type),
    ),
    Decision::Skip(reason) => (ExpandedDecision::Skip(reason), None),
    Decision::Act(specs) => (ExpandedDecision::Act(specs), None),
};

allowlist 통과분이 하나도 없으면 Skip(REQUESTED_ACTIONS_DENIED), 있으면 Act(specs). 즉 모두 거부돼도 outcome이 skip으로 명시되어 무엇이 요청됐고 왜 거부됐는지가 outcome.info의 JSON에 남는다.

dynamic_config → generic_action_allowlistgrowthbook.rs(+126)에 새 메서드. GrowthBook은 X의 dynamic config·feature-flag 시스템 [추정] — 즉 allowlist(어떤 kind를 스코어러가 요청 가능한지, 어떤 policy·label을 쓸 수 있는지)는 런타임에 A/B 게이팅 가능하다. 새 스코어러가 붙을 때 코드 배포 없이 GrowthBook 콘솔에서 allowlist 항목을 켰다 껐다 할 수 있음.

동시에 유입된 첫 클라이언트: panda_reports_embedding_v10_rough_spam — enforcement_user.yaml에 신규 규칙:

- id: panda_reports_embedding_v10_rough_spam
  when: '"panda_reports_embedding_v10_rough_spam" in score.labels'
  then: { kind: act_suspend_user, perm: false, policy: "PlatformManipulation" }

이 규칙 자체는 정적 매핑(옛날 스타일) — 하지만 라벨명 자체가 새로운 정보: panda = X의 내부 spam 검출 시스템 이름 [추정], reports_embedding_v10 = 리포트 embedding 기반 검출기의 10번째 버전, rough_spam = "확신도 낮지만 스팸 가능성 높은" 판정. 임시(perm: false) suspend + PlatformManipulation policy. 즉 이 검출기는 embedding 기반이고 버전 넘버링이 v10까지 왔다 — 계속 재학습되는 파이프라인이라는 방증.

의미 [의미 절 참조].

정본 반영 services/x.md:

  1. 4세대 표에 4세대+8 행 추가
  2. 한 줄 요약 문단 확장 — 아홉 번째 후속 드랍 서술
  3. BDSM 절 뒤에 "4세대+8 (2026-08-25) — AES generic_actions 패스스루 배선" subsection 추가

1-2. VM Ranker 경로 대폭 단순화 — author_diversity 값 모델 삭제 → 서버 측 dpp로 이동, ranking_scorer::effective_head_weights 88줄 제거

배경 VMRanker는 home-mixer에서 slate reranker 역할을 하는 원격 gRPC 서비스로, Phoenix가 뽑은 후보 점수 위에서 DPP(Determinantal Point Process) 기반 다양성 재정렬(θ=0.65, K=150)을 수행한다. 지금까지 home-mixer/scorers/vm_ranker.rs는 두 개의 value model을 지원했다: author_diversity(MPN 폴드백 기반 저자 다양성 감쇠, home-mixer가 로컬 계산해 rank server에 전달)와 default(rank server가 반환한 점수 그대로 사용). 4세대+3(2026-08-18)의 SID 필드 7개 배선이 이 vm_ranker에 붙은 것이다.

4세대+8이 이 경로를 크게 단순화했다:

home-mixer/scorers/vm_ranker.rs (+11/−128) — 삭제된 것:

// 삭제됨:
const AUTHOR_DIVERSITY_VALUE_MODEL_ID: &str = "author_diversity";
const MPN_FOLD_MULTIPLIER_MAX: f64 = 10.0;

pub struct VMRanker {
    pub client: Arc<dyn VMRankerClient>,
    pub xds_client: Option<Arc<dyn VMRankerClient>>,
    pub author_cold_start: AuthorColdStart,  // 삭제
}

// score() 안의 MPN fold-back 로직 전체 삭제:
let fold_weights = (query.params.get(EnableMpnScoring)
    && query.params.get(VMRankerValueModelId) == AUTHOR_DIVERSITY_VALUE_MODEL_ID)
    .then(|| ScoringWeights::from_params(&query.params));
// ...MpnParts.pos/neg × (returned/sent).clamp(0, MPN_FOLD_MULTIPLIER_MAX) 계산
// ...AuthorColdStart.apply로 후처리

새로 추가된 상수는 하나: const DPP_VALUE_MODEL_ID: &str = "dpp";. 즉 값 모델 ID 하나를 삭제하고 하나로 교체했다. 새 score() 로직은:

candidates.iter().map(|c| Ok(PostCandidate {
    score: score_map.get(&c.tweet_id).copied().or(c.score),
    ..Default::default()
})).collect()

MPN 폴드백·AuthorColdStart 후처리가 모두 사라지고 VM Ranker가 반환한 점수를 그대로 통과. 로컬에서 재계산하지 않음.

home-mixer/scorers/ranking_scorer.rs (+28/−201)ScoringWeights::effective_head_weights 메서드 88줄 삭제. 이 메서드는 각 candidate에 대해 xai_vm_ranker_proto::HeadWeights 프로토버프를 만들어 VMRanker에 전송하는 로직이었다: post_unexplored 승수 계산·click_dwell_time low-fav-rate 페널티·quoted_vqv duration 체크·reply weight per-candidate 조정 등 후보별 가중치 조합. 지금은 통째로 사라졌다.

의미의 층위:

  • 아키텍처 이동: 다양성 계산이 home-mixer(client) → VMRanker(server) 이동. 이전엔 home-mixer가 "다양성 요구사항을 담은 head weights"를 매 후보마다 만들어 rank server에 전송했는데, 이제 rank server가 자체 DPP 로직으로 다양성을 처리하고 home-mixer는 반환된 점수만 소비.
  • author_diversitydpp 명칭 이동의 실체는 아직 애매하다 — dpp가 정말로 기존 재순위 절의 DPP(θ=0.65, K=150)를 가리키는지, 아니면 rank server 안에서만 쓰는 다른 DPP 인스턴스인지는 이 커밋만으로는 확정 못함 [추정]. VMRankerValueModelId 파라미터도 함께 정리된 흔적이 home-mixer/params/param.rs에 있다(+10/−29 순 감소).
  • AuthorColdStart는 사라진 게 아니라 이동: home-mixer/scorers/author_cold_start.rs 파일은 여전히 존재하고 +12/−9로 수정됐다. VMRanker의 후처리에서만 빠진 것 — 다른 지점(RankingScorer? Phoenix 파이프라인?)에서 여전히 적용될 가능성.
  • 삭제된 effective_head_weights의 도착지: 이 메서드가 계산하던 head weights(favorite·reply·retweet·share·dwell·quoted_vqv 등)가 이제는 서버가 자체 로직으로 계산하거나, 아니면 아예 head weights 개념 자체가 다른 방식으로 대체된 것으로 보임. VMRanker가 이제 원 phoenix 점수를 그대로 소비하고 자체 DPP만 적용하는 걸로 해석하는 게 자연스럽다 [추정].

이 단순화는 4세대의 큰 방향 — home-mixer에서 로컬 계산·캐시를 걷어내고 서빙 산출을 우선 사용 — 의 연장이다. 4세대+5의 UseServedSlateContext 게이트가 slate context 계산을 로컬 → Phoenix 서빙으로 이동시켰던 것과 짝을 이룬다.

"AUTHOR_DIVERSITY_VALUE_MODEL_ID: &str = "author_diversity"" ← 삭제 "DPP_VALUE_MODEL_ID: &str = "dpp"" ← 신규 — home-mixer/scorers/vm_ranker.rs

정본 반영 services/x.md:

  1. 랭킹 절의 VMRanker 서술 갱신 — 값 모델 명칭 변경, effective_head_weights 삭제
  2. 다양성 절 — DPP가 VMRanker의 유일한 값 모델이 됐다는 사실 반영
  3. 파라미터 변경 관행에 파라미터 -29줄(MPN·author_diversity 관련 상수 정리)

1-3. Following 파이프라인 블록 관계 확장 — FollowingBlockedByHydrator + AuthorSocialgraphFilter 신설

배경 Following 지면은 인네트워크 최신 포스트만 노출하는 reverse-chron 파이프라인이다. 4세대+3에서 Following 전용 VF hydrator가 분기된 이후 이 파이프라인이 계속 정교화되는 흐름이 이어지고 있는데, 이번엔 블록 관계 처리를 인용·리트윗 저자까지 확장하는 작업이 붙었다.

home-mixer/candidate_hydrators/following_blocked_by_hydrator.rs (65줄 신규) — 새 hydrator. 각 candidate에 대해:

let user_ids: Vec<u64> = candidates
    .iter()
    .flat_map(|c| c.quoted_user_id.into_iter().chain(c.retweeted_user_id))
    .collect();

let blocked_by_user_ids = self.socialgraph_client
    .check_blocked_by(query.user_id, &user_ids)
    .await?;

즉 candidate의 quoted 저자retweeted 저자의 user_id 리스트를 모아 SocialGraphClient에 "이들 중 누가 뷰어를 블록하고 있는가?"를 물어보고, 결과를 후보 필드 두 개에 세팅:

  • author_blocks_viewer — retweeted 저자가 뷰어를 블록하면 true
  • quoted_author_blocks_viewer — quoted 저자가 뷰어를 블록하면 true

home-mixer/filters/author_socialgraph_filter.rs — 기존 파일(4세대에서 이미 존재)에 새 배선. 필터는 6개 조건 중 하나라도 참이면 candidate 제거:

if muted                          // 뷰어가 저자를 mute
    || blocked                    // 뷰어가 저자를 block
    || author_blocks_viewer       // 저자(=retweeted 저자)가 뷰어를 block
    || quoted_author_blocks_viewer  // quoted 저자가 뷰어를 block
    || viewer_blocks_quoted_author  // 뷰어가 quoted 저자를 block
    || viewer_blocks_retweeted_user  // 뷰어가 retweet된 저자를 block
{
    removed.push(candidate);
} else {
    kept.push(candidate);
}

이전엔 뷰어→저자 방향의 block/mute만 봤는데, 이제 저자→뷰어 방향quote/retweet 체인의 원 저자까지 여섯 갈래로 확장.

home-mixer/candidate_pipeline/reverse_chron_posts_pipeline.rs (+27/−2) — 파이프라인에 신규 hydrator/filter 배선:

let post_selection_hydrators = vec![
    Box::new(FollowingBlockedByHydrator::new(socialgraph_client).await),  // 신규
    Box::new(VFFollowingCandidateHydrator::new(...)),
    // ...
];
let post_selection_filters = vec![
    Box::new(AuthorSocialgraphFilter),  // 신규
    Box::new(VFFilter),
    Box::new(AncillaryVFFilter),
];

AuthorSocialgraphFilterVF 필터 앞에 위치. 즉 블록/뮤트로 걸린 후보는 VF 판정 조회 자체가 스킵되어 성능도 개선. SocialGraphClient는 XAI candidate_pipeline component_library의 클라이언트(TLS S2S로 flock 접속) — 미공개 서비스.

의미의 층위:

  • 블록 시맨틱의 전이 확장 — 이전엔 "당신이 A를 팔로우 안 하면 A의 포스트 안 보임"이었는데, 이제 "당신이 A를 팔로우해도 A가 원 저자 B를 리트윗했는데 B가 당신을 블록하고 있으면 안 보임"까지 확장. B→당신 블록이 팔로잉 관계와 무관하게 존중된다. 광범위한 policy 결정 — X가 quote/retweet을 통한 우회 노출을 명시적으로 막기 시작했다는 신호로 해석 [추정].
  • 성능 트레이드오프: 매 요청마다 SocialGraphClient에 원격 조회 하나가 추가된다. 다만 조회는 batch(모든 candidate의 quoted/retweeted user_id 한꺼번에 check_blocked_by)이므로 fixed overhead가 아니라 후보 수 대비 sub-linear.
  • Following만 배선: For You(algorithmic) 파이프라인의 hydrator 목록에는 이 hydrator가 아직 없다. 배선 대칭성이 있다면 다음 커밋에서 For You에도 붙을 가능성 [추정].

정본 반영 services/x.md:

  1. Following 지면 서술에 블록 확장 subsection 추가
  2. 필터 21개 표AuthorSocialgraphFilter 상세 갱신 (기존에도 있었지만 시맨틱이 확장됐음을 반영)

1-4. Brazil2026ElectionFilter 계정 리스트 갱신 (+3,379줄) — TSE dadosabertos 원본 반영

home-mixer/filters/brazil_2026_election_filter.rs (+3,379/−5, 파일 전체 4,947줄)에 계정 리스트가 대폭 추가됐다. README 알림란에도 명시: "Account list updated August 25, 2026." 데이터 원본 dadosabertos.tse.jus.br/dataset/candidatos-2026 — 브라질 선거관리위원회(TSE)의 2026 선거 후보자 공개 데이터셋.

필터 시맨틱 변경 없음 — 여전히 4세대+1에서 신설된 로직 그대로: (1) dadosabertos.tse.jus.br의 신고 계정 명단을 하드코딩, (2) For You 파이프라인에서 이들 계정의 포스트를 제거, (3) 단 뷰어가 명시적으로 팔로우한 계정은 예외. Art. 28 § 1º-A of Electoral Resolution 23.610 준수.

투명성 관행 — 공개 소스와 사용자 프라이버시의 절충:

// User ids below are obfuscated; usernames are included for transparency.

// @OmarAzizSenador deleted his account at the time this code was written.
// @_ANDREDOPRADO no live account was found.
// @_EDUARDOMANTOAN no live account was found.
// @ADALBERTO_1111 no live account was found.
...

user_id는 obfuscated(내부 X ID 노출 방지) 하지만 @username은 그대로 코드에 남는다. 각 계정 옆에 "deleted his account" / "no live account was found" 같은 상태 주석까지 붙어 있다. 공개 소스와 사용자 프라이버시(내부 user_id 유출 방지) 사이의 절충 — 검증 가능성을 유지하면서 X의 내부 user_id 매핑은 감추는 방식. 4세대+1의 665개에서 훨씬 늘어난 규모 [추정] (정확한 계정 수는 diff 라인 세기로 별도 계산 필요, 4947줄 파일에 계정당 24줄이면 대략 12002000개 규모).

정본 반영 services/x.mdBrazil2026ElectionFilter 항목 갱신 — 계정 리스트가 정기 갱신되는 관행이라는 사실 명시.

1-5. phoenix-rankall prefloor 스냅샷 배선 — min_age 있는 window에 대해 pre-min-age 데이터 동시 로드

배경 phoenix-rankall/는 Phoenix의 offline 인덱싱·집계 파이프라인으로, 다양한 window(예: 1fav_uec_1day, video_14day, evergreen_video_1825day)로 후보 pool을 유지한다. 4세대+1에서 video_14day SID window가 추가됐고, 4세대+6에서 EVERGREEN retrieval dataset이 evergreen_video_1825dayvideo_4to14day로 축소된 흐름을 이어 4세대+8은 rankall base 저장소 자체를 확장했다.

**phoenix-rankall/src/store/base.rs (+202/−61)**에 새 상수와 로딩 로직:

const PREFLOOR_SLACK_SECS: f64 = 6.0 * 3600.0;

// window config에 min_age가 있으면:
if wc.min_age.is_some() {
    let pf_name = format!("prefloor_{window_name}");
    let pf_link = self.config.output_dir.join(format!("{pf_name}.parquet"));
    let pf_path = if pf_link.exists() {
        Some(pf_link)
    } else {
        find_latest_versioned_file(&self.config.output_dir, &pf_name)
    };
    // pf_path에서 배치 로딩...
}

즉 특정 window가 min_age 조건(예: "이 pool은 게시 후 최소 N시간 지난 것만 포함")을 가지면, 그 조건을 통과 못한 min_age 이전 데이터를 별도의 prefloor_<window>.parquet 파일로 유지해 함께 로드한다. PREFLOOR_SLACK_SECS = 6시간 — prefloor 데이터가 min_age 문턱을 넘기 전에 유지되는 여유 시간.

의미4세대+2에서 phoenix-rankall-stratofavoriteCount>=1 게이트가 제거됐던 흐름의 연장. 이전엔 "인덱스에 들어가려면 조건 통과가 필요"였는데, 이제 rankall이 아직 조건을 통과 못한 후보도 별도 pool에 유지해서 조건 통과 시점에 즉시 프로덕션에 반영 가능하게 한다. 콜드스타트·freshness 관점의 개선 — 신규 포스트의 인덱스 지연을 줄이는 방향 [추정].

정본 반영 services/x.mdPhoenix 학습·인덱스 절에 subsection "4세대+8 (2026-08-25) — rankall prefloor 스냅샷 배선" 추가.

1-6. Phoenix copy_port tokio::spawn 하드닝 — rate-limit이 병렬 폴링 없이도 in-flight cap 지키게

phoenix/crates/serving/xai-recsys-engine/src/copy_port_client.rs (+155) — copy_port는 Phoenix 서빙에서 오브젝트 스토리지(S3/xai-o2)에서 임베딩 테이블·체크포인트를 다운로드하는 클라이언트다. 이전 코드는 join_all(futures).await로 여러 다운로드를 병렬 진행했는데, rate limit 배치 안에서 join_all이 futures를 순차적으로 poll하면 실제 in-flight concurrency가 max_concurrent를 넘을 수 있는 문제가 있었다.

수정:

// Before:
let batch_results = join_all(batch).await;

// After:
let batch_results = join_all(batch.into_iter().map(tokio::task::spawn))
    .await
    .into_iter()
    .collect::<Result<Vec<_>, _>>()
    .map_err(|e| CopyPortError::Other(format!("copy_port download task join: {e}")))?;

각 future를 tokio::task::spawn으로 별도 태스크에 감싸면 런타임 스케줄러가 진짜로 병렬 실행하고, rate limit 로직(join_rate_limited)이 다음 배치를 issue할 시점을 정확히 in-flight 카운트 기반으로 결정한다. 회귀 테스트 2개 신규:

  • rate_limit_caps_in_flight_despite_spawn — 6개 다운로드에 concurrency=2 상한 → peak in-flight이 정확히 2
  • rate_limit_paces_between_spawned_batches — 배치 사이의 페이싱이 유지됨

의미 4세대+7에서 Phoenix 체크포인트 로더 다중 노드 하드닝이 restore path의 OOM을 잡았다면, 이번은 서빙 시점의 병렬 다운로드 스로틀링 정확성을 잡는 하드닝. 두 개가 짝을 이룬다 — 4세대+6에서 Muon+GB300 학습이 export에 정식 포함된 이후 학습·서빙 양 측 인프라 성숙 사이클의 연장. 이런 stability 픽스가 매일 커밋에 붙는 것 자체가 X가 4세대 오픈소스 릴리스를 검증 가능·프로덕션 신뢰 가능하게 유지하는 데 조직 리소스를 계속 투입하고 있다는 방증.

1-7. 소소한 변경 4건 (grox reply_spam · grox upa · engagement counts · URT 마셜링)

의미 — 이번 드랍의 세 축은

  1. enforcement 관행의 유연화 — AES가 하드코딩 YAML 규칙에서 스코어러가 직접 요청하는 일반 액션 파이프라인을 함께 지원. 새 스코어러 붙이는 배포 사이클이 짧아짐. panda_reports_embedding_v10_rough_spam처럼 embedding 기반 spam 검출기가 계속 재학습되며 붙는 인프라 정착.
  2. 랭커 경로의 대폭 단순화 — VMRanker의 로컬 계산 층이 걷어지고 서버 측 DPP로 위임. 4세대+5의 slate context 이관과 짝을 이루는 아키텍처 리팩터링 — home-mixer는 "얇은 어그리게이터"로, 계산은 gRPC 서버들이 담당.
  3. Following 지면의 policy 확장 — 인용·리트윗 체인의 저자 블록 관계까지 존중. quote를 통한 블록 우회를 명시적으로 막음.

4세대 전체의 흐름은 여전히 "코드 공개 → 검증 인프라 배선 → experiment 트래킹 → 아키텍처 정리 → policy 확장"의 성숙 곡선을 그리고 있다. 매일~격일 커밋이 계속 붙는 흐름이 4세대+8(08-25)까지 12일간 이어지고 있다는 사실 자체가 X가 이 오픈소스 릴리스를 마케팅 이벤트가 아니라 지속되는 코드 미러 관계로 유지하고 있다는 방증.

2. Tlow — WeChat/Tencent 프로덕션 A/B, flow-based item tokenizer가 RQ-VAE 대안으로 등장 (레이더)

자료 Tlow: Flow-based Item Tokenizer for Recommendation — arXiv 2608.24176, 2026-08-25 v1, 저자 6명 Nian Li, Chonggang Song, Jingtao Ding, Lingling Yi, Yong Li, Qingmin Liao. China's largest social media platform WeChat 프로덕션 A/B로 소속 확인 (HTML 판 abstract에서 명시).

배경 Semantic ID(SID) 라인의 핵심 컴포넌트인 item tokenizer는 각 아이템의 의미 임베딩을 discrete token ID 시퀀스로 변환하는 모듈이다. 사실상 표준은 RQ-VAE(Residual-Quantized VAE) — Google 2023 TIGER 논문 이후 여러 프로덕션 시스템(Netflix Foundation Model, Kuaishou PushDualGen 등)에서 채택. 하지만 RQ-VAE는 세 가지 알려진 문제가 있다: (a) codebook collapse — 대부분 code slot이 죽고 소수만 활용됨, (b) quantization 오류의 residual 축적 — deep quantization 층에서 오차가 커짐, (c) 불연속성 — 유사한 아이템이 완전히 다른 token 시퀀스로 매핑되어 학습이 어려움.

Tlow는 이 문제들을 normalizing flow로 접근한다. Flow-based model은 invertible neural network로 임베딩 공간을 학습 가능한 분포로 변환·역변환한다. 저자들의 주장은: flow 기반 tokenization이 codebook 활용률과 semantic locality 두 축에서 RQ-VAE보다 낫다.

새로 알게 된 것

  • 프로덕션 A/B [확인]:

    "The retrieval model based on token IDs improves user CTR by 10.32% globally and by 11.64% for new items." — Tlow abstract, 2026-08-25

    글로벌 CTR +10.32%, 신규 아이템 CTR +11.64%. 신규 아이템에서 더 큰 개선폭은 콜드스타트에 특히 강하다는 시사 — semantic tokenization 라인의 핵심 이점(cold item의 유의미한 표현 확보)이 프로덕션 지표로 확인됨.

  • 평가 지면 [확인] — WeChat retrieval model. 광고인지 유기 콘텐츠인지, 어느 세부 지면(Look/Video Channels/Moments)인지는 abstract에 미공개.

  • 저자 소속 확인 채널 — Tencent 관련 저자 이름(Chonggang Song) + WeChat이 China's largest social platform으로 abstract에 명시 → Tencent WeChat rec 그룹으로 확정.

정본 반영 radar.md "이번 달 신규"에 ### Tlow (WeChat/Tencent) — flow-based item tokenizer가 RQ-VAE 대안으로 프로덕션 CTR +10.32% 절 추가 (HEGM보다 위, SID 스레드에 링크).

의미

  • SID/generative retrieval 스레드의 새 축 — tokenizer 아키텍처 자체가 프로덕션에서 갈리기 시작 — 지금까지 SID 라인은 대체로 "RQ-VAE + downstream 모델" 조합이었다. Tlow는 tokenizer 층을 flow 기반으로 대체해도 프로덕션 유효한 지표 개선이 나온다는 첫 진술. RQ-VAE의 codebook collapse가 실제 서빙에서 문제였다는 방증 [추정] — Tencent가 이 문제를 겪고 대안을 내놓은 것으로 해석.
  • Tencent WeChat의 오랜만의 프로덕션 진술 — WeChat rec은 최근 몇 년 조용한 편이었다. Tlow가 나오면서 유기 콘텐츠 지면의 실 아키텍처 진술이 재개되는 신호. Weixin Video Channels(WeChat의 짧은 비디오 지면)의 rec 스택 논문이 이어질지 관찰 가치.
  • 관전 포인트 — (a) code + 상세 (block-wise flow structure)가 후속에서 나올지, (b) 두 번째 회사(Kuaishou / ByteDance / Xiaohongshu 등)의 유사 tokenizer 대안 진술이 나오면 topics/ 승격 후보.

3. TAGR — 익명 대형 live-stream 광고 플랫폼, revenue +16.1% (레이더)

자료 TAGR: Temporally Adaptive Generative Recommendation for Industrial Live-Streaming Advertising — arXiv 2608.24034, 2026-08-25 v1, 저자 10명 Wencai Ye, Guangyi Liu, Chaoyi Wang, Wenbin Luo, Shengyu Wang 외. 저자 소속·플랫폼 이름 abstract에 미명시 — abstract에서 "a large-scale e-commerce live-stream advertising platform"으로만 언급.

배경 라이브 스트리밍 광고는 실시간으로 컨텐츠·상품·유저 피드백이 바뀌는 특성상 recommender에 강한 freshness 요구를 걸어놓는다. 지금까지 generative recommender(SID 기반) 라인은 대부분 static 카탈로그를 가정했는데, 라이브는 스트림이 열리고 닫히는 시간 스케일이 분 단위라 static token vocab의 유효 기간이 짧다.

새로 알게 된 것

  • 프로덕션 A/B 결과 [확인]:
    • live-room entry rate +8.5%
    • shopping-cart click rate +7.4%
    • revenue +16.1% over production baseline
  • 아키텍처 — Temporally Adaptive Generative Recommendation. abstract에서 "designed for rapidly changing live content, promoted products, and user feedback"라고 표현. 구체적 시간축 adaptation 메커니즘(tokenizer 재학습 주기? online update?)은 abstract에 없음 — 본문 확인 필요하나 이번 배치에서는 스킵.
  • 플랫폼 미공개 — 저자 이름으로는 확정 못 함. 중국 e-commerce live-stream의 대표 후보는 Kuaishou(Kwai)·Alibaba(Taobao Live)·Douyin/ByteDance(Douyin E-commerce)·Xiaohongshu — 저자 이름은 이 중 어느 회사와도 직접 매칭 안 됨 [추정].

정본 반영 radar.md "이번 달 신규"에 ### TAGR — Temporally Adaptive Generative Recommendation, 대형 live-stream 광고 플랫폼 revenue +16.1% 절 추가.

의미

  • 라이브 스트리밍 랭킹 스레드에 세 번째 회사 — 기존 Twitch(Amazon) Multi-Objective와 Netflix의 라이브 콜드스타트 이후. TAGR은 광고 지면·중국 e-commerce 라이브 이라는 다른 세 번째 각도.
  • generative recommender가 광고·라이브·rapid change 도메인에도 프로덕션 진술 축적 — 이전까진 static short-video나 e-commerce catalog 기준 진술이 많았는데, 이번은 시간축 adaptation 필요 도메인에서의 진술.
  • 플랫폼 미확인이 가장 큰 약점 — v2 이후 소속 공개 또는 저자 이메일 도메인 확인 시 정본 승격 재검토.

검증에서 뒤집힌 것

없음 — 이번 배치의 신규 자료(X 4세대+8, Tlow, TAGR)는 기존 정본을 뒤집지 않는다. VM Ranker 단순화(4세대+8)는 4세대의 아키텍처 정리 흐름에 정합, Following 블록 확장은 정책 방향 확장, Brazil 계정 갱신은 컴플라이언스 관행 유지. Tlow·TAGR은 각 관찰 스레드(SID/generative retrieval, live-stream)에 새 데이터 포인트로 붙는다.

레이더

  • 신규 2건:
    • Tlow (Tencent WeChat, arXiv 2608.24176) — flow-based item tokenizer 프로덕션 CTR +10.32%
    • TAGR (익명 e-commerce live-stream, arXiv 2608.24034) — temporally adaptive generative recommendation revenue +16.1%

arXiv cs.IR triage 30건 중 통과 2건. 통과 못 한 것들은 대체로 offline 벤치마크 위주 + industry provenance 부재였다. 주목한 미통과 후보 4건: Native Multimodal for CTR (Alibaba 추정, 프로덕션 진술 미확인), RecGPT-Mobile-V2 (Alibaba 온디바이스 query prediction, 이전 V1 정본 미추적), WeMM-Embedding (Tencent WeChat multimodal embedding technical report, retrieval 프로덕션 진술 없음), RetrievalFormer (dual-encoder search+rec 통합 index, 프로덕션 규모 명확치 않음).

다음에 볼 것

  • X 4세대+9 (다음 커밋) — 12일 연속(4세대 원본 08-13부터) 매일~격일 커밋 흐름. 관전 포인트: (a) AES generic_actions allowlist가 GrowthBook을 통해 어떤 스코어러들에게 열리는지, (b) VMRanker의 dpp 값 모델이 유일한 옵션으로 정착하는지 vs 다른 값 모델이 추가되는지, (c) AuthorSocialgraphFilter가 For You 파이프라인에도 배선되는지, (d) panda_reports_embedding_v10 이후 v11이 언제 나오는지 (embedding 검출기의 재학습 주기 관측), (e) prefloor 스냅샷이 어떤 window에 최초 활성화되는지, (f) 4세대+7의 SafetyPtosPolicyCrossValidator가 스팸·혐오 발화 카테고리로 확장되는지.
  • Tlow 후속 — code 공개 여부, Tencent의 다른 WeChat 지면(Video Channels·Moments·Look) 진술 추적.
  • TAGR 플랫폼 확인 — v2 이후 저자 소속 공개 시 정본 승격 결정. 저자 이름으로 Kuaishou / Xiaohongshu / Douyin 매칭 재확인.
  • 월요일(2026-08-31) 산업 블로그 스윕 — Pinterest engineering, research.atspotify.com, Google Research blog, LinkedIn engineering.