SkillsSkill for Claude

Launch promise tracker from keynotes

Give Claude the link to a product keynote a company you cover published on its own channel, plus its press release, and get a promise table for your model appendix: each starting price, order or ship date, performance multiple against a named base, and capacity or supply figure, with the figure and footnote read from a saved full frame, the presenter's words from the captions, a link to the company's recording at that second, and an empty delivery_status column for next quarter. Press releases drop figures and comparison bases; small availability lines, chart labels and spoken hedges such as a rough timeframe live only on the keynote's screen or in the presenter's voice, and keynotes are full of big numbers that are not promises, so every window Vivu returns is checked against a frame or the captions before it reaches the table.

Maintained by Vivu. Updated 2026-10-15.

Download

launch-promise-tracker.zip

11 KB. Unzips to launch-promise-tracker/SKILL.md. Upload the zip as it is in the Claude app, or unzip it into your skills folder for Claude Code.

SHA-256 f207fd66b41a610f2d318225ddfef2645162d5e4cf1cd27d227c8ae35ddd02e3

At a glance

What the Launch promise tracker from keynotes skill does, where it runs, what it needs, and when it asks
Looks forMoments where a new product's price, order or ship date, performance multiple or capacity figure is shown on a slide or said on stage. Slides carry figures, bases and small availability lines that the press release and captions leave out. Every hit is checked against a full frame of the original video or its captions before it is reported, and figures are never copied from Vivu's reason text.
Runs onClaude Code on your computer (the terminal or the Code tab of Claude Desktop), because it downloads the keynote with yt-dlp from a residential IP, keeps the files locally and runs ffmpeg. Claude on the web and cloud sessions cannot do that. No scheduler: run it once per keynote.
Needs
  • The Vivu connector with write access, to create a private project, open its upload page and search.
  • A shell on a machine with a residential IP, with yt-dlp and node, because YouTube blocks downloads from cloud IPs.
  • ffmpeg and ffprobe, to cut one file per product section, measure lengths and extract frames.
  • English captions for the keynote, because spoken quotes are copied from captions, never from Vivu's reason text.
  • An upload path: the one time upload link opened in your own browser, or a browser tool that can attach local files.
  • The keynote link and the company's press release or agenda, to choose which product sections to index.
Your Vivu planIndexing uses minutes for the product sections you choose, not the whole keynote; searching uses eight precise searches per keynote, an estimate of 40 search credits. Before uploading, the skill measures the sections, reads your remaining allowance and shows minutes and credits against your plan for approval. In our test run six sections from two keynotes came to 47.07 indexed minutes.
Asks you firstIt asks before downloading (platform terms and usage rights), before uploading (index minutes and search credits against your plan), on the sample row and field mapping before writing the table, and before putting the table or note anywhere outside the working folder.

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 keynotes the company published itself; YouTube's terms restrict downloading, so keep files for internal research and do not redistribute video, clips or frames.
  • The table records what was promised and gives no investment advice or credibility judgment; the delivery_status column stays empty for you.
  • Every search result is a candidate that the skill checks against a full frame or the captions before it reaches the table; figures and quotes never come from Vivu's reason text.
  • Spoken searches missed more than on-screen searches in testing, worst on an ad-libbed keynote with auto captions, so a local caption search runs every time; finding a real capacity or supply figure is untested.
  • The videos stay in a private project in your Vivu account until you delete them.
  • Claude in Chrome uploads at most 10 MB per call; larger files go through your own browser or the Vivu web app, never split or recompressed.
  • Putting the table or note in a shared drive, workbook, Notion or Slack acts as you, so the skill shows the rendered note and waits for approval.

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 is the company's keynote from yesterday and its press release. Build me a launch promise table: every price, ship date, performance claim and supply figure, with the slide and what was said, so I can check delivery next quarter.

