Problem
Today's feed: 45 cards
- 44 are "RUNNING ON FUMES" workload cards
- 1 is a hot_streak card
All 44 workload cards have:
- Same headline template: "[PLAYER NAME] IS RUNNING ON FUMES"
- Same structure
- Same repetitive filler text
- Same low verification score (60)
This is not intelligence. This is spam.
Root Cause
The workload card generator produces unlimited cards without any cap. If 50 players have minute increases, it generates 50 nearly identical cards.
Requirements
1. Cap Cards Per Type Per Day
CARD_TYPE_LIMITS = {
"hot_streak": 10,
"cold_streak": 10,
"workload": 5, # Hard cap - these are low value
"injury_impact": 10,
"matchup": 15,
"narrative": 10,
"crossref": 10,
}
def filter_cards_by_type_limit(cards: list[dict]) -> list[dict]:
"""Keep only top N cards per type, sorted by quality."""
by_type = defaultdict(list)
for card in cards:
by_type[card["cardType"]].append(card)
result = []
for card_type, type_cards in by_type.items():
limit = CARD_TYPE_LIMITS.get(card_type, 10)
# Sort by verification score descending, take top N
sorted_cards = sorted(type_cards, key=lambda c: c["verificationScore"], reverse=True)
result.extend(sorted_cards[:limit])
return result
2. Require Card Type Diversity in Feed
MINIMUM_CARD_TYPES = 3 # Feed must have at least 3 different card types
def validate_feed_diversity(cards: list[dict]) -> bool:
types_present = set(c["cardType"] for c in cards)
return len(types_present) >= MINIMUM_CARD_TYPES
3. Prioritize High-Value Card Types
When selecting which cards to show, prioritize:
- matchup - game-specific intelligence
- narrative - story angles for media
- crossref - convergence signals (our core value prop)
- hot_streak/cold_streak - player performance trends
- workload - lowest priority (minutes increase is weak signal)
4. Deduplicate Similar Cards
If two cards are about the same signal (e.g., two "minutes increase" cards for players on the same team), keep only the better one:
def deduplicate_similar_cards(cards: list[dict]) -> list[dict]:
# Group by (card_type, team, signal_type)
seen_signals = set()
result = []
for card in sorted(cards, key=lambda c: c["verificationScore"], reverse=True):
signal_key = (card["cardType"], card.get("player_team"), card.get("signal_type"))
if signal_key in seen_signals:
continue
seen_signals.add(signal_key)
result.append(card)
return result
Validation
After deploy:
- Generate cards for a day
- Verify no more than 5 workload cards appear
- Verify at least 3 different card types are present
- Verify no two cards have identical headlines
Definition of Done
Problem
Today's feed: 45 cards
All 44 workload cards have:
This is not intelligence. This is spam.
Root Cause
The workload card generator produces unlimited cards without any cap. If 50 players have minute increases, it generates 50 nearly identical cards.
Requirements
1. Cap Cards Per Type Per Day
2. Require Card Type Diversity in Feed
3. Prioritize High-Value Card Types
When selecting which cards to show, prioritize:
4. Deduplicate Similar Cards
If two cards are about the same signal (e.g., two "minutes increase" cards for players on the same team), keep only the better one:
Validation
After deploy:
Definition of Done