How we calculate
the Gap Score
The Gap Score is our proprietary 0–100 metric measuring how much a story is trending on social media relative to its mainstream media coverage. A score of 94 means enormous social interest with almost no mainstream media coverage — a significant coverage gap signal. Here's exactly how we compute it.
What this is — and isn't
GapWatch measures the gap between social media velocity and mainstream media coverage. We track persistence and platform diversity, not truth.
Some gaps close because the underlying story turns out to be real and mainstream media eventually picks it up. Some close because the story is debunked. Some never close because the conversation dissipates without consequence. Our validation page tracks how each gap actually resolves.
A high Gap Score means a story is receiving significantly more social attention than mainstream media coverage. It is a signal for further investigation — not a verdict on accuracy, importance, or whether coverage is being withheld.
What GapWatch measures
GapWatch is an information discovery platform that measures the gap between social media signal — aggregated across Reddit, X, TikTok, Bluesky, Hacker News, RSS feeds, and independent web sources — and mainstream media coverage. When a story is gaining significant traction across social platforms but has not yet been picked up by traditional outlets, GapWatch surfaces it and quantifies the gap. Coverage gaps matter because they represent the window between when a story becomes publicly significant and when the press treats it as news — a window that is actionable for journalists, researchers, and analysts.
The engine aggregates signal from all tracked platforms without privileging any single source. Gap Score and Velocity Score are computed on aggregate social signal. No platform — including Reddit — is weighted above others in the current scoring engine. See the Platform weighting section for details and roadmap.
Important
A high GapScore means a story is receiving significantly more social attention than mainstream media coverage. It is a signal for further investigation, not a verdict on truth or importance.
Core formula
Gap Score =
(SVI − MCI)
× SDM × CAM
Normalized to 0–100 scale · Updated every 15 minutes
Rate of social mention acceleration across platforms
Article count × outlet prominence × recency decay
Up to 1.35× when public sentiment diverges from mainstream media framing
Up to 1.25× when cross-spectrum coverage asymmetry is detected
1. Social Velocity Index (SVI)
We measure mention volume and acceleration across social platforms including Reddit, X, TikTok, Bluesky, Hacker News, and curated RSS feeds. The base velocity uses an exponential curve over on-topic post count (score = 100 × (1 − e−n/15)), so going from 0 to 15 posts matters more than going from 50 to 65. An engagement bonus of up to 10 points is added when verified upvote data is available from Reddit's public API. A cross-subreddit breadth bonus of up to 15 points is applied when a topic is being discussed organically across multiple communities beyond the curated allowlist — this diversity signal indicates genuine widespread interest rather than activity confined to a single niche.
Platforms in SVI calculation:
Most platforms contribute to all verticals. Hacker News is scoped to the verticals where its signal is most reliable — this scoping is configurable as the system learns which sources predict coverage gaps best.
Reddit (/rising + /hot feeds)
Viral detection via Reddit's own rising/hot rankings
Reddit (ForumScout)
Broader keyword coverage, merged with viral pool
X / Twitter
Real-time public conversation
TikTok
Virality leading indicator
Bluesky
Decentralised social signal
Hacker News
Tech & finance community signal via public API
RSS / Indie feeds
15+ independent & Substack feeds
Firecrawl Web Search
Niche blogs, Substacks, independent journalism
Reddit data is sourced from two complementary feeds: Reddit's public Atom RSS for each subreddit's /rising and /hot rankings (viral signal — Reddit has already ranked which posts are accelerating) and ForumScout keyword search (broader topic coverage). Results are merged and deduplicated across all platforms. For RSS-sourced posts, mention count and feed-rank are the engagement signal; real upvote totals are only displayed when they come from a verified API response.
Viral detection pipeline
Every 15 minutes, GapWatch fetches each vertical's curated subreddit allow-list via Reddit's /rising and /hot RSS feeds. Posts are filtered (no stickied, no NSFW, age < 48h), ranked by feed position, merged with keyword-search results at the head of the discovery pool, and fed into the topic clusterer. A rolling 7-day percentile tracks the “velocity floor” per vertical so the threshold for calling a post “viral” adapts as each community's baseline activity shifts.
Viral stories carry a “first detected on /rising” timestamp, preserved across refreshes — this is what powers “Called It” receipts for stories GapWatch flagged before mainstream pickup.
2. Mainstream Media Coverage Index (MCI)
We ingest article counts, headline prominence, and broadcast minutes from 180+ mainstream media sources across left-leaning, right-leaning, and centrist outlets. MCI is a 0–100 score where 100 = saturation coverage.
We deliberately include both sides of the political spectrum to avoid ideological bias in the score itself. A story absent from both CNN and Fox simultaneously scores much lower on MCI than one absent from only one — because cross-spectrum coverage asymmetry is a stronger signal.
Gap formula subtracts MCI directly from SVI at equal weight — full mainstream media coverage of a fully viral story produces a gap score of zero.
After subtracting MCI from SVI, a square root compression curve is applied before multipliers. This spreads scores across the full 0–100 range — without it, topics with partial mainstream media coverage would cluster at 90–100 with no differentiation. The compression uses two curves depending on whether mainstream media coverage exists at all. When zero mainstream media articles are found, the curve is more generous (ceiling 85), because the complete absence of mainstream coverage is itself the signal — a topic with real social traction and literally no mainstream coverage represents the clearest possible coverage gap. When mainstream has partial coverage, a tighter curve (ceiling 65) prevents score inflation. Both leave room for sentiment and coverage anomaly multipliers to push higher-signal stories toward 100. A floor of 50 ensures that any story with meaningful social velocity and zero mainstream media articles never scores below “significant.”
Before computing MCI, articles are passed through a topic relevance filter. For curated static-topic stories, each story has a set of required keywords — an article must contain at least one in its headline or description to count toward coverage. For dynamically discovered stories, relevance is determined by an LLM-as-judge step (Claude Haiku) that evaluates whether each article is specifically about the story being tracked, not merely keyword-adjacent. This catches both false positives (old articles matching evergreen phrases) and false negatives (relevant articles whose descriptions don't contain exact topic words verbatim). Articles that pass the judge are marked with a one-sentence relevance reasoning for transparency. If the article sample passes the filter but NewsData found matching articles overall, a conservative 30% coverage floor is applied — acknowledging the topic is likely covered even when our sample was imperfect.
3. Sentiment Divergence Multiplier
When social sentiment and mainstream media framing diverge sharply, the raw coverage gap understates the story's significance. A story the public feels positively about that mainstream media frames negatively (or vice versa) receives a multiplier of up to 1.35×.
Sentiment is scored using a fine-tuned model trained on media framing and social discourse data, producing a score from -1 (very negative) to +1 (very positive) for both the social and mainstream media signals.
4. Coverage Asymmetry Multiplier
The most nuanced component. We look for statistical anomalies in coverage distribution — patterns distinct from simply low interest. This is our most interpretive signal and the one most susceptible to false positives. See limitations #09 for the full caveat.
- →Story has high social velocity but zero or negative mainstream media article growth
- →Story is trending in multiple geo-regions simultaneously with low mainstream coverage in all
- →Unusual velocity deceleration inconsistent with organic decay patterns
- →Cross-spectrum coverage absence: minimal pickup from outlets across the political spectrum
The Coverage Asymmetry Multiplier ranges from 1.0 (no asymmetry signal) to 1.25 (strong cross-spectrum asymmetry). This is the most proprietary component of the Gap Score.
Platform weighting
The current scoring engine ingests signal from all tracked platforms and contributes each to the Social Velocity Index without platform-specific multipliers. Reddit, X, TikTok, Bluesky, Hacker News, and RSS/web sources each contribute to aggregate SVI equally — a story's total mention velocity and acceleration across all platforms determines its score, regardless of which platform drove the signal.
Reddit is not privileged in the mechanics. The cross-subreddit breadth bonus described in the SVI section is one signal component that measures organic topic spread within Reddit's own ecosystem — it does not weight Reddit's total contribution above other platforms.
Roadmap — April 2026
Empirical per-vertical weighting is in development. The goal is to derive, from historical signal-to-coverage correlation data, whether certain platforms are more predictive for specific verticals — for example, whether X signal correlates more strongly with finance story pickups, or Bluesky with AI story pickups. These weights will be empirical, not assumed, and will be documented in this section when applied. Until then, all platforms contribute equally to the aggregate score.
The Causal Gap
ANALYST TIERA second dimension beyond the core Gap Score formula
Beyond individual story gaps, the Analyst tier surfaces a second type of gap: the causal gap — connections between seemingly unrelated stories that suggest a larger pattern mainstream media is failing to connect.
Our entity extraction model identifies shared people, organizations, assets, and events across stories and computes a connection strength score. The Intelligence Hub visualizations (Narrative Board, Story Network Graph, Entity Explorer) render these connections interactively.
We do not editorialize on what the connections mean — we surface the data and let analysts draw their own conclusions.
Gap Score interpretation
Massive social velocity, near-zero mainstream coverage. Strong coverage gap signal.
Strong social momentum with minimal mainstream pickup. Notable coverage asymmetry.
Clear coverage gap developing. Social traction outpacing mainstream coverage.
Significant gap. Story has meaningful social momentum with limited mainstream coverage.
Story has partial or adequate coverage. Social interest modestly exceeds or matches mainstream pickup.
Source Quality Assessment
For Pro users, GapWatch performs AI-powered credibility analysis on each story's sources. Using structured extraction, we assess whether sources contain original reporting or are reposts, whether primary evidence is present, and whether multiple sources trace back to the same origin (circular sourcing). The resulting 0–100 credibility score helps distinguish stories backed by independent corroboration from those amplified through reposting.
Source quality is assessed on-demand when viewing a story and cached for 24 hours. It does not affect the Gap Score calculation — it is a separate trust signal.
“Called It” — Gap Closure Detection
GapWatch tracks whether stories it flags eventually break into mainstream coverage. When mainstream media publishes articles on a topic GapWatch identified 24+ hours earlier with a gap score above 40, we record the “hours to pickup” — how far ahead GapWatch detected the story. This data powers the “Called It” indicators on story pages and the historical proof layer.
Gap closure is checked daily using both NewsData.io article counts and supplementary web searches. A gap is considered “closed” when 5 or more new mainstream media articles are found covering the topic.
AI-generated content
Several surfaces on GapWatch are generated by AI models. Here is a complete disclosure of what is generated, which model is used, and at what tier it is available. All AI calls route through narrative sweep filters that reject sensationalist or first-person language before content is displayed.
Story display headlines (disc stories only)
Dynamically discovered stories receive AI-generated observational headlines (30–100 chars). Headlines are regenerated when the story's gap band changes or after 48 hours. Curated static-topic stories use hand-written titles.
Story synthesis — short ("What People Are Saying")
2–3 paragraph summary of social discussion. Generated after a story accumulates ≥2 posts. Regenerated on gap band change or 48h staleness. Falls back to "Synthesis is being generated" on first cycle.
Story synthesis — long (full deep-read)
5–7 paragraph extended analysis, generated in parallel with the short synthesis. Same regeneration triggers. Available on story pages for Premium and above.
Share card headlines (OG image)
Two-line observational headline for the story's social share card image. Generated in three score bands (critical/high/moderate). Falls back to a deterministic template on first request; the generated headline replaces it on subsequent loads.
Mainstream media article relevance (disc stories)
For dynamically discovered stories, each candidate mainstream media article is evaluated by Haiku before being attached to the story. The judge considers publication date, URL slug, article description, and story context. Fail-open: judgment failures include the article. Replaced the previous keyword-overlap filter, which could not detect temporal mismatches.
Cluster Confidence Score
Every story — both dynamically discovered and curated static-topic — carries a cluster confidence score (0–3) that reflects how strongly the underlying social signal forms a coherent, cross-platform cluster:
- Tier 0 — Noise / unverified. Not displayed publicly.
- Tier 1 — Emerging signal. Single-platform or low post count. Shown in Just Discovered with amber pill.
- Tier 2 — Confirmed. Cross-platform signal with sufficient post count. Eligible for hero feature.
- Tier 3 — Strong. High on-topic post share across multiple platforms.
Sub-metrics persisted alongside the tier: on_topic_share (fraction of posts genuinely on-topic), platforms_contributing (count of distinct platforms), and on_topic_mention_count (raw on-topic post volume). These are used internally for scoring and are available in the admin panel for pipeline inspection.
Limitations & known biases
- English-language bias: Our current data pipeline is weighted toward English-language content. International stories may be under-represented in social velocity calculations.
- Platform API dependencies: X/Twitter API rate limits may cause delays in real-time data for high-velocity stories. We use third-party data aggregators to mitigate this.
- Coordinated inauthentic behavior: Bot-amplified stories can inflate Social Velocity Index. We apply bot-detection filters but they are not foolproof.
- Niche vs. coverage gap: A very niche story may register a high gap score simply because it appeals to a specific community, not because of a genuine coverage gap. Context matters.
- Social media and accuracy: Social media velocity reflects what people are talking about, not what is accurate. High-gap stories include a mix of legitimate underreported news, misinformation, and genuine public interest stories that mainstream outlets have simply not yet covered. GapWatch does not verify claims — it measures the gap.
Mainstream Media Coverage Set
GapWatch monitors 180+ outlets. Coverage set is updated quarterly. Outlet inclusion is based on reach, editorial independence, and geographic diversity — not political lean.
Major National Newspapers
Broadcast & Cable News
Wire Services
Digital Native News
Business & Finance
Science & Technology
International
Specialty & Investigative
Methodology FAQ
What counts as "mainstream media"?
The named outlets in the Mainstream Media Coverage Set above, updated quarterly. Outlets are selected for reach and editorial independence across the political spectrum. No outlet is excluded solely on the basis of political lean.
Which countries and languages are included?
The primary coverage set is English-language. US, Canadian, UK, and Australian outlets are included. International English-language outlets (Al Jazeera English, South China Morning Post, The Guardian) are included. Non-English outlets are not currently in the mainstream coverage set, but social signals from non-English platforms are tracked.
How are stories clustered and deduplicated?
GapWatch uses keyword clustering and semantic similarity to group related mentions into a single story. A post mentioning "Pentagon UAP program" and one mentioning "DoD unidentified aerial phenomena" are grouped as the same story. Duplicate articles from the same outlet are counted once.
How does GapWatch handle bot-amplified virality?
Social velocity is measured against baseline activity levels for each platform and topic category. Sudden spikes that don't show organic engagement patterns (comments, reposts, varied authorship) are weighted lower in the Velocity Score calculation. GapWatch cannot fully filter coordinated inauthentic behavior but applies normalization to reduce its impact.
How do you distinguish organic interest from coordinated manipulation?
We apply subreddit relevance filtering, account age weighting, and engagement-to-impression ratios where available. High mention counts from newly created accounts or single-platform sources are flagged in the Velocity Score.
Is the score based on absolute volume, velocity, or engagement quality?
The GapScore combines both. The Social Velocity Index (SVI) measures rate of mention acceleration, not absolute volume. A story with 40,000 mentions growing at 8,000/hour scores higher than one with 200,000 mentions growing at 500/hour. The Mainstream Media Coverage Index (MCI) measures article count weighted by outlet prominence.
What is the refresh rate?
Stories are refreshed every 15 minutes across all tiers. Each cycle re-fetches social signals (including Reddit /rising + /hot RSS feeds for viral detection), mainstream media article counts, and recomputes gap scores. The pipeline runs on a cron schedule.
How is the "First seen" timestamp determined?
The "First seen" date is set the first time GapWatch detects meaningful social velocity for a story and is permanently preserved — it is never overwritten by subsequent refreshes. This timestamp is the foundation of the "Called It" feature: it proves GapWatch identified a story before mainstream media pickup. The "Last updated" timestamp shown alongside it reflects the most recent data refresh.
What does a GapScore of 100 mean?
A score of 100 means GapWatch detected significant social velocity around a story with near-zero mainstream media coverage in the measurement window. It does not mean the story is true, important, or being deliberately withheld. It means the gap between social attention and mainstream coverage is at maximum. Always verify the underlying source before drawing conclusions.
Questions about our methodology? press@gapwatch.io
Brand Pull — Mackalski Brand Pull Scale
Enterprise tier · Brand Intelligence
The Mackalski Brand Pull Scale classifies each social post about a brand on a 1–5 spectrum of consumer intent: 1 = Strong push (hostile, boycott calls, warnings to avoid the brand), 2 = Mild push (criticism, frustration), 3 = Neutral (informational, ambiguous), 4 = Mild pull (positive, satisfied), and 5 = Strong pull (brand champions — craving posts, enthusiastic advocacy, unprompted recommendations, posting brand slogans with enthusiasm). Classification uses Claude Haiku via the callClaudeWithSweep pipeline, up to 20 posts per snapshot.
The Mackalski Index is computed as:
Range: −100 to +100. A score of 0 is neutral equilibrium. The index measures passion concentration — a brand with 40% lovers and 40% haters scores 0 but is highly polarized, which is distinct from a brand with 80% neutral posts also scoring near 0. The distribution bar shows the full 1–5 spread; the index is a single number that captures the net passion direction.
The display score translates the 1–5 average into a −100 to +100 scale via (avg − 3) × 50. Pull labels are assigned from the display score using the following calibrated bands:
These bands were calibrated to the 1–5 classification scale in May 2026. A display score of +35 corresponds to an average rating of ~3.7/5 — a meaningful majority of respondents leaning positive — which warrants the "strong pull" designation. Earlier thresholds (≥60 for strong pull) were borrowed from NPS conventions and significantly underread on this scale.
Sentiment / Pull divergence signal: When overall sentiment is near-neutral (|sentiment| < 0.10) but the Mackalski Index is meaningfully non-zero (|index| ≥ 20), the brand panel surfaces a divergence annotation. This indicates polarization — a brand with strong lovers and vocal critics can produce near-zero aggregate sentiment while carrying a real pull signal in the distribution tails. This gap is a core use case for the Mackalski framework.
Mackalski Index over time: The brand panel charts the index week-over-week using daily snapshots. The chart highlights a neutral-middle band (±20) — brands trapped in the neutral zone have low passionate engagement in either direction. History draws from all stored snapshots; the 7/30/90-day window selector filters the visible range.
Platform-attributed polarization: Each classified post's platform (Reddit, X, web, news, etc.) is tracked through the aggregation, producing a per-platform distribution. This allows cross-tabbing: which platforms have the highest concentration of level-5 lovers vs. level-1 haters. Platform attribution accumulates from the first snapshot generated after 2026-05-21; earlier snapshots contain the aggregate distribution only.
Changelog
Narrative clustering fix: two bugs caused Haiku theme generation to fall through to n-gram for every brand in the daily cron, producing only 1-2 flat-neutral clusters instead of 5-6 real themes. Bug 1: 'strategically' in the media-bias hard-ban list fires on legitimate brand analysis language. Fixed by adding skipNarrativeBanChecks flag that skips media-bias checks (HARD_BANNED + CONTEXT_BANNED_PATTERNS) for structured JSON output while preserving market directive checks. Bug 2: maxTokens=600 was truncating 5-theme JSON arrays mid-array, causing JSON.parse failures. Increased to 900. Brand Pull label recalibration: pull label thresholds recalibrated from NPS-borrowed values (strong pull ≥60) to scale-appropriate bands (strong pull ≥35, mild pull 10–34, neutral ±9, mild push −10 to −34, strong push ≤−35). Added sentiment/pull divergence annotation when |sentiment| < 0.10 and |Mackalski Index| ≥ 20. Fixed negative-zero formatting in sentiment display.
Brand Pull: added Mackalski Index trend chart (index over time, with neutral-middle band ±20 annotated). Added platform-attributed polarization: each post's platform is tracked through Mackalski classification, producing a 2D platform×level matrix (distributionByPlatform) stored per snapshot. The brand panel now shows the distribution bar per platform and a 7/30/90-day window selector for the trend chart. Platform attribution accumulates from first snapshot after this release; Mackalski index trend draws from all existing historical snapshots.
Search Visibility: added fourth measurement layer tracking whether brands appear in organic category search results (Brave Search API). Pipeline: Haiku generates 5 disambiguation-aware category queries per brand → Brave returns top 10 results → brand presence detected by name/alias match → disambiguation check filters confusor results → structured JSON classifier assigns sentiment score, recommended flag, and reasoning per snippet → Visibility Index (0–100) aggregates presence rate, average position, sentiment, and recommendation rate. Runs weekly (Tuesdays 05:00 UTC), refreshes on first visit if no data exists.
AI Perception parser: replaced keyword-counting parseResponse with a two-part structured prompt. Each LLM now self-classifies its response as a JSON block (mentioned, sentiment, recommended, knowledge_confidence, reasoning). The extractor handles code-fenced output, trailing commas, and single quotes; schema validation catches malformed output and marks rows with parse_status. Adds knowledge_confidence badge (medium/low) and reasoning tooltip to the per-model pull score. Existing rows backfilled by re-querying all four LLMs with the new prompt.
Terminology update: 'legacy media' replaced with 'mainstream media' throughout user-facing copy. 'News discovery platform' updated to 'information discovery platform'. Added 'What this is and isn't' framing section.
AI-generated content: added full disclosure table covering which surfaces are AI-generated, which model is used (Haiku vs Sonnet), and at what tier each is available.
Mainstream media article relevance: LLM-as-judge (Claude Haiku) now evaluates each candidate article for dynamically discovered stories before it is attached to the story. Replaces keyword-overlap filter, which could not detect temporal mismatches (e.g. 2020 articles matching a 2026 story on shared proper nouns). Fail-open: judgment failures include the article.
Cluster confidence: now computed for all stories, including curated static-topic stories. Previously only dynamically discovered stories had confidence scores. Sub-metrics (on_topic_share, platforms_contributing, on_topic_mention_count) are now persisted for pipeline inspection.
AI-generated display headlines: dynamically discovered stories now display Haiku-generated observational headlines (30–100 chars) instead of keyword-derived titles. Curated static-topic stories retain hand-written titles. Headlines regenerate on gap band change or 48h staleness.
Story synthesis: added to story pages. Short synthesis (2–3 paragraphs, Haiku) is free. Long synthesis (5–7 paragraphs, Sonnet) is Premium+. Both regenerate on gap band change or 48h staleness, and require ≥2 posts to generate.
Share card headlines: OG image cards now carry AI-generated two-line headlines (Claude Haiku, observational register) in three score bands. Deterministic fallback template on first request; generated headline persists on subsequent loads.
Initial public methodology documentation. Added platform weighting section explicitly stating aggregate scoring across all platforms with per-vertical empirical weighting on the development roadmap.
Data model: deployed per-platform signal snapshots (story_signal_snapshots table). Each refresh cycle now writes one row per story × platform, enabling 30-day time-series breakdowns. Timeline history extended from 12 hours to 30 days. Hacker News ingestion persisted for ai-tech and finance verticals.