In Claude Code you can also type /launch-promise-tracker. 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: Get the keynote and choose the product sections
  8. Step 3: Cut one file per section and price the job
  9. Step 4: Upload and index
  10. Step 5: Search
  11. Step 6: Read the on-screen figures from full frames
  12. Step 7: Check the spoken promises in the captions
  13. Step 8: Fill the gaps
  14. Step 9: Write the table and the appendix note
  15. Compliance
  16. Known failure modes

The full skill

This is launch-promise-tracker/SKILL.md from the download, as Claude reads it: the frontmatter first, then the instructions.

---
name: launch-promise-tracker
description: "Turn a company's product keynote into a launch promise table with Vivu: prices, ship dates, performance claims and supply figures read from frames and captions. Use after a keynote you cover."
---

Launch promise tracker from product keynotes

This skill takes the link to a product keynote that a company you cover published on its own channel, plus its press release or agenda, and returns a promise table for your model's appendix: one row per concrete promise in four categories (starting price, order or ship date, performance multiple against the previous generation or a rival, capacity or supply figure), with the product, the time in the keynote, the figure and footnote read from a saved full frame, the presenter's words copied from the captions, a link to the company's recording at that second, and an empty "delivery_status" column you fill next quarter. Claude picks the product sections from the chapters and the press release, downloads them, cuts one file per section, prices the job against the user's Vivu plan, uploads the files to a private Vivu project, runs one on-screen search and one spoken search per category, checks every window against frames or captions, fills the gaps with a local caption search, and writes the table.

The value is in what only the keynote has. Press releases pick some figures and drop others; the comparison base ("vs. AirPods Pro 2", "vs. original AirPods Pro"), the label under a big "2x", a small "Availability Starting March" line under a price row, and spoken hedges such as "around May time frame" exist only on the keynote's screen or in the presenter's voice. A keynote is also full of big numbers that are not promises (hours of user research, peak brightness, transistor counts, last year's product at last year's price). So every window Vivu returns stays a candidate until a full frame or the captions show a promise for a new product, and every figure in the table is copied from that frame or caption, never from Vivu's reason text.

When to use

Use when someone asks "pull every price, date and performance claim from yesterday's keynote into my tracker", "what did the company promise on stage for the new lineup, with timestamps?", "build a launch promise table from the event video so I can check delivery next quarter", or "which numbers were on the slides but not in the press release?".

