AI Data Copilot

Download the channel's data as a SQLite file, paste it into Claude or ChatGPT with any prompt below, and ask questions YouTube Studio can't answer. No SQL required.

Data through Apr 28, 2026

YouTube's reporting tends to lag 2–3 days behind real time. Newer activity may not yet appear.

This database was built at 2026-04-30T16:38:21.176Z. Daily aggregates typically reflect data through 2026-04-28.

schema v42

What we tested

Conventional beliefs about YouTube — does each apply to this channel?

Conventional wisdom about YouTube is usually true on average. The interesting question is whether it's true on thischannel. Each card tests one belief against this channel's data and reports agrees, disagrees, inconclusive, or not currently testable.

  • Beliefdisagrees
    High click-through-rate drives video success more than high retention.

    On this channel: 0.11×· ctr over retention· agrees ≥ 1.5× — the belief disagrees here.

    n = 19, high confidence.

    How this is computed
    Per video, scale CTR and retention to channel-relative units (each
    value's distance from the channel's median, divided by the channel's
    typical spread). Fit a linear regression of total views against both.
    If the magnitude of the CTR coefficient is at least 1.5× the retention
    coefficient, the data agrees that CTR dominates on this channel.
    

    Source: MrBeast school of creator advice; widely contested.

  • Beliefdisagrees
    Videos 8–10 minutes long perform best for ad revenue and watch time.

    On this channel: 20 min· retention 29%· belief expects 10 min — the belief disagrees here.

    n = 16, high confidence.

    How this is computed
    Bucket videos by duration (60/180/360/600/1200/1800/3600+ sec). Median
    weighted CTR, AVD, retention pct, sub conversion per bucket. Agrees if
    600s bucket has the highest median weighted retention pct.
    

    Source: Creator-economy folklore; pre-2018 mid-roll-ad threshold.

Have a YouTube belief you want tested? or email it directly. Useful submissions get added to the canon — credit appears in the card's source line.

Honesty

What this dataset doesn’t say

A page in an atlas marked “survey conducted under ice cover” is not weakened by the footnote — it’s strengthened. The columns below name the conditions under which every other chart in this dashboard was drawn.

Reporting lag

YouTube reports two to three days behind.

Data flows reliably through 2026-04-28. The dashboard never charts past that date — it would be zeros dressed as truth. Reporting time zone is America/Los_Angeles; a “day” here is a calendar day in PT, not your local time.

Stub rows

7 videos have pre-publish stub rows.

When a video is scheduled, YouTube sometimes records reporting rows for the day before it published — usually a row of zero views and null impressions. Every chart and aggregate filters these out (the pre_publish_stub = 0guard in every summary CTE). These stubs stay in the database for provenance — they’re how we know YouTube did this on this channel.
Per-video pre-publish stub counts (top 5)
Video 91 stub days
Video 101 stub days
Video 111 stub days
Video 121 stub days
Video 131 stub days

Click-rate confidence

Where the click-rate sample is thin, the dashboard says so.

Click rate from fewer than 50 impressions is noise. From 50 to 249 it’s directional. From 250 to 999 it’s readable. From 1,000 or more it’s reliable. The four-segment dotted glyph after every click-rate cell encodes which tier — fewer dots means a thinner sample.

Watch-time confidence

The same tiering applies to average watch time.

Below 10 views, average watch is noise. 10 to 29 is directional. 30 to 99 is readable. 100 or more is reliable. The same four-segment glyph after every average-watch cell.

Source gaps

7% of impressions don't trace to a source.

YouTube’s per-source impression rows don’t always sum to the per-video impression total. The gap is real — some impressions come from sources YouTube doesn’t expose. We surface the gap rather than redistribute it.

989 unattributed of 14,526 total impressions.

Snapshot drift

Channel-level views match the sum of per-video views.

