SkillsSkill for Claude

Press briefing fact-check sheet

Give Claude the official recording of a government news conference, its captions, and the four to six figures you need to check. Claude downloads the presentation, prices it against your Vivu plan, indexes it in a private project, runs one precise search per topic, keeps only the windows where the captions show an official saying that topic's figure, reads the slide from a frame, and writes a sheet with the time, the quote, the slide title and figure, whether they agree, and a link to the official video at that second. Transcripts, when an agency posts one, have the spoken numbers but not the charts, and the slide is where the definition and the published figure live.

Maintained by Vivu. Updated 2026-10-02.

Download

press-briefing-fact-check-sheet.zip

11 KB. Unzips to press-briefing-fact-check-sheet/SKILL.md. Upload the zip as it is in the Claude app, or unzip it into your skills folder for Claude Code.

SHA-256 c9031b68867ca319ddf0b473c859137775e00ee5506b2877ff71f72c6750951a

At a glance

What the Press briefing fact-check sheet skill does, where it runs, what it needs, and when it asks
Looks forThe moments where an official states a topic's figure for the year, with the slide on screen at that moment. Neighbouring figures (subgroups, a different measure with a similar name) sit right next to the headline, so every window is checked against the captions before it reaches the sheet, and figures come from the captions and the frame, never from Vivu's reason text.
Runs onClaude Code on your computer (the terminal or the Code tab of Claude Desktop): it needs a shell with yt-dlp, ffmpeg and node, local files, and a residential IP when the briefing is on YouTube. Nothing is scheduled; run it once per briefing.
Needs
  • The Vivu connector with write access, to create a private project, open its upload page and search.
  • A shell with yt-dlp, ffmpeg, ffprobe and node, to download the presentation and cut frames.
  • A residential IP when the briefing is on YouTube, because YouTube blocks cloud IPs.
  • The agency's captions or transcript, because the captions decide each window and supply the quote.
  • An upload path: the Vivu upload page opened in your own browser, or a browser tool that can attach local files.
  • The briefing links and your list of topics.