Not for these:

  1. One question about one keynote ("what did they say the new chip's price is?"): search Vivu directly and look at the frame.
  2. Judging whether a promise is credible, rating the company, or any investment advice. The table records what was promised; the analyst fills delivery_status later.
  3. Following management's answers to the same question across quarters. The earnings-commentary-drift-memo skill (https://vivu.ai/skills/earnings-commentary-drift-memo) is built for that.
  4. Many startups in one recording. The demo-day-traction-sheet skill (https://vivu.ai/skills/demo-day-traction-sheet) is built for that.
  5. Recordings the company did not publish, or a press release alone: read the press release.

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. A screen window is a candidate until a full frame shows the figure; the figure, its label and footnote are copied from that frame. A spoken window is a candidate until the captions show the sentence; the quote is copied from the captions. Vivu's reason text paraphrases and can describe figures that are not on screen, so it never fills a cell.
  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 indexed minutes, before upload) and before anything that acts on their behalf (putting the table anywhere outside the working folder).
  5. A category with no row is reported as "not stated in the keynote sections indexed", which is a finding about the keynote, not about the company. Never fill a gap from the press release, a news story or memory; the press release figure goes in its own column, labeled as such.

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 a machine with a residential IP, with yt-dlp and node YouTube blocks downloads from cloud and datacenter IPs with "Sign in to confirm you're not a bot"; current yt-dlp needs a JavaScript runtime yt-dlp --version, node --version, then the chapter command in Step 2
ffmpeg and ffprobe on the same machine cut one file per section, measure lengths, extract frames and contact sheets ffmpeg -version, ffprobe -version
English captions for the keynote (the uploader's captions, YouTube auto captions, or a local speech to text tool such as whisper.cpp) spoken quotes come from the captions, never from the reason text the download in Step 2 writes a .vtt file; open it
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 keynote link and the company's press release or agenda the press release decides which product sections to index the user pastes both; Step 2 reads the chapters

This skill needs Claude Code on the user's computer (the terminal or the Code tab of Claude Desktop), because it downloads with yt-dlp from a residential IP, keeps the files locally and runs ffmpeg. Claude on the web and cloud sessions cannot do that. Nothing recurs, so no scheduler is involved; run it once per keynote. The only connector it needs is Vivu; putting the table anywhere else uses whichever connector the user names, after approval.

Inputs to collect

Ask for anything missing, most important first.

  1. KEYNOTE_URL: the company's own recording. Required.
  2. COMPANY and EVENT: the company name and a short event label, for example "CES 2025 keynote". Required.
  3. The product sections to index, with start and end times. Default: the chapters whose titles match the products in the press release; leave out openings, partner segments and closings.
  4. Categories. Default: all four (price, date, perf, capacity).
  5. Where the table goes. Default: a local CSV only; anything else (a shared drive, a model workbook, a Notion page) waits for approval in Step 9.
  6. WORK_NAME: a short name for the working folder and the Vivu project. Default: company and event, for example nvidia-ces2025.

Files and state

Keep everything in one working folder:

promises-WORK_NAME/
  config.json            KEYNOTE_URL, VIDEO_ID, COMPANY, EVENT, Vivu project id, query wording, destination
  sections.csv           nn, product, start_s, end_s, file, duration_s, video_id
  source/                the downloaded keynote, its .vtt captions, archive.txt
  segments/              one file per section, named NN_PRODUCT.mp4
  results/               one JSON per search, without the result page link
  frames/                contact sheets and the full frames figures were read from
  candidates.csv         every window Vivu returned, with the verdict and a one line reason
  promise_tracker.csv    one row per verified promise
  appendix_note.md       a short note for the model appendix
  state.json             steps done, files uploaded, searches run with job ids, windows checked

Run every command from the folder that contains promises-WORK_NAME/. A rerun reads state.json first: a file marked uploaded is not uploaded again, a search with a saved result is not run again, and a window with a verdict in candidates.csv is not checked again.

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, node --version, ffmpeg -version and ffprobe -version.

Done when vivu_get_account shows can_create_projects: true and all four commands print a version.

Step 2: Get the keynote and choose the product sections

Goal: the keynote on disk with captions, and one start and end time per product section.

  1. Confirm the Compliance items with the user before downloading.
  2. Read the chapters. VIDEO_ID is the 11 character ID in KEYNOTE_URL:
yt-dlp --js-runtimes node --skip-download --print "%(chapters)s" "https://www.youtube.com/watch?v=VIDEO_ID"
  1. Match chapters to the products in the press release and write sections.csv. Prices and dates are often announced at the end of a product run, sometimes in a later chapter (a watch lineup's prices can sit in the last watch chapter), so check the captions for "starts at", "available" and "pre-order" before fixing the cut points; one short section that holds the closing price and date recap is usually worth more than a long feature chapter.
  2. Download at 720p with English captions. 720p keeps price rows and labels readable at a fraction of the 1080p size; the match filter refuses anything longer than about 100 minutes, which is usually a wrong link (raise it for a longer keynote):
yt-dlp --js-runtimes node --restrict-filenames \
  -f "bv*[height<=720][ext=mp4]+ba[ext=m4a]/b[height<=720]" --merge-output-format mp4 \
  --write-subs --write-auto-subs --sub-langs en --sub-format vtt --sleep-subtitles 2 \
  --match-filter "duration<=6000" \
  --download-archive promises-WORK_NAME/source/archive.txt \
  -P "home:promises-WORK_NAME/source" -o "%(id)s.%(ext)s" --retries 5 \
  "https://www.youtube.com/watch?v=VIDEO_ID"

If it fails with "HTTP Error 403: Forbidden", add --extractor-args "youtube:player_client=web_embedded" and run it again. The youtube-competitor-watch skill (https://vivu.ai/skills/youtube-competitor-watch) covers channel verification and download troubleshooting in more depth.

Done when the keynote and its .vtt file are in source/ and sections.csv has one row per product section with a start and an end.

Step 3: Cut one file per section and price the job

Goal: a file for each section, with its length and price approved before upload.

  1. Cut each section with a re-encode, so the cut points are exact and the file's time plus start_s is the time in the company's recording. PRODUCT is a short lowercase name with no spaces, so Vivu keeps the file name:
ffmpeg -v error -y -ss START_S -to END_S -i promises-WORK_NAME/source/VIDEO_ID.mp4 -c:v libx264 -preset veryfast -crf 23 -c:a aac promises-WORK_NAME/segments/NN_PRODUCT.mp4
  1. Measure each file and write duration_s:
ffprobe -v error -show_entries format=duration -of csv=p=0 promises-WORK_NAME/segments/NN_PRODUCT.mp4
  1. Call vivu_get_usage and show one table:
This keynote Plan allowance Remaining this month
Index minutes sum of duration_s / 60 from vivu_get_usage from vivu_get_usage
Search credits eight precise searches, 40 credits, plus 5 for each rewording (estimate) 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. For example, a keynote whose product sections add up to about 45 minutes fits Premium about three times a month on minutes (estimate); on Free it only fits by indexing the closing price and date recaps, which are often under 20 minutes together, and its 40 credits fit Free once a month (estimate).

  1. If the job does not fit, offer levers in this order: index only the sections where the press release says prices and dates are announced, drop the capacity searches when the company is not a manufacturer, split companies across two months, and only then move to a larger plan. Never drop a section without naming it, and never trim or recompress a section to save minutes.

In our test run the six section files measured 47.07 minutes. The account used in our test run returns no allowance figures, so the plan table and the user's approval were not exercised in our test run.

Done when every section has a file in segments/ with a duration_s, and the user has approved the minutes and credits.

Step 4: Upload and index

Goal: every section file indexed in a private Vivu project.

  1. Call vivu_list_projects and reuse a project named "Keynote 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, and coverage work before a note is published usually should not be.
  2. 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 every file in segments/, or open it in a browser tool that can attach local files. Claude in Chrome accepts at most 10 MB per upload call; larger files go through the user's own browser or the Vivu web app. Never split or recompress a file to fit.
  3. Poll vivu_list_videos until every file shows ready. Vivu replaces spaces and punctuation in file names with "_", which is why the files are named NN_PRODUCT.mp4; match each listed name to sections.csv and record the video_id. When a name does not match, match by length (duration_ms against duration_s).

In our test run all six files were ready about 13 minutes after the upload page was opened, and every listed name equaled the local name. 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 every row of sections.csv has a video_id and every file shows ready.

Goal: saved candidate windows for each category, once on screen and once in speech.

Field Query Mode maximum_results
price_screen a slide or title card on screen showing the price of a newly announced product as a currency amount, such as a starting price under the product name precise 20
date_screen a slide or title card on screen saying when a newly announced product can be ordered, ships or becomes available, with a day, month or season precise 20
perf_screen a slide on screen comparing the new product with the previous generation or a rival product as a multiple or percentage, such as a big number with a label naming what it is compared to, or a bar chart precise 20
capacity_screen a slide on screen with a production, manufacturing capacity, units shipped or supply figure for the product precise 20
price_spoken the presenter says out loud how much a newly announced product will cost or what price it starts at precise 20
date_spoken the presenter says out loud when a new product can be ordered or will be available, ship or go on sale, including a rough timeframe precise 20
perf_spoken the presenter says out loud how many times faster or better the new product is, or by what percentage, compared with the previous generation or a rival precise 20
capacity_spoken the presenter says out loud a production volume, manufacturing capacity, number of units shipped or supply figure precise 20

The price and date screen searches carry the table. The spoken searches add the presenter's words and hedges, and they missed more in our test run, so the Step 8 caption search is part of every run, not an extra. The capacity rows had nothing to find in our test run: neither keynote showed or said a capacity or supply figure, and both capacity searches returned nothing. That shows they did not invent one, but finding a real capacity figure is untested; treat any capacity window as a candidate and check it like the others.

Run vivu_search_videos (project_id, query, mode "precise", maximum_results 20) for each row. fast is not used: it returns whole files with an empty reason, and the file list is already known. maximum_results 20 is above the number of promises one keynote usually has per category and is also the recall ceiling; raise it to 40 for a keynote with more than about ten products. It 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 each result to results/FIELD.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 table, the note or candidates.csv.

The chain: the screen search finds where a figure is shown, the frame check in Step 6 reads it, the spoken search for the same category flips from what is shown to what is said, and the captions in Step 7 give the words to set beside the slide. The queries name the category, never the expected figure or product, so the same table works for any company.

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

Step 6: Read the on-screen figures from full frames

Goal: each screen window labeled kept or rejected, with the figure, label and footnote copied from a full frame.

  1. Make a contact sheet across the window, one frame every half second. A window often holds two or three slides, and a price row or a comparison label may be on screen for only part of it:
ffmpeg -v error -y -ss START -to END -i promises-WORK_NAME/segments/NN_PRODUCT.mp4 -vf "fps=2,scale=320:-1,tile=8x7" -frames:v 1 promises-WORK_NAME/frames/FIELD_NN_START_sheet.png

START and END are the window in seconds (start_ms and end_ms divided by 1000). Tile k is at START plus k/2 seconds, counting from 0 at the top left; a window longer than 28 seconds needs a second sheet from START plus 28. 2. Pick the tile where the slide is fully shown and extract it as a full frame:

ffmpeg -v error -y -ss SECONDS -i promises-WORK_NAME/segments/NN_PRODUCT.mp4 -frames:v 1 -q:v 3 promises-WORK_NAME/frames/FIELD_NN_SECONDS.png
  1. Label the window. Kept: a figure that is a promise for a newly announced product (its price, its order or ship date, a multiple or percentage against a named base, a capacity or supply figure). Rejected: last generation's price, spec numbers with no comparison (hours of battery, nits, transistor counts), research and audience numbers, and windows where the frame shows no figure at all.
  2. Copy the figure exactly as written, units included, and copy the comparison base and any footnote or small line on the same slide into the footnote column. Small text that is not legible at 720p is marked UNCERTAIN; never complete it from the reason text.
  3. Write every window into candidates.csv with its verdict and a one line reason, and count rejected windows as false positives.
Worked example from our test run

The test corpus was two public product keynotes that the companies published on their own channels, a phone and wearables event and a graphics chip keynote, cut by chapter into 6 videos (47.07 minutes): four sections with features and prices, one feature section with no price, one section where a product date was only said. Before searching we went through every section on contact sheets and through the captions, and wrote down each promise by category, plus look-alike numbers that are not promises (hours of user research, peak brightness, battery hours, storage sizes, last generation's price card).

The price search returned 8 windows: 7 real, 1 false, and 1 missed. The false window was last generation's card at last generation's price, which the reason called "its starting price"; Step 6 rejects it because the product is not new. The miss was a laptop price whose card came back later in the section and was found there. The date search returned 4 windows: 4 real, 0 false, and 1 missed, a small "Availability Starting March" line under a price row in a wide shot of the stage screen; it was inside a price window, which is why Step 6 reads every line of a kept frame. The comparison search returned 10 windows: 10 real, 0 false, and 2 missed. It found small "3X Ada", "2X Ada" and "1.5X Ada" labels under spec figures that our own contact sheet tiles were too small to read, so we added those after the search and counted them. The median window was 17.88 seconds wide for prices and 9.9 seconds for comparisons. No query was reworded.

Every figure, label and comparison base we read from a full 720p frame matched the slide, including a four bar GPU chart with percentages against four older phones. Two things only the frame showed: one phone maker's prices fade in after the product names, so the window's middle frame showed the prices dim and the half second sheet was needed to find the tile where they were fully drawn; and one reason added a comparison base ("comparing Ceramic Shield 2 with the original Ceramic Shield") to a slide that only says "3x Better scratch resistance". The footnote column takes the base from the frame or stays UNCERTAIN, never from the reason.

Done when every screen window has a verdict in candidates.csv and each kept window has a frame and its figure.

Step 7: Check the spoken promises in the captions

Goal: each spoken window labeled kept or rejected, with the presenter's words copied from the captions.

  1. Convert the window to the keynote's time: section seconds plus the section's start_s. In a .vtt file the times are on the line above the text, so grep -n "^01:MM:" promises-WORK_NAME/source/VIDEO_ID.en.vtt finds the line numbers for minute MM of the second hour (use ^00:MM: for the first hour); read from the window's start to its end.
  2. Kept: the presenter states a price, a date or timeframe, a multiple or percentage against a base, or a capacity figure for a new product. Rejected: last generation's price, a comparison said with no figure ("a big step up"), or a production remark with no number.
  3. Copy the sentence into spoken_quote. Auto captions mishear amounts and model numbers; when the same figure is on a slide, read it from a full frame (Step 6) and keep both. Never correct a misheard word inside spoken_quote; copy the caption as is and put the frame's reading in parentheses. Mark a quote NOT VERIFIED when there are no captions.

In our test run the spoken searches were weaker than the screen searches. Spoken prices: 5 windows, 4 real, 1 false, 3 missed. All three misses and the false window were in the chip keynote, which was ad-libbed and had only auto captions that misheard the laptop price and the model numbers; the scripted keynote's spoken prices were all found. The false window held a performance comparison and "availability starting January", while its reason said the presenter stated a price there; the price sentence ended a few seconds before the window. Spoken dates: 4 windows, 4 real, 0 false, 1 missed, and the hedged "around May time frame" for a product with no date on screen was found. Spoken comparisons: 6 windows, 6 real, 0 false, 4 missed. Comparisons said with no figure ("a big step up" for a GPU whose chart gave percentages against older phones) were not returned, which is right for this table, and that chart is on screen only.

Done when every spoken window has a verdict in candidates.csv and each kept window has a quote.

Step 8: Fill the gaps

Goal: every category checked in every section, including what the searches missed.

Recall is the weak side, so search the captions locally for each section with no kept window in a category. This is free:

grep -n -i -E "starts? at|\\$[0-9]|available|pre-?order|ship|times|twice|faster|percent|production|capacity|units" promises-WORK_NAME/source/VIDEO_ID.en.vtt

For each caption line inside a section, extract a full frame at that time with the Step 6 command to see whether the figure is also on screen. Mark these rows source_check "caption search" so the analyst knows the search did not find them. Write "not stated in the keynote sections indexed" for a category only after the captions and the contact sheets of the price and date recap at the end of each section have been checked.

In our test run the caption search found every spoken promise the searches missed, including a doubling said with "double" rather than "times", and confirmed that neither keynote gave a capacity figure (only "producing at very large scale" and "in full production") and that the small computer's price was not in the indexed section.

Done when every section and category in sections.csv has either a kept row or "not stated in the keynote sections indexed".

Step 9: Write the table and the appendix note

Goal: a table and a short note the analyst can drop into the model appendix, approved before it goes anywhere.

  1. Show the user one sample row and the field mapping, and wait for a yes before writing the rest:
company,event,product,category,start_mmss,end_mmss,slide_text,footnote,spoken_quote,spoken_mmss,frame,video_link,source_check,delivery_status
COMPANY,CES 2025 keynote,GeForce RTX 5070,price,09:13,09:26,"RTX 5070 | 4090 Performance $549",,"so 5070 490 performance $549 (auto captions; slide says 4090 Performance)",09:41,frames/price_screen_05_559.png,https://www.youtube.com/watch?v=VIDEO_ID&t=1132,frame+captions,
Field Source If unavailable
company, event config.json none
product sections.csv and the slide none
category price, date, perf or capacity none
start_mmss, end_mmss the kept screen window, as MM:SS in the section file the spoken window
slide_text copied from the full frame blank when only spoken
footnote comparison base, small lines and footnotes on the same frame UNCERTAIN when not legible
spoken_quote, spoken_mmss copied from the captions "not said"; NOT VERIFIED without captions
frame path of the frame the figure was read from blank
video_link KEYNOTE_URL with &t= start_s plus the slide time in seconds the time only
source_check frame+captions, frame, captions, or caption search none
delivery_status left empty for the analyst stays empty
  1. Write promise_tracker.csv and appendix_note.md. The note lists promises per product, every place where the slide and the speech differ (a timeframe said but not shown, a price row shown but not said), and the categories not stated. It contains no rating, forecast or recommendation.
  2. Tell the user the counts: kept rows per category, windows rejected, and rows found only by the Step 8 caption search.
  3. Before putting the table or the note anywhere outside the working folder (a shared drive, a model workbook, a Notion page, a Slack channel), name the destination, show the full rendered note, and wait for explicit approval. Email goes to drafts unless the user asks to send.

In our test run the table has one row per kept promise plus "not stated" rows for capacity and for the small computer's price. The user's approval of the sample row and putting the table anywhere were not exercised in our test run, and nothing was sent.

Done when promise_tracker.csv has one row per kept promise, appendix_note.md exists, and the user has approved the sample row and any destination.

Compliance

  1. Use only recordings the company published on its own channel or investor site, and check the platform's terms (YouTube's Terms of Service restrict downloading) and the company's terms. Keep the files for internal research; do not redistribute the video, clips or frames. Confirm this with the user before Step 2.
  2. Presenters are company executives at a public event, but the table is internal. Name companies and products, not people; when a speaker must be named, take the name from the on-screen name card or the agenda. Do not identify anyone by face or voice.
  3. The table records what was promised. It does not judge whether a promise is credible, does not rate the company and gives no investment advice; delivery_status stays empty for the analyst.
  4. The videos stay in the user's Vivu project until the user deletes them. Create the project as private. Delete a project or video only when the user asks, and confirm first.
  5. Putting the table or the note anywhere outside the working folder acts as the user; Step 9 asks first.

Known failure modes

Symptom Cause Fix
(observed) last generation's product card at last generation's price is returned as a price the slide shows a price under a product name, which is what the query asks for Step 6 rejects any price for a product that is not new
(observed) a spoken price window holds no price; its reason says the presenter "states out loud that it delivers" a price the reason pulled a sentence said a few seconds before the window into it copy quotes only from the captions inside the window; check a few seconds before the window when the reason and captions disagree
(observed) the spoken prices of an ad-libbed keynote are missed auto captions mishear figures ("570 laptop for $12.99") and the presenter does not use "starts at" the Step 8 caption search; read the figure from the slide frame
(observed) a small "Availability Starting March" line under a price row is not returned by the date search small text in a wide shot of the stage screen read every line of each kept price frame; dates often sit under prices
(observed) a window's middle frame shows dim or missing prices the price card fades in after the product name pick the tile from the half second contact sheet where the price is fully drawn
(observed) the reason names a comparison base the slide does not show ("comparing Ceramic Shield 2 with the original Ceramic Shield") the reason paraphrases and fills in context take the base from the frame or the captions; otherwise footnote is UNCERTAIN
(observed) a returned comparison window is a wide shot where the labels cannot be read the stage screen is small in a hall shot read the figures from another window on the same slide, or mark UNCERTAIN
the reason text gives a figure that is not on screen the reason paraphrases and has invented prices on other footage copy figures only from a full frame
an empty result for a category the keynote did cover search recall is limited by wording and by maximum_results the Step 8 caption search; an empty result does not prove the keynote had no such promise
"Sign in to confirm you're not a bot" download attempted from a cloud IP run Step 2 on the user's own machine
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 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
a listed file name does not match sections.csv Vivu replaced spaces or punctuation with "_" match by the NN prefix, or by length
"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.