The channel snapshot (my-channel-snapshotsin the database) sometimes shows totals slightly higher than the sum of per-video reporting rows. This is YouTube’s own attribution gap; we chart it instead of hiding it.
How is this computed?
The timezone YouTube reporting uses for per-day rollups.
All dates in the public DB are calendar days in YouTube's reporting timezone (America/Los_Angeles, PT), not the visitor's local timezone. A "day" here is a calendar day in PT — a video published at 22:00 PT on Apr 27 will accumulate that day's reporting under the date 2026-04-27, even for viewers in UTC+12.
Flag (0/1) on every per-video reporting row indicating whether the row sits before the video's published_at.
Set to 1 when the row's date is earlier than SUBSTR(published_at, 1, 10). Every summary_* CTE that aggregates over per-video reporting must include WHERE pre_publish_stub = 0 so the seven-row stub artifact (NULL impressions, 0 views) doesn't poison aggregations. The flag itself stays in the DB for downstream provenance.
Sample-size confidence tier for the row's click-through rate; one of noise / low / medium / high.
Derived from the row's impressions sample size. Noise tier when impressions < 50; low when < 250; medium when < 1000; high otherwise. The thresholds are calibrated so that a noise-tier CTR is statistically meaningless (one or two clicks against a tiny denominator).
Sample-size confidence tier for the row's average view duration; one of noise / low / medium / high.
Derived from the row's view sample size — the denominator AVD averages over. Noise tier when views < 10 (one or two viewers' watch time, statistically meaningless); low when views < 30; medium when views < 100; high otherwise. Mirrors the V10 ctr_confidence pattern but keyed on views instead of impressions.
Per-date drift between the channel-level views snapshot and the sum of per-video views.
MAX(0, channel_daily.total_views - SUM(video_daily.views WHERE pre_publish_stub = 0)) per date. Reads >0 when the channel-snapshot total exceeds the sum of attributed per-video reporting (e.g. deleted videos, late attribution). Floored at zero so reporting overcounts (per-video sum exceeds channel snapshot — also possible during transient lag) don't render as negative drift.

Channel state · publishing cadence

The trailing 28-day publish strip plus the detected pattern. Descriptive only; the strip is the channel’s observed rhythm, not a recommendation about when to publish.

Publishing cadence appears after the first 28 days.

Channel state · view distribution

How unevenly views and subscribers are distributed across the catalog over time. A higher Gini means a few videos carry most of the recent views or subscribers; a lower Gini means the distribution is more even. Both shapes are common at different channel stages.

Questions you can ask your data

Start here

Consultant analysis — top 5 observations

The closest thing to a paid YouTube analyst — evidence-based, no fluff.

I've uploaded an anonymized YouTube analytics SQLite database from a real channel. Videos are labeled "Video 1", "Video 2", etc. Analyze all tables and give me your top 5 specific, evidence-based observations about this channel — things the creator might not have noticed. Include the actual numbers.

Diagnose growth

Is the channel growing, flat, or declining?

View velocity, spikes, and drops across the channel over time.

I've uploaded a YouTube analytics SQLite database. Query the video_daily table and analyze the daily trends. Is the channel's daily view count growing, flat, or declining? Are there any days with unusual spikes or drops? What's the view velocity (views per day) for the most recent videos vs. the earliest ones?

Is day-1 performance a predictor of lifetime views?

Whether early signals reliably forecast long-term outcomes.

I've uploaded a YouTube analytics SQLite database. Look at the summary_video table's day1_views, day1_impressions, and day1_ctr columns. Is there a relationship between day-1 performance and lifetime performance? Do videos that start strong continue strong, or is day-1 noise?

Understand the audience

Where are viewers actually finding these videos?

Browse-driven vs Suggested-driven vs Search — by video.

I've uploaded a YouTube analytics SQLite database. Query the traffic_daily and summary_traffic tables. For each video, show me the percentage of views from Browse/Homepage vs. Suggested Videos vs. YouTube Search. Are some videos "Browse videos" and others "Suggested videos"? What distinguishes them? Is there a pattern by publish date or video duration?

How does click rate behave over a video's lifetime?

Does CTR stay stable, or does it drop as YouTube expands the audience?

I've uploaded a YouTube analytics SQLite database. Query video_daily for CTR over time for each video. Does CTR typically start high and decline (as YouTube expands to less-targeted audiences), or does it stay stable? Which video had the most consistent CTR? Which had the biggest CTR drop? What does this tell us about YouTube's impression allocation strategy?

Inspect individual videos

Which videos have potential that hasn't been discovered yet?

Videos with above-average click rate but below-average views.

I've uploaded a YouTube analytics SQLite database. Query the summary_video table and find any videos where weighted_ctr is above the channel average but total_views is below average. These are videos that performed well on click rate but did not accumulate many views. What patterns do you see in their titles, durations, or traffic sources? What factors might explain the gap between click rate and views?

Which videos keep getting views — and which flashed and died?

Flash pattern vs evergreen across the catalog.

I've uploaded a YouTube analytics SQLite database. Query the video_daily table, filtering by days_since_publish. For each video, show me how views decay over time. Which videos had the steepest decay (flash pattern)? Which maintained views longest (evergreen pattern)? Plot the normalized decay curves if possible.

Which videos convert impressions into watch time most efficiently?

How much viewing time each thumbnail impression generates.

I've uploaded a YouTube analytics SQLite database. The summary_video table has a watch_min_per_impression column — this measures how much watch time each thumbnail impression generates. Which videos are most efficient at converting impressions into watch time? Is there a correlation between video length and this metric?

Which videos turn viewers into subscribers?

Subscriber conversion rate across the catalog.

