Signal vs. Noise: Building Real-World Trend Validation

Scoring V2: When Trend Detection Meets Real-World Validation
The task was straightforward on paper: make the trend-analysis project smarter about which emerging trends actually matter. The team had been tracking trends from Hacker News, GitHub, and arXiv for months, but without a proper scoring system, distinguishing a genuinely important signal from noise was impossible. Enter Scoring V2 and Tavily citation-based validation—a two-pronged approach to separate the signal from the static.
I started by building the foundation: a TrendScorer class that could quantify both urgency (0-100, measuring how fast something’s gaining traction) and quality (0-100, measuring substantive content depth). The recommendation engine sits on top, outputting one of four verdicts: ACT_NOW for critical emerging trends, MONITOR for promising developments worth watching, EVERGREEN for stable long-term patterns, and IGNORE for noise. The logic feels almost journalistic—like having an editor decide what makes the front page.
But here’s where it got interesting. Raw metrics aren’t enough. I needed ground truth. That’s where Tavily came in. The approach was unconventional: instead of trusting source counts, I’d verify trends by counting how many unique domains cited them. This filters out aggregator pages that just repost content without adding value. I built a TavilyAdapter with three key methods: count_citations() to quantify domain diversity, _is_aggregator() to detect and skip pages like Medium or Dev.to when they’re just amplifying existing news, and fetch_news() to pull fresh citations above a configurable threshold.
The enrichment loop was the crucial integration point. As the crawler processed HN threads, GitHub repositories, and arXiv papers, it now reaches out to Tavily to fetch citation data for each trend. This added latency, sure, but the quality gain justified it. A trend without citations from diverse domains gets downgraded; one with strong citation presence climbs the recommendation scale.
Frontend changes reflected this new confidence. I added RecommendationBadge and UrgencyQualityIcons components to visualize the scores. More importantly, sources got refactored from simple counts to URL arrays, making each citation clickable. Users could now drill down and verify recommendations themselves. The categories page navigation switched to URL parameters, meaning browser back/forward buttons finally work as expected—a small UX win, but these compound.
Here’s something that surprised me during implementation: citation validation isn’t about counting links, it’s about domain diversity. A trend mentioned on 100 tech blogs means less than the same trend appearing on 10 completely different domain types. Aggregators muddy this signal badly. Medium writers rewriting HN stories, DevOps blogs republishing GitHub release notes—they look like validation but they’re just echoes. Detecting and filtering them required pattern matching against known aggregator domains.
The CHANGELOG and implementation docs—TAVILY_CITATION_APPROACH.md, SCORING_V2_PLAN.md—became the project’s institutional memory. Future team members can see not just what was built, but why each decision was made.
What started as “make trends more meaningful” became a lesson in trust, but verify. Scoring systems are only as good as their ground truth, and ground truth requires external validation. Tavily citations provided that ground truth at scale.
😄 Why did the trend analyst break up with their metrics? They had no basis for the relationship.
Metadata
- Branch:
- feat/scoring-v2-tavily-citations
- Dev Joke
- VS Code: решение проблемы, о существовании которой ты не знал, способом, который не понимаешь.