Your Vivu planIndex minutes for the presentation part of each briefing, plus one precise search per topic. The skill shows the minutes and credits next to your plan from vivu_get_usage and waits for your approval before uploading. In our test run two briefings took 57.75 minutes and the searches used 35 credits (estimate).
Asks you firstBefore searching (the query written for each topic) and using the recordings (rights and YouTube's terms), before uploading (the index minutes against your plan), and before writing the full sheet (one sample row and the field mapping).

The skill does its video work through the Vivu connector. If the connector is not in your Claude yet, add it first; the skill checks that it is connected before it does anything else.

Before you run it

  • Use only recordings the agency published; check the terms for non-federal agencies, and keep downloads for internal checking only.
  • Downloading from YouTube may conflict with YouTube's Terms of Service; confirm your organization accepts it.
  • Search results are candidates: neighbouring subgroup figures and a same number for a different group come back, so each window is checked against the captions.
  • Automatic captions can mishear figures and carry no speaker labels; speakers come only from caption labels, a name bar or the agency's transcript, never from faces or voices.
  • The briefing videos stay in your Vivu project until you delete them; the project is created private because the default is visible to your organization.
  • Claude in Chrome uploads at most 10 MB per call, so briefings usually go through your own browser or the Vivu web app.
  • The sheet puts spoken and on screen figures side by side; it does not judge a figure or contact the agency, and nothing is sent anywhere.

Start it

Once the skill is installed, ask for the task in your own words. Naming the skill is the most reliable way to have Claude use it. For example:

Here are the links to today's Census income and poverty briefing and last year's. Build me a fact-check sheet for median household income, the official poverty rate, the SPM rate, the Gini index and the uninsured rate: when each figure is said, the quote, and what the slide shows.

In Claude Code you can also type /press-briefing-fact-check-sheet. Claude asks for anything the request leaves out, most important first.

What is inside

  1. When to use
  2. Working principles
  3. What you need before starting
  4. Inputs to collect
  5. Files and state
  6. Step 1: Check the Vivu connector and the setup
  7. Step 2: Turn topics into queries and confirm the rights
  8. Step 3: Download the presentation and the captions
  9. Step 4: Price, upload and index
  10. Step 5: Search each topic
  11. Step 6: Check every window against the captions
  12. Step 7: Read the slide from a full frame
  13. Step 8: Write the fact-check sheet
  14. Compliance
  15. Known failure modes

The full skill

This is press-briefing-fact-check-sheet/SKILL.md from the download, as Claude reads it: the frontmatter first, then the instructions.

---
name: press-briefing-fact-check-sheet
description: "Build a fact-check sheet from an agency news conference video with Vivu: per topic, the minute the official states the figure, the quote, and the slide read from a frame. Use on release day."
---

Press briefing fact-check sheet with slide frames

This skill takes the official recording of a government news conference (one to three briefings, downloaded from the agency's website or official channel), the agency's caption file or transcript, and the four to six topics a reporter needs to check, and returns a fact-check sheet: for each topic and briefing, the start and end time where an official states the figure, the sentence quoted from the captions, the slide title and figure read from a full frame at that moment, whether the spoken and the on screen figures agree, the speaker as labeled in the captions or on a name bar, the frame file, a link to the official video at that second, and an empty column for the reporter's own check with the agency. Claude downloads the presentation part of each briefing, prices it against the user's Vivu plan, uploads it to a private Vivu project, runs one precise search per topic, reads the captions inside every returned window to keep only the windows where the topic's figure is actually said, reads the slide from a frame, and writes the sheet.

The value is in what the recording shows and the transcript does not. A transcript, when the agency posts one at all, has the spoken numbers but not the charts; the slide carries the definition that decides what a figure means ("real" versus nominal income, the official poverty rate versus the Supplemental Poverty Measure) and sometimes a number that is rounded differently from what was said. The hard part is that a briefing on a data release states many figures in a row, and neighbouring topics bleed into each other: the official poverty rate and the SPM rate are presented back to back and compared, and the overview at the start repeats every headline. So every window Vivu returns stays a candidate until the captions inside it show an official saying that topic's figure, and no number in the sheet comes from Vivu's reason text.

When to use

Use when a reporter or fact checker says "pull the poverty and income numbers from today's Census briefing with timestamps", "where in the press conference did the director give the budget figure, and what was on the slide?", "make me a check sheet for these five figures from the briefing video", or "did the number on the chart match what the official said?".

Not for these:

  1. A one off question about one figure in one video ("when does she mention the uninsured rate?"): search Vivu directly and read the captions around the hit.
  2. The question and answer part of a briefing. This skill indexes the presentation; reporters' questions and officials' off script answers need their own pass (index the Q&A part and add topics for it).
  3. Deciding whether a figure is right or newsworthy. The sheet puts the spoken figure next to the slide; the reporter checks with the agency and writes the story.
  4. Identifying people by face or voice. Speakers come from the caption labels, a name bar or the agency's transcript only.
  5. Recordings the newsroom has no right to use, such as a paywalled feed.

Working principles

  1. Report measured numbers, not estimates. When a number is an estimate, say so.
  2. Nothing is verified until it has been checked against the source. Every Vivu window is a candidate until the captions inside it show an official saying the topic's figure. Figures come from the captions and the frame, never from Vivu's reason text, which paraphrases and can invent numbers.
  3. Stop and tell the user when a required capability or tool is missing. Do not guess around it.
  4. Ask the user before anything that is expensive to redo (the briefing list and its index minutes, before upload) and before writing the full sheet (one sample row first). The skill sends nothing to anyone and contacts no agency.
  5. Never decide for the reporter. When the spoken and the on screen figures differ or one cannot be read, write that in the row; the agency_verified column stays empty for the reporter.

What you need before starting

Check each item at the start of the run and tell the user plainly what is missing before doing anything else.

Requirement Why How to check
Vivu connector with write access create a private project, open its upload page, search vivu_get_account shows can_create_projects: true (tool names may carry a server prefix). A write call failing with "has not granted vivu.write" means the user reconnects Vivu and allows write access
A shell on the user's computer with yt-dlp, ffmpeg and ffprobe, and node for yt-dlp download the briefing, measure it, cut frames yt-dlp --version, ffmpeg -version, ffprobe -version, node --version
A residential IP, when the briefing is on YouTube YouTube blocks downloads from cloud and datacenter IPs the one video download in Step 3
The agency's captions or transcript for each briefing the captions inside each window decide whether the figure is said, and the quote is copied from them Step 3 downloads the caption file; if there is none, ask for the agency's transcript or a local speech to text tool such as whisper.cpp
An upload path move the files into Vivu vivu_open_upload_page plus the user's own browser, or a browser tool that can attach local files
The briefing links and the topic list topics drive the searches; the links are the source of the video and of the sheet's link column the user pastes them

This skill needs Claude Code on the user's computer (the terminal or the Code tab of Claude Desktop), because it downloads and reads local files and runs ffmpeg. Claude on the web and cloud sessions cannot reach the files, and YouTube blocks their IPs. Nothing recurs, so no scheduler is involved; run it again for the next briefing.

Inputs to collect

Ask for anything missing, most important first.

  1. TOPICS: the four to six figures to check, in the reporter's words (for example "median household income", "official poverty rate", "share without health insurance"). Required.
  2. BRIEFING_URLS: the official recording of each briefing, one to three. Required.
  3. The presentation part of each briefing as start and end times. Default: read the chapter list in the video description, or the first and last lines of the presentation in the captions (the moderator usually says "we'll take your questions"); include the closing recap.
  4. Optional control topic: a figure the reporter expects was not given, to see whether the search invents one. Default: none.
  5. WORK_NAME: a short name for the working folder and the Vivu project. Default: the agency and release date, such as census-income-2023-09-12.

Files and state

Keep everything in one working folder:

briefing-WORK_NAME/
  config.json            topics with their query, briefing URLs, cut times, Vivu project id
  briefings.csv          file, listed_name, source_url, cut_start_s, duration_s, video_id, caption_file
  video/                 the downloaded presentation parts (.mp4)
  subs/                  the caption files (.vtt)
  results/               one JSON per topic: search results without the result page link
  sheets/                contact sheets for kept windows
  frames/                full frames the slide was read from
  candidates.csv         every window Vivu returned, with the caption verdict and the reason
  fact_check_sheet.csv   one row per topic per briefing
  state.json             steps done, files uploaded, topics searched with job ids, windows checked

Run the commands from inside briefing-WORK_NAME/ so the relative paths resolve.

A rerun reads state.json first and skips finished steps: a downloaded file is not downloaded again (the yt-dlp archive file), a file marked uploaded is not uploaded again, a topic with a saved result is not searched again, and a window with a recorded verdict is not checked again. A topic added later is searched against the same project.

Step 1: Check the Vivu connector and the setup

Goal: confirm every requirement before spending anything.

  1. Call vivu_get_account. If the tool does not exist, tell the user to add the Vivu connector in Claude (https://mcp.vivu.ai/mcp) and stop. If the account does not show can_create_projects: true, or a later write call fails with "has not granted vivu.write", ask the user to reconnect Vivu and allow write access, then stop until they have.
  2. Run yt-dlp --version, ffmpeg -version, ffprobe -version and node --version.
  3. Ask for the topics and the briefing links if they are not in the request.

In our test run vivu_get_account returned can_create_projects: true and the four tools were installed. In Step 2, the queries were written by us from the release's own reports; the reporter's approval of the queries and the rights confirmation were not exercised in our test run (the footage is a federal agency's public domain work).

Done when vivu_get_account shows can_create_projects: true, the four tools print their versions, and the user has given the topics and the briefing links.

Step 2: Turn topics into queries and confirm the rights

Goal: one search query per topic, and the user's confirmation that the recordings can be used.

  1. Rewrite each topic as a description of an official saying that figure, in the agency's own terms: "an official states FIGURE_NAME for the year and HOW_IT_CHANGED". Name the measure exactly as the agency does (the Supplemental Poverty Measure is not the official poverty rate), because the search matches what is said, and two measures with similar names are presented side by side. Keep the reporter's wording in config.json next to it; the sheet shows the reporter's wording.
  2. Do not put the figure you expect into the query. A number in the query invites a reason text that repeats it.
  3. Confirm the Compliance items with the user (rights to the recording, YouTube's terms when downloading from YouTube).

Done when the user approves the query list and confirms the Compliance items, and both are saved in config.json.

Step 3: Download the presentation and the captions

Goal: the presentation part of each briefing and its caption file in the working folder.

Run on the user's computer, never in a cloud sandbox. For a briefing on YouTube, get the chapters first; agencies often list the presentation and the Q&A times in the description:

yt-dlp --js-runtimes node --skip-download --write-description --write-subs --write-auto-subs --sub-langs "en,en-US" --sub-format vtt -P "home:subs" -o "%(id)s.%(ext)s" "https://www.youtube.com/watch?v=VIDEO_ID"

Prefer the human captions (.en.vtt with speaker labels) when the agency uploaded them; YouTube's automatic captions mishear names and numbers ("genie index"). Then download only the presentation, at 720p, which keeps chart labels readable:

yt-dlp --js-runtimes node --restrict-filenames -f "bv*[height<=720]+ba/b[height<=720]" --merge-output-format mp4 --download-sections "*START-END" --download-archive archive.txt -P "home:video" -o "BRIEFING_%(id)s.%(ext)s" --retries 5 "https://www.youtube.com/watch?v=VIDEO_ID"

VIDEO_ID is the 11 character ID in the link, START and END the presentation times as HH:MM:SS, and BRIEFING a short label such as cb2023. --restrict-filenames keeps the names to letters, digits and underscores, so they come back from Vivu unchanged. A file cut at START has its own clock: file time plus START is the time in the official video, so record cut_start_s in briefings.csv. For an agency website that offers an mp4, download it directly and cut nothing. If yt-dlp prints "HTTP Error 403: Forbidden", retry once with --extractor-args "youtube:player_client=web_embedded,default".

The youtube-competitor-watch skill (https://vivu.ai/skills/youtube-competitor-watch) covers channel verification and download troubleshooting in more depth.

In our test run both presentations downloaded at 720p with the web_embedded client named above, along with their caption files. One briefing had human captions with speaker labels; the other had only automatic captions, which wrote "Gini" as "genie" and garbled one spoken figure.

With --download-sections yt-dlp re-cuts the section through ffmpeg, which is slower than a plain download of the same length.

Done when video/ holds one mp4 per briefing, subs/ holds a caption file for each, and briefings.csv lists file, source_url and cut_start_s.

Step 4: Price, upload and index

Goal: every presentation indexed in a private Vivu project, with the user's approval of the cost.

  1. Measure each file: ffprobe -v error -show_entries format=duration -of csv=p=0 video/FILE, where FILE is the presentation file in video/ (for example cb2023_VIDEO_ID.mp4). Write duration_s.
  2. Call vivu_get_usage and show one table:
These briefings Plan allowance Remaining this month
Index minutes sum of duration_s / 60 from vivu_get_usage from vivu_get_usage
Search credits 5 per topic, 25 for five topics (estimate), plus 5 for each rewording from vivu_get_usage from vivu_get_usage

Plan facts: Free is $0 a month with 20 index minutes a month and 50 search credits a month; Premium is $30 a month with 180 index minutes and 500 search credits. A precise search uses 5 credits in total. Two briefings with a 30 minute presentation each are about 60 index minutes (estimate): Premium covers that, Free covers part of one.

  1. If the briefings do not fit, offer levers in this order: index only the presentation (not the Q&A), index one briefing first, and only then move to a larger plan. Never drop a briefing the user asked for without saying which one, and never trim or recompress a file to save minutes.
  2. Call vivu_list_projects and reuse a project named "Briefings WORK_NAME" if one exists; otherwise call vivu_create_project with that name and visibility "private". The default visibility is organization, which shows the project to everyone in the user's Vivu organization; unpublished story work belongs in a private project.
  3. Call vivu_open_upload_page with the project ID immediately before uploading. The link expires in 180 seconds and works once, so never post or store it. Give it to the user to open in their own browser and select the files, or open it in a browser tool that can attach local files. Claude in Chrome accepts at most 10 MB per upload call and a briefing is larger, so briefings normally go through the user's own browser or the Vivu web app. Never split or recompress a file to fit.
  4. Poll vivu_list_videos until every file shows ready. Vivu replaces spaces and punctuation in file names with underscores; with --restrict-filenames the names already match. Record each video_id in briefings.csv and state.json.

In our test run the two presentations measured 57.75 minutes and were both ready about 15 minutes after the upload started; each duration_ms equaled the ffprobe length and the names matched. The account used in our test run returns no allowance figures, so the comparison with a real plan and the user's approval were not exercised in our test run. The files went through the upload page with an automated browser, so opening the link in the user's own browser was not exercised in our test run.

Done when the user has approved the index minutes, and every file in briefings.csv shows ready and has a video_id.

Step 5: Search each topic

Goal: a saved list of candidate windows for every topic.

One precise search per topic, because each topic is its own row. Every search is precise: only precise returns a time window, and fast returns whole files with an empty reason, which tells you nothing the briefing list does not. The chain behind each row: the precise search suggests windows where an official says the figure, the captions inside each window decide whether that topic's figure is really said there (Step 6), and a frame from the same window gives the slide (Step 7). That last step is the flip from what is said to what is shown: the slide title carries the definition and the figure as published.

Run vivu_search_videos (project_id, query, mode "precise", maximum_results 10) for each topic. Ten covers the usual places a headline figure is said in one presentation (the opening overview, the presenter's section, the closing recap) across two or three briefings, plus the subgroup figures that Step 6 has to set aside; it is also the recall ceiling, so for more than three briefings raise it. vivu_search_videos returns a job ID; call vivu_get_search_results until complete is true. Each status call can wait up to 45 seconds, so a pending search is not a stalled one. Save the results to results/TOPIC_KEY.json without the result page link, and show the result page link only in the live reply: it expires after four hours, so it never goes into the sheet or candidates.csv.

The queries from our test run, on two Census Bureau income, poverty and health insurance briefings, show the pattern:

Field Query Mode maximum_results
median_income an official says how much real median household income changed from the year before and gives the new median household income figure precise 10
income_inequality an official reports the change in income inequality measured by the Gini index precise 10
official_poverty an official states the official poverty rate for the year and how many people were in poverty precise 10
spm_poverty an official states the Supplemental Poverty Measure (SPM) rate for the year and how it changed precise 10
uninsured an official gives the headline uninsured rate for the whole population this year: the percentage and the number of people who had no health insurance at any point in the year; not a rate for one age, income or work group, and not a chart of earlier years precise 10
control (optional) an official states the homeownership rate for the year precise 10

In our test run the uninsured wording above came after 1 rewording on the same corpus. The first wording ("an official states the share of people without health insurance for the year") returned 10 windows, 5 of them false: uninsured rates for children in poverty, for workers and for age groups, a trend chart, and a sentence saying the rate had not changed. Saying "the whole population" and naming what does not count removed all five. The control topic, never mentioned in either briefing, returned 0 windows. In our test run the seven precise searches (five topics, one rewording and the control) came to 35 credits (estimate: 5 per precise search).

When a topic's first page has subgroup windows, reword it the same way. A rerun is one more precise search.

Done when every topic has a saved result file and its job id is in state.json.

Step 6: Check every window against the captions

Goal: each window labeled "figure said" or "other", before anything reaches the sheet.

  1. For each window, convert start_ms and end_ms to seconds and read the caption lines whose times fall inside it. Caption times are in the official video's clock: add cut_start_s to the window first. In a .vtt file the times are on the line above the text, so grep -n "^00:MM:" subs/VIDEO_ID.en.vtt finds the lines for minute MM. VIDEO_ID is the briefing's YouTube ID from briefings.csv; use .en-US.vtt or the auto-caption file if that is what Step 3 saved.
  2. Label the window:
    • figure said: an official says this topic's figure for the whole population and the year (in the presenter's section, the opening overview or the closing recap);
    • other: a subgroup figure (children, workers, a region), a different measure, a trend with no figure for the year, or a sentence that the figure did not change.
  3. Write every window with its label and the caption line that decided it into candidates.csv, and count the "other" windows as false positives for the topic. Vivu's reason text never decides the label.
  4. For each topic and briefing keep one "figure said" window, preferring the presenter's section over the overview and recap, because that is where the chart for the figure is shown.
  5. A topic with no "figure said" window in a briefing gets a row saying "not found in the indexed presentation" and goes back to the user.
Worked example from our test run

The test corpus was two public news conferences from the U.S. Census Bureau's official channel on its income, poverty and health insurance release (two different years), cut to the presentation and recap: 57.75 minutes in all, slides with charts and highlight bullets, one briefing with human captions and one with automatic captions only. Before searching we marked in the captions, for five topics, every place an official says the topic's figure: the presenter's section (the main statement, one per topic per briefing) and the overview and recap repeats.

On the first wordings the five topic searches returned 37 windows: 31 real and 6 false. After 1 rewording of the uninsured query on the same corpus, the final wordings returned 29 windows: 28 real and 1 false, and 0 main statements missed. The official poverty rate and the SPM rate, presented back to back and compared with each other, never crossed. The one false window on the final wordings is the trap this step exists for: the official says how far the SPM child poverty rate rose, and the child rate is the same number as the headline SPM rate that year; the slide on screen is "SPM Poverty Rates by Age". Only the captions and the slide title tell the two apart; the reason text called it the SPM rate.

Every number in the reason texts in our test run matched the captions or the slide, and one reason gave a count with the slide's decimal where the official had said "about". The figures in the sheet still come only from the captions and the frame. Per topic, the median window was 12 to 23 seconds wide, often starting or ending on the neighbouring slide.

Done when every window in results/ has a label and a caption line in candidates.csv, and each topic has a kept window or a "not found" note for each briefing.

Step 7: Read the slide from a full frame

Goal: for each kept window, the slide title and figure on screen, read from the picture.

  1. Cut a contact sheet across the kept window, one frame every half second, because windows often start on the previous slide and end on the next:
ffmpeg -v error -y -ss WIN_START -to WIN_END -i video/FILE -vf "fps=2,scale=240:-1,tile=8x6" -frames:v 1 sheets/TOPIC_KEY_BRIEFING.png

WIN_START and WIN_END are the kept window's start_ms and end_ms divided by 1000, in seconds in the file (not the official video's clock). One sheet holds 24 seconds; a longer window needs a second sheet from WIN_START plus 24. Tile k is at WIN_START plus k/2 seconds, counting from 0 at the top left. Pick a tile where the slide for this figure is fully shown. 2. Extract that moment as a full frame and read it:

ffmpeg -v error -y -ss SECONDS -i video/FILE -frames:v 1 -q:v 3 frames/TOPIC_KEY_BRIEFING.png

FILE is the presentation file in video/ (for example cb2023_VIDEO_ID.mp4), SECONDS is WIN_START plus k/2 for the tile you picked, TOPIC_KEY is the field name from the query table (for example official_poverty), and BRIEFING is the label from Step 3.

  1. Write the slide title and the figure exactly as shown ("11.4 percent", "$67,500", "0.489"). When the slide has no figure for this topic (a chart with no label for the year, a title slide), write "not on slide". When the text cannot be read, write UNCERTAIN; never complete it from the captions or the reason.

In our test run the slide title and figure were readable in all ten kept windows at 720p, including the briefing where the slide is shrunk next to a presenter tile. Some slides carried the level but not the change or the count that the official said; the sheet says so instead of marking a mismatch.

Done when every kept window has a frame in frames/ and a slide_title and slide_figure value (or "not on slide" or UNCERTAIN).

Step 8: Write the fact-check sheet

Goal: a sheet the reporter can check against and quote from.

  1. Show the user one sample row and the field mapping, and wait for a yes before writing the rest:
topic,briefing,file,start,end,spoken_quote,spoken_figure,slide_title,slide_figure,match,speaker,frame,source_link,transcript_checked,agency_verified
official poverty rate,2020 data (2021-09-14),cb2021_o6t84kGR20c.mp4,12:57,13:28,"The official poverty rate in 2020 was 11.4% -- up 1 percentage point from 10.5 percent in 2019.",11.4%; 37.2 million,"Highlights: Official Poverty",11.4 percent; up 1.0 point; 37.2 million,same,caption label (income and poverty presenter),frames/official_poverty_cb2021.png,https://www.youtube.com/watch?v=o6t84kGR20c&t=777,yes,
Field Source If unavailable
topic the reporter's wording from config.json none
briefing, file briefings.csv none
start, end the kept window in the file, as MM:SS none
spoken_quote, spoken_figure copied from the captions inside the window NOT VERIFIED when there are no captions
slide_title, slide_figure read from the full frame (Step 7) "not on slide" or UNCERTAIN
match same, differs (say how), or partial (say what is only spoken) UNCERTAIN
speaker the caption's speaker label, a name bar in the frame, or the agency's transcript UNCERTAIN
frame path of that frame blank
source_link the official video link with t equal to cut_start_s plus start, in seconds file name and time
transcript_checked yes when Step 6 labeled the window from the captions no
agency_verified left empty for the reporter stays empty
  1. Write fact_check_sheet.csv, one row per topic per briefing.
  2. Tell the user the counts: rows written, rows where spoken and slide differ or one is missing, topics not found, windows set aside in candidates.csv.

In our test run the sheet has 10 rows. All ten matched; some of them say that a change or a count was spoken but not printed on the slide. The five rows from the briefing with automatic captions have speaker UNCERTAIN, because those captions carry no speaker labels and no name bar was on screen. The user's approval of the sample row was not exercised in our test run.

Done when fact_check_sheet.csv has one row per topic per briefing (kept or "not found"), the user has approved the sample row, and the counts are reported.

Compliance

  1. Use only recordings the agency published. Work by U.S. federal government employees in their official duties is in the public domain; state, city and other agencies' recordings can carry their own terms, so check the terms or ask the press office before Step 3. Keep the downloads for the newsroom's checking work and do not redistribute the video or clips.
  2. Downloading from YouTube may conflict with YouTube's Terms of Service. Have the user confirm this is acceptable for their organization before Step 3, or use the agency's own mp4 when it offers one.
  3. Download to the user's computer and upload from there. The skill does not hand video links to a third party importer.
  4. Speakers come from the caption labels, a name bar on screen or the agency's transcript. The skill does no face or voice recognition and does not identify reporters heard in the room.
  5. The videos stay in the user's Vivu project until the user deletes them. Delete a project or video only when the user asks, and confirm first.
  6. The sheet puts the spoken and the on screen figures side by side. It does not judge whether a figure is right, and it contacts no one; the reporter checks with the agency and fills agency_verified.

Known failure modes

Symptom Cause Fix
(observed) a topic's first page has windows for children, workers or an age group the subgroup figures follow the headline in the same section and use the same words label them "other" in Step 6; reword the query to ask for the whole population and name what does not count, as the uninsured query did (5 of 10 false before, 0 of 2 after)
(observed) a window has the same number as the headline but for a different group the SPM child poverty rate equaled the headline SPM rate that year; the reason text called it the SPM rate read the captions and the slide title ("SPM Poverty Rates by Age"); never accept a window because the number matches
(observed) a window has no figure at all the official says "no statistically significant change in the uninsured rate" or introduces a trend chart label it "other"; the sheet needs the figure for the year
(observed) automatic captions turn a figure into words that are not a number YouTube's automatic captions garbled the spoken figure as "Cantu was" read the slide from the frame, mark spoken_figure UNCERTAIN, and listen to that second of the video before quoting
(observed) the window starts or ends on the neighbouring slide precise windows are wider than the sentence and cross slide changes pick the frame from the half second contact sheet, not the window's first or middle second
(observed) speaker is UNCERTAIN for a whole briefing automatic captions carry no speaker labels and no name bar was on screen use the agency's transcript or the speaker list in the video description, and say which
a reason text gives a figure that is not in the captions or on the slide the reason paraphrases and can invent numbers never copy a figure from the reason; quote the captions and read the frame
a topic gets no "figure said" window the briefing did not give that figure, or the query uses a different name for the measure than the agency write "not found in the indexed presentation"; reword once with the agency's term; an empty result does not prove the figure was never said
a figure given only in the Q&A is missing the skill indexes the presentation only index the Q&A part as its own file and add the topic
yt-dlp prints "HTTP Error 403: Forbidden" YouTube refused the default player client retry with --extractor-args "youtube:player_client=web_embedded,default"
"Sign in to confirm you're not a bot" download attempted from a cloud IP run Step 3 on the user's computer
upload page asks to sign in or shows an error the one time upload link expires after 180 seconds request a new link right before opening it
a briefing file is rejected by the browser upload tool Claude in Chrome accepts at most 10 MB per upload call the user opens the upload link in their own browser or adds the file in the Vivu web app
"has not granted vivu.write" Vivu connected read only the user reconnects Vivu with write access

Connect Vivu, then add the skill.

The skill runs through the Vivu connector. Add it to Claude from the connector directory, then install the skill.