I've uploaded a YouTube analytics SQLite database. Look at the subs_per_1k_views column in summary_video. Which videos are best at converting viewers into subscribers? Is it the high-view videos or the high-engagement ones? What does this suggest about which content to make more of?

Go deep

Complete channel audit

Comprehensive read across every table — what's moving, what's flat, what's surprising.

I've uploaded a YouTube analytics SQLite database with tables: summary_channel, summary_video, video_daily, traffic_daily, summary_traffic, summary_era, summary_channel_daily, summary_traffic_daily, summary_traffic_top_videos, channel_daily. This is a real, anonymized channel. Give me a comprehensive audit: what's working, what's not, what's surprising, and what questions would you ask the creator based on this data?

How does this channel compare to typical creator-stage benchmarks?

The AI compares against public creator-stage research it knows about — hedged.

I've uploaded a YouTube analytics SQLite database. Based on public creator-stage research you know about — typical views per video, CTR ranges, subscriber growth curves for channels at a similar stage — how does this channel's data compare? Where do the numbers look unremarkable for the stage, and where do they stand out? Note that benchmarks vary widely by niche, audience, and content type, so treat any comparison as a rough reference rather than a target.
Sample SQL queries (for SQL writers)

Copy any of these into a SQLite client (or paste them into your AI alongside the .db file). Each one exercises a column added this round.

Videos that were watched but not clicked

High retention, low click rate — quality signal without reach.

SELECT video_id, weighted_ctr, avg_retention_pct, total_views
FROM summary_video
WHERE ctr_quadrant = 'watched-not-clicked'
ORDER BY total_views DESC;

Channel's 28-day weighted click rate over time

Smoothed channel-wide click rate, NULL while the window is incomplete.

SELECT date, weighted_ctr_28d
FROM summary_channel_daily
WHERE weighted_ctr_28d IS NOT NULL
ORDER BY date;

How concentrated is each video's source mix?

source_hhi is the Herfindahl index over the per-video source shares (0..10000).

SELECT video_id, primary_traffic_source, source_hhi
FROM summary_video
WHERE source_hhi IS NOT NULL
ORDER BY source_hhi DESC;

Videos that took longest to get a Browse / Homepage impression

Days from publish to the first Browse impression on each video.

SELECT video_id, days_to_first_browse_imp
FROM summary_video
WHERE days_to_first_browse_imp IS NOT NULL
ORDER BY days_to_first_browse_imp DESC
LIMIT 10;

Channel's source diversity over time

Simpson 1 - Σ share² over the trailing-7d source share. Higher = more spread out.

SELECT date, source_diversity_score, top_video_share_7d
FROM summary_channel_daily
WHERE source_diversity_score IS NOT NULL
ORDER BY date DESC
LIMIT 30;

Top video week by week

Which video held the largest share of channel views in each rolling 7-day window.

SELECT date, top_video_id_7d, top_video_share_7d
FROM summary_channel_daily
WHERE top_video_id_7d IS NOT NULL
ORDER BY date;

Quiet inventory — videos with no views in the prior 7 days

Track how many of the channel's published videos went view-less in each rolling window.

SELECT date, videos_with_zero_views_7d, quiet_inventory_pct
FROM summary_channel_daily
WHERE quiet_inventory_pct IS NOT NULL
ORDER BY date;

Avg Watch drift — videos whose recent average watch is longer than the first 3 days

Positive drift = recent viewers stay longer than the early audience did.

SELECT video_id, avg_avd_sec, avd_drift_sec
FROM summary_video
WHERE avd_drift_sec IS NOT NULL
ORDER BY avd_drift_sec DESC
LIMIT 10;

Per-video source-share daily — who sent views on which day

Long-format trailing-window source share. Useful for stacked-area charts.

SELECT date, traffic_source_id, share_7d, views_7d
FROM summary_channel_source_share_daily
WHERE share_7d IS NOT NULL
ORDER BY date DESC, share_7d DESC
LIMIT 50;

Which AI should I use?

These prompts work best with Claude, ChatGPT Plus, or Gemini Advanced— they need file upload and long-context reasoning. Free-tier models will often fail silently on the bigger queries (like "Complete channel audit"). If you have access to Claude Projects or custom GPTs, upload the .db once and keep asking questions.

Where each metric comes from

Subscriber columns come from two independent YouTube APIs. subs_total_eod is a daily snapshot from the Data API. subs_gained and subs_lost are deltas from the Analytics API. Drift between them is expected — they sample at different times of day and use different rounding rules. Each column is authoritative for its own purpose.

FieldAPI source
views, watch_time_minutes, avg_view_duration_sec, avg_view_pct, subs_gained, subs_lost, likes, comments, sharesYouTube Reporting API + Analytics API (reconciled)
impressions, ctrYouTube Reporting API (reach reports)
engaged_views, dislikesYouTube Analytics API only
Country, device_type, subscribed_status dimensionsYouTube Reporting API
Schema changelog (v5 – v42)

One row per schema version, newest first. Reading theschema_versiontable directly returns the same data.

  1. v422026-04-29L-16 — summary_detector_activity table. New per-detector aggregation table populated by scripts/build-detector-activity.js after dashboard/scripts/generate-snapshots.ts has written the insight_snapshot history. One row per detector_name with total_fires, first_fired_date, last_fired_date, highest_significance, and the snapshot_date that carried that highest_significance. Empty at clean-build time (insight_snapshot has no rows yet); populated when refresh-public.js completes its finalize step. The /help/detectors master list page (L-17) reads this table via getDetectorActivity() to render fired vs not-yet-fired groupings.
  2. v412026-04-28A-30 — Calc hygiene + metric_metadata + indexes. New metric_metadata table (metric_id, definition, source_tables, computation_doc, confidence_method, last_modified) populated from scripts/metric-metadata.yaml at build time; consumed by /data tile tooltips so "How is this computed?" reads from a single source. Index audit: the eight Round-3 indexes (idx_svcd_video_date, idx_svcd_country_date, idx_sccd_country_date, idx_mzd_metric_date, idx_wt_status_date, idx_wt_test_date, idx_vsd_video_date, idx_cal_country_date) all use CREATE INDEX IF NOT EXISTS for build-rebuild idempotence. Time-zone documentation: data_status gains a reporting_timezone row pointing at America/Los_Angeles (PT) so the dashboard's honesty surfaces read the timezone from one source. Schema-history consistency check (scripts/schema-history-check.js) extends the prior tail-equality assertion with three new failure modes — version skip / gap, non-monotonic order, and position-by-position mismatch with a hard-coded EXPECTED_SCHEMA_HISTORY_VERSIONS sequence — so future schema arithmetic regressions fail the build with precise diagnostics.
  3. v402026-04-28A-25 — Honesty surface column. summary_channel_daily gains unattributed_channel_views INTEGER, populated post-insert as MAX(0, total_views - SUM(video_daily.views WHERE pre_publish_stub = 0)) per date. The column makes the per-date snapshot drift between channel-level views and the sum of per-video reporting rows readable directly from one column instead of recomputing every render. Powers the new <HonestyPanel> on /data (six sub-sections naming reporting lag, pre-publish stub rows, click-rate confidence distribution, AVD confidence distribution, unattributed impressions, and the channel-snapshot reconciliation chart) plus a one-line <HonestyDigest> in the Coda chapter on /. The digest reads "Data flows reliably through {cutoff}; per-source attribution is at {pct}%; click-rate sample tier today: {tier}." with a link to the full panel; the third clause omits when reconciliation is sparse. Observation-only voice; the surface is reference content, not a verdict.
  4. v392026-04-28A-23 — AVD confidence tier columns. summary_video, summary_traffic, and video_daily each gain an avd_confidence TEXT column (one of noise / low / medium / high) derived from the row's view sample size: noise < 10, low < 30, medium < 100, high otherwise. Mirrors the V10 ctr_confidence pattern but keyed on views (the denominator AVD averages over) instead of impressions. Persisting the tier alongside the value lets every UI surface that renders an AVD value wrap it in <AvdConfidencePip> — strikethrough on noise, muted on low, full on medium / high — without recomputing the threshold per call site. Same A-23 ships StageChip + VideoMiniStack visual chrome on /videos rows + comparison-band reuse on per-video charts; those are presentation-only and do not bump the schema.
  5. v382026-04-28A-19a — Wisdom canon foundation. Two new tables: wisdom_canon (50 rows loaded from scripts/wisdom-canon.yaml — one per conventional belief, with belief_text, calculation_doc, evidence_shape in {single-ratio, correlation, delta, share-distribution, count-tier, not-applicable}, and agrees_directionality in {positive, negative, neutral}) and wisdom_test (one verdict row per (test_id, snapshot_date) with status in {agrees, disagrees, inconclusive, not_currently_testable}, an optional inconclusive_reason that classifies into thin_sample / near_threshold, evidence_json, confidence, sample_size, prior_status, status_changed_today, and the not_yet_implemented flag the runner sets while the per-test impl files are still landing). New scripts/wisdom-runner.js loads the canon yaml on every build, populates wisdom_canon idempotently, and emits 50 wisdom_test rows: every requires_owner_mode / requires_cross_channel / not_currently_testable_reason entry short-circuits to status not_currently_testable; every testable entry with a per-test file at dashboard/src/lib/wisdom/tests/<test_id>.ts dispatches and writes a real verdict; every testable entry without an implementation file gets a placeholder row with not_yet_implemented = 1. Three anchor implementations land in this slice: frequency_cannibalization (single-ratio), first_24_48h_determines_fate (correlation), title_changes_reset_algo (delta). A-19b lands the remaining 26 testable implementations across multiple sessions; the architecture cannot regress because the runner already passes all 50 entries with the placeholder fallback.
  6. v372026-04-28A-17 + A-18 — Cadence classifier, cadence break events, day-of-week trend (A-17), plus library Gini coefficient and Lorenz half-mass count (A-18). A-17 ships channel_cadence_daily (one row per date with a classified publishing pattern: daily, every_other_day, weekday_only, weekly_3x, weekly, irregular; conformance percentage over the trailing 28 days; days_since_break that resets on each divergence) and the cadence_break channel_timeline event emitted on each break day after the channel held the pattern for at least seven days. Two TEXT JSON columns on summary_channel: publish_gap_distribution (histogram of inter-publish gaps in days) and day_of_week_trend (per-weekday twelve-week slope of channel views). A-18 layers three new columns on summary_channel (gini_views, gini_subs, library_half_life_days — the third counts top videos sorted desc by views needed to reach half of total channel views, populated as a Lorenz half-mass count) plus two trailing 28-day rolling Gini columns on summary_channel_daily (gini_views_28d, gini_subs_28d). The Coda chapter renders a hedged "{M} of {N} videos" callout from gini_subs against the Lorenz curve; /data renders a distribution-evolution line chart of the two daily Gini series. Observation-only voice across all surfaces; both extremes (concentrated vs even) are legitimate channel patterns.
  7. v362026-04-28A-16 — Days-to-N velocity columns. summary_video gains seven INTEGER columns: days_to_10_views, days_to_100_views, days_to_500_views, days_to_1000_views (cumulative-views milestones, populated by the same per-video walk that already produces days_to_50_views), plus days_to_first_comment, days_to_first_like, days_to_first_share (day offset where the cumulative engagement count first reaches one). All seven columns hold NULL when the milestone has not landed yet, mirroring the days_to_first_subscriber convention. summary_channel gains two INTEGER columns: median_days_to_100_views and median_days_to_1000_views — channel medians across videos that have crossed each milestone, NULL when fewer than one eligible video exists. The /videos/[id] discovery-unfolded strip extends to surface the new milestones inline alongside the existing days_to_first_* values; the Catalog chapter on the home page renders a hedged channel-median callout. Pure-data slice; observation-only voice.
  8. v352026-04-28A-14 + A-15 — Engagement composite, velocity, two new detectors, plus subscriber granularity. A-14 ships engagement_weights (default likes=1, comments=5, shares=3) and three columns on summary_video: engagement_rate_composite (weighted-engagement-events / total_views; NULL when total_views = 0), engagement_velocity_24h (likes + comments + shares from the first 24 hours since publish), engagement_velocity_7d (the same sum over the first 7 days). Two new detectors: comment-outliers fires per-video when comments-per-100-views runs at least 3x the channel median (sprouting+); engagement-leads-views runs a cross-correlation between engagement spikes and view spikes per video at lag 3-7 days (growing+). Both route through emerging_signal via evidence.shape. The chip on /videos/[id] surfaces the 24h and 7d velocity values; the new <EngagementVelocityChart> renders them as a two-bar Recharts BarChart. A-15 layers subscriber granularity on top: summary_traffic gains subs_gained INTEGER (per-(video, source) total_subs_gained allocated proportionally by view share; YouTube does not break subs out by source so the value is an inference) and funnel_engaged_views INTEGER (SUM(engaged_views) from reporting_traffic_metric per (video, source)); summary_video gains days_to_third_subscriber and days_to_fifth_subscriber (extends the days_to_first_subscriber pattern, walks video_daily for the day cumulative subs_gained reaches 3 / 5). channel_timeline.event_type adds subscriber_event for milestone-only channel-wide subs (every 5th up to 100, every 10th past 100, every 25th past 500, every 100th past 1k) — replaces the prior milestone-typed subscriber rows so the Story dispatcher can target the new event type explicitly. New <SubFunnelChart> mounts on /traffic/[sourceId] rendering impressions → views → engaged → subs as a horizontal Recharts BarChart; new sub-rate-vs-view-rate detector fires when the trailing 28-day sub-rate slope and view-rate slope diverge (audience-quality-improving / volume-without-depth shapes routed through emerging_signal). Observation-only voice across both slices.
  9. v342026-04-28A-12 + A-13 — Z-score machinery and step-change scaffolding. A-12 ships metric_zscore_daily (date, metric, value, baseline_mean, baseline_sd, zscore, sample_size; PK on (date, metric)) holding per-(date, metric) z-scores against a prior 28-day baseline for five tracked metrics: daily_views, weighted_ctr, weighted_avd, sub_gain_rate, total_impressions. Each row reads the 7-day trailing mean as the value, prior 28-day mean and sd as the baseline; baseline window must hold at least 28 non-null values or the z-score stays NULL. summary_channel_daily.anomaly_score_composite reads SUM(ABS(zscore)) per date so the Opening rail anomaly markers fire on multi-metric outlier days. The new metric-anomaly detector reads z > 2 outliers in the trailing 7 days and routes through the existing emerging_signal slot via evidence.shape. A-13 layers six new columns on summary_channel_daily: trailing 14-day OLS slopes for top_video_share, top3_video_share, source_diversity, quiet_inventory, and channel-level country HHI, plus recent_debut_trend_14d (relative delta between recent-14-day and prior-30-day mean day1_impressions across the catalog). A-13 also adds a CUSUM step-change scan over four channel-level rolling series (views, click rate, avg watch, subs gained) emitting step_change channel_timeline events when the maximally-separating split is at least 30% relative magnitude and sits at least 7 days from either series boundary. The new recent-debut-trend detector reads summary_video and surfaces the recent-vs-prior comparison as a single channel-scope insight at growing+ maturity. Observation-only voice across all surfaces.
  10. v332026-04-28A-11 — Audience persistence and replacement, plus the emerging_audience event type. summary_channel_daily gains two REAL columns: audience_persistence_pct (share of last week's (source, country) buckets that also appeared the prior week) and audience_replacement_rate (share of last week's buckets that did not appear the prior week). Computed as a JS pass over reporting_traffic_metric on the source DB; one weekly comparison written per ISO week-ending row in summary_channel_daily, with NULL on dates that do not fall on a week boundary. A new emerging_audience event_type emits one channel_timeline row per (traffic_source_id, country_code) bucket that did not appear in the channel's first 14 days yet drew at least 50 views in the last 28 days; headline names the country, then the source. The Audience chapter mounts a two-bar gauge showing the persistence and replacement values with arrows reading the most recent two weekly comparisons; both states (high persistence vs high replacement) are legitimate channel patterns at different ages.
  11. v322026-04-28A-10 — Sticky-traffic ratio and algorithmic dependency index. traffic_source gains an is_sticky 0/1 column (sources where the viewer chose to come back: Direct, Channel Page, Playlist, End Screen, link-clicks from off-platform, subscriber notification; everything else is algorithmic discovery). summary_video adds sticky_traffic_ratio (0..1 share of total_views from sticky sources, NULL when no traffic rows). summary_channel adds algorithmic_dependency_index (1.0 minus the channel-wide sticky share). summary_channel_daily adds two columns: per-day algorithmic_dependency_index and a trailing 28-day OLS slope of that index (units: index points per day, NULL when fewer than 14 daily values fall in the trailing window). The Audience chapter mounts a new <StickyTrafficSparkline> tile that renders the per-day index as a sparkline against a hedged qualifier; per-video pages render a small sticky-traffic chip. Both extremes (high and low ratio) are legitimate channel patterns; the value is observation, not verdict.
  12. v312026-04-28A-09 — Channel temperature and country diversity. summary_channel_daily gains two new REAL columns: temperature_score (a 0..100 weighted blend of trailing CTR, AVD, sub-rate, source diversity, and library activity z-scores against the prior 90-day baseline; 50 reads as the channel's own normal, 60 as a warmer week than typical for this channel, 40 as a cooler week than typical) and country_diversity_score (Simpson form 1 - sum(share^2) over the per-date top-country shares from summary_channel_country_daily). Both columns require at least 35 days of baseline; below that they stay NULL. Adds two channel-scope detectors that share the emerging_signal slot via evidence.shape: algorithmic_thaw fires when channel-wide impressions ran at or above 2x their prior 14-day median for two or more consecutive days, and algorithmic_frost fires on the symmetric drop (impressions at or below 50 percent of the prior 14-day median for two or more days). Both maturity-gated to sprouting+. The 5th tile on the home page right-now strip renders the score, a 14-day sparkline, and a hedged qualifier sourced from EVOLUTION section 4.1 ("warmer than typical" / "your normal" / "cooler than typical") so the channel position is observation, not verdict.
  13. v302026-04-28A-08 — Channel-scope co-movement events and anomaly composite scaffolding. Two new channel_timeline event types ship on default builds: multi_video_activation (a day where three or more videos each ran at or above 2x their prior 7-day rolling mean views) and cohort_lift (an ISO-week publish cohort whose median trailing-7-day views climbed at least 30 percent over the prior week while older cohorts stayed flat within plus-or-minus 10 percent). Two new detectors (multi-video-activation, cohort-lift) emit the same patterns as Insight objects routed through the existing emerging_signal slot via evidence.shape. summary_channel_daily gains the anomaly_score_composite REAL column; the column stays NULL on default builds until A-12 ships the metric_zscore_daily table that populates it (sum of absolute z-scores across tracked metrics per date). The Opening rail container exposes the data-testid="anomaly-marker-rail" hook so the smoke gate can catch a SQL-join-key class of regression at build time even before A-12 lands.
  14. v292026-04-28A-05 + A-06 — Lifecycle daily classifier and stage-transition timeline. A-05 ships the new video_stage_daily table (per-(video, date), one of nine stages: pre_publish / debut / growth / peak / tail / quiet / re_emerged / zombie / dormant) populated by a deterministic JS pass over video_daily anchored on summary_video.peak_views_day. Eight new columns on summary_video persist the latest stage (lifecycle_stage), the per-stage day spans (days_in_growth, days_in_peak, days_in_tail), the time from peak to half-of-peak rolling views (tail_half_life_days), and three survives-day-N flags (survives_day_7 / 14 / 30) gated on cumulative views at day N reaching the channel-median cumulative views at the same day. A-06 layers a stage_transition channel_timeline event type on top — emitted from diff of consecutive video_stage_daily rows, filtered to meaningful transitions only (any transition INTO re_emerged / zombie / dormant, any transition OUT of quiet, plus peak -> tail) — and adds three detectors that read the persisted stages: zombie-impressions, dormant-video, and channel-level video-re-emergence. Eight columns plus the transition events let the catalog grid read current stage and trajectory health without touching video_daily; downstream slices (A-23 StageChip, A-27 story dispatcher, A-29 video timeline strip) read these directly.
  15. v282026-04-28A-04 — Country composites on summary_video. Five derived columns (country_hhi, dominant_country_code, dominant_country_share, country_concentration_with_weak_retention, country_audience_match_score) populated by a post-summary pass over the coarsened summary_video_country rows. HHI mirrors source_hhi shape (sum of squared shares × 10000); the concentration boolean fires when one country holds >= 40% share of a video and that country watches >= 30% shorter than the video overall; the match score is the cosine similarity between this video distribution and the channel-wide well-retaining country distribution (countries weighted by views from videos retaining at or above the channel median). Pairs the country dimension with the existing source_hhi to characterize concentration on two independent axes; the geographic-concentration detector now reads the persisted boolean instead of recomputing per-insight.
  16. v272026-04-28A-02 + A-03 — Daily country tables and country_activation_log. summary_video_country_daily (per-(video, country, date)) and summary_channel_country_daily (per-(date, country)) ship in default builds, populated from reporting_video_metric with cutoff and pre-publish guards. The daily resolution unlocks per-video country stream charts on /videos/[id] and the channel country river on /traffic; downstream slices read these tables for activation logs, audience-swap detection, and per-country sub-funnel cohorts. Long-tail rows below the 5% per-video share threshold collapse into the same "OT" bucket the lifetime tables use. A-03 layers the country_activation_log table (per-(video, country) first-active and first-meaningful >= 5 views dates) on top, plus a first_country_view channel_timeline event (one per country the channel has reached, significance 50) so the Story dispatcher can render geographic-reach milestones once A-27 wires it.
  17. v262026-04-28A-01 — Country tables default-public. The two tables (summary_video_country, summary_channel_country_trailing30) now ship in default builds, with --coarsen-country-mix on so countries below 5% share collapse to "OT" (Other). The owner-mode flag still suppresses summary_video_subscribed plus summary_channel_device. The country dimension on its own does not deanonymize an English-language channel (top countries cluster around US/IN/GB/CA on essentially every channel); the prior owner-mode gate hid the most diagnostic dimension in the dataset.
  18. v252026-04-27Reverts V23 (CLOSE-B-51) coarsening of video.published_at and summary_video.published_at to YYYY-MM-01. The collapse to first-of-month broke the cadence detector (every channel misclassified as "schema-ambiguous"), the per-date predicates in the dashboard, and the publish-date scatter (every dot landed on a single vertical line); the privacy gain was marginal because per-video age is already exposed via days_tracked, view trajectories, and the timeline. duration_seconds bucketing remains in place — it carries genuine de-anonymization risk (a precise integer-second runtime is rare enough to be fingerprintable) without the downstream collateral. The --show-precise-metadata flag still toggles the duration bucketing for owner-mode rebuilds.
  19. v242026-04-27Count consistency across surfaces. summary_channel.total_public_videos now counts videos with published_at <= latest_data_date (the reporting cutoff) instead of joining through video_daily, so videos published right at/after the cutoff stop being silently dropped from the count. summary_channel.total_days_tracked now derives from (latest_data_date - first_video_date + 1) so the days span and the public-video count align by construction for daily posters. summary_channel_daily.cumulative_videos_live is recomputed from precise source-side publish dates instead of the noisy data-api channel_snapshot.video_count, and two new columns most_recent_video_id (TEXT) and days_since_last_publish (INTEGER) let the dashboard render per-date "videos live" + "Video N is X days old" without recomputing from coarsened video.published_at (CLOSE-B-51 silently broke that path).
  20. v232026-04-27Coarsened publish_date and duration_seconds in default builds so the public DB cannot be cross-referenced to identify the channel: video.published_at and summary_video.published_at snap to YYYY-MM-01; video.duration_seconds and summary_video.duration_seconds snap to one of eight bucket lower bounds (0/60/180/360/600/1200/1800/3600). Coarsening runs as a final UPDATE pass after all derived columns (day3/day7 cohorts, days_to_first_*, peak_views_day, summary aggregates) are computed against precise values, so build-time math is unaffected. Owner-mode rebuilds with --show-precise-metadata skip the UPDATE and preserve full precision.
  21. v222026-04-27Owner-mode tables (summary_video_country, summary_video_subscribed, summary_channel_country_trailing30, summary_channel_device) suppressed by default; pass --include-owner-tables to emit them. Stage-1 public deploys ship without these tables; the dashboard read helpers hard-assert NEXT_PUBLIC_OWNER_MODE=true as defense-in-depth. The legacy --show-channel-name flag is removed.
  22. v212026-04-27Covering index idx_insight_snapshot_cat_date on insight_snapshot(insight_category, snapshot_date) — detectShapeChange and any future category-scoped snapshot lookup now use an index SEARCH instead of falling back to idx_snapshot_date and re-checking insight_category row by row.
  23. v202026-04-27Covering index idx_traffic_daily_source_date on traffic_daily(traffic_source_id, date) — homepage Browse-impression activity card now uses an index SEARCH instead of a full traffic_daily scan (~91k rows on a 200-video fixture).
  24. v192026-04-27Foreign-key constraints on junction tables (video_daily, traffic_daily, video_era, summary_video, summary_era, summary_traffic, summary_channel_traffic, summary_traffic_daily, summary_traffic_top_videos, source_activation_log, summary_traffic_daily_history, summary_channel_source_share_daily, summary_video_country, summary_video_subscribed) — orphan video_id / traffic_source_id rows now raise SQLite errors when a writer enables PRAGMA foreign_keys. The dashboard read-only client opens the DB with PRAGMA foreign_keys = ON for belt-and-suspenders enforcement.
  25. v182026-04-27pre_publish_stub filter applied to source_activation_log and summary_traffic_daily_history build SELECTs — longitudinal storage tables now exclude pre-publish stub rows so trip events on /traffic/[sourceId] and the Spine no longer reflect zero-view pre-publish dates.
  26. v172026-04-27Impression-weighted CTR formula (SUM(impressions * ctr) / SUM(impressions)) on summary_video.day3_ctr / day7_ctr and summary_traffic_daily_history.weighted_ctr — replaces the views/impressions shortcut so cohort and per-day source CTR match the canonical weighted_ctr definition.
  27. v162026-04-26date-only indexes on video_daily and traffic_daily so date-range scans no longer fall back to a full table scan.
  28. v152026-04-26source_diversity_score + top_video_share_7d + top3_video_share_7d + top_video_id_7d + videos_with_zero_views_7d + quiet_inventory_pct columns on summary_channel_daily.
  29. v142026-04-26Rolling 7d / 28d columns (views, watch_min, impressions, weighted_ctr) on summary_channel_daily; new summary_channel_source_share_daily long-format table.
  30. v132026-04-26ctr_quadrant column on summary_video (winner / clicked-not-watched / watched-not-clicked / quiet / noise) with median_video_ctr + median_video_retention on summary_channel as the crosshairs.
  31. v122026-04-26imp_to_view_ratio + avd_drift_sec + source_hhi on summary_video; imp_to_view_ratio_median on summary_channel.
  32. v112026-04-26Day-3 / Day-7 cohort columns + velocity (days_to_first_*) + peak_views_day/value + late_growth_pct on summary_video.
  33. v102026-04-26ctr_confidence tier (noise / low / medium / high) + unattributed_impressions on video_daily, traffic_daily and summary_video.
  34. v92026-04-26pre_publish_stub flag on video_daily / traffic_daily — flags rows where date < published_at so summary aggregations can exclude them.
  35. v82026-04-26Owner-mode F-tier tables: summary_video_subscribed, summary_channel_country_trailing30, summary_channel_device.
  36. v72026-04-25weighted_ctr column on summary_traffic (per-(video, source) impression-weighted CTR).
  37. v62026-04-25Per-(video, country) views-only aggregation in summary_video_country.
  38. v52026-04-25Longitudinal storage tables (source_activation_log, channel_phase_log, summary_traffic_daily_history) so daily history survives rebuilds.

The data is anonymized by default — video titles and IDs are stripped. Privacy-preserving but fully analyzable.