---
name: bill-hearing-remarks-brief
description: "Turn official committee hearing videos on one bill into a brief with Vivu: per issue you track, who spoke, when, what they said, and a link to that second. Use for state or local hearings."
---Bill hearing remarks brief
This skill takes the official recordings of the committee hearings on one bill (one to three hearings this session, usually from the legislature's own YouTube channel or video archive), the bill number, and the three to five issues a government affairs team tracks (for example enforcement, preemption of local rules, exemptions, how the bill compares with other states), and returns a one page hearing brief: for each issue and hearing, the start and end time where a legislator, the bill author or a witness talks about it, a one line gist, the sentence quoted from the captions, who was speaking as shown on the name caption or called on by the chair, the frame that shows it, a link to the official video at that second, and an empty follow up column for the team. Claude cuts each recording down to this bill's agenda item, prices it against the user's Vivu plan, indexes it in a private Vivu project, runs one precise search per issue, reads the captions inside every returned window to keep only the windows that are really about that issue, reads the speaker's name caption from a frame, and writes the brief. After the user approves a sample, Claude posts it to the team's Slack channel or Notion page.
The value is in what the recording holds and nothing else does. Most state and local committees publish no transcript; the video is the record. Automatic captions exist but carry no speaker labels and mishear names, so whether a sentence came from the bill author, a committee member or a trade association witness is only visible on screen (the lower third name caption) or audible in the chair calling on someone. The hard part is that a hearing on a long bill moves through neighbouring provisions in one breath: a walkthrough of section 12 (enforcement) runs straight into section 13 (preemption), and "keeping the bill in line with the other chamber" sounds like "lining up with other states". So every window Vivu returns stays a candidate until the captions inside it show the issue being discussed, and the quote comes from the captions, never from Vivu's reason text.
When to use
Use when someone on a government affairs, public policy or association team says "pull every place the enforcement section came up in the two committee hearings on SF 2915", "who testified about preemption and what did they say?", "build a hearing brief on our four issues before Thursday's markup", or "find where members talked about exemptions in last week's hearing and post it to our policy channel".
Not for these:
- A one off question about one moment in one hearing ("when did the author mention the effective date?"): search Vivu directly and read the captions around the hit.
- Reading years of archives to build a timeline of an issue across many bills. This skill indexes only this bill's agenda items in this session's hearings.
- Predicting votes, scoring legislators or writing lobbying talking points. The brief lists what was said in public, side by side, and nothing more.
- Identifying people by face or voice. Speakers come only from the on screen name caption, the chair calling on them, or the committee's own minutes.
- Floor sessions and press conferences. They need different issues and different cuts; the press-briefing-fact-check-sheet skill covers agency briefings.
Working principles
- Report measured numbers, not estimates. When a number is an estimate, say so.
- Nothing is verified until it has been checked against the source. Every Vivu window is a candidate until the captions inside it show the issue being discussed. Quotes come from the captions, never from Vivu's reason text, which paraphrases.
- Stop and tell the user when a required capability or tool is missing. Do not guess around it.
- Ask the user before anything that is expensive to redo (the hearing list and its index minutes, before upload) and before anything that acts on their behalf (posting the brief to Slack or Notion; one rendered sample first).
- Never fill a speaker from a guess. When neither a name caption nor the chair's call identifies the speaker, the speaker cell stays empty and says so.
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, ffprobe and node | download the hearing and its captions, cut it, measure it, extract frames | yt-dlp --version, ffmpeg -version, ffprobe -version, node --version |
| A residential IP, when the hearings are on YouTube | YouTube blocks downloads from cloud and datacenter IPs | the caption download in Step 3 |
| Captions for each hearing (YouTube's automatic captions are enough) | the captions decide each window and supply the quote | Step 3 downloads them; if a hearing has none, ask for the committee's minutes or a local speech to text tool such as whisper.cpp, and mark quotes NOT VERIFIED until one is available |
| 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 |
| Slack or Notion connector with access to the destination (only for Step 9) | post the approved brief | read the channel or open the page once |
| The bill number, the hearing links and the issue list | issues drive the searches; the links are the source of the video and of the brief'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 after the next hearing and add the new file to the same project.
Inputs to collect
Ask for anything missing, most important first.
- BILL: the bill number and short title as the committee calls it (for example "SF 2915, consumer data privacy"). Required.
- ISSUES: three to five issues in the team's words (for example "enforcement and who pays for it", "preemption of city ordinances", "exemptions", "how it compares with other states"). Required.
- HEARING_URLS: the official recording of each committee hearing on the bill, one to three. Required.
- The bill's agenda item in each recording as start and end times. Default: the time index in the video description when the committee posts one; otherwise the chair's call of the bill ("we have Senate file NNNN in front of us") and the final motion ("be recommended to pass") found in the captions in Step 3.
- DESTINATION: the Slack channel or Notion page for the brief. Default: none; the brief stays in the working folder.
- Optional control issue: something the team suspects was never discussed, to see whether the search invents it. Default: none.
- WORK_NAME: a short name for the working folder and the Vivu project. Default: the bill number and session, such as sf2915-2024.
Files and state
Keep everything in one working folder:
hearings-WORK_NAME/
config.json bill, issues with their query, hearing URLs, agenda cut times, Vivu project id, destination
hearings.csv file, hearing, source_url, cut_start_s, duration_s, video_id, caption_file
video/ the downloaded agenda items (.mp4)
subs/ the caption files (.srv1, timestamped)
results/ one JSON per issue: search results without the result page link
frames/ frames the speaker was read from
candidates.csv every window Vivu returned, with the caption verdict and the reason
hearing_brief.csv one row per kept window
hearing_brief.md the brief as it will be posted
state.json steps done, files uploaded, issues searched with job ids, windows checked, post status
Run the commands from inside hearings-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, an issue with a saved result is not searched again, a window with a recorded verdict is not checked again, and a brief marked posted is not posted again. A hearing added later is uploaded to the same project and every issue is searched again, keeping only windows on the new video.
Step 1: Check the Vivu connector and the setup
Goal: confirm every requirement before spending anything.
- 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 showcan_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. - Run
yt-dlp --version,ffmpeg -version,ffprobe -versionandnode --version. - If the user wants the brief posted, check the Slack or Notion connector by reading the channel or opening the page once.
- Ask for the bill, the issues and the hearing links if they are not in the request.
In our test run vivu_get_account returned can_create_projects: true, and yt-dlp, ffmpeg and ffprobe ran in the later steps. The Slack or Notion connector check was not exercised in our test run, because nothing was posted.
Done when vivu_get_account shows can_create_projects: true, the four tools print their versions, and the user has given the bill, the issues and the hearing links.
Step 2: Turn issues into queries and confirm the rights
Goal: one search query per issue, and the user's confirmation that the recordings can be used.
- Rewrite each issue as a description of someone in the hearing talking about it: "someone discusses ISSUE_IN_PLAIN_WORDS: DETAIL_A, DETAIL_B or DETAIL_C". Name the two or three concrete things that make the issue its own (for enforcement: the attorney general's authority, a private right of action, the attorney general's cost and staff), because the search matches what is said, and a long bill's sections run into each other.
- Write who may be speaking ("a legislator, the bill author or a witness") instead of a name. Vivu does not identify speakers, and a name in the query invites a reason text that repeats it.
- Keep the team's own wording in config.json next to each query; the brief shows the team's wording.
- Confirm the Compliance items with the user: the legislature's terms for its recordings, and YouTube's terms when downloading from YouTube.
In our test run we wrote the four queries ourselves for a consumer data privacy bill; the user's approval of the queries and the rights confirmation in Step 2 were not exercised in our test run (internal testing only).
Done when the user approves the query list and confirms the Compliance items, and both are saved in config.json.
Step 3: Download the captions, find the agenda item, download it
Goal: this bill's agenda item from each hearing and its timestamped captions in the working folder.
Run on the user's computer, never in a cloud sandbox. Get the description and the captions first; srv1 captions put each line's start second in the file, which makes finding the bill and reading a window a plain text search:
yt-dlp --js-runtimes node --skip-download --write-description --write-auto-subs --write-subs --sub-langs "en" --sub-format srv1 -P "home:subs" -o "%(id)s.%(ext)s" "https://www.youtube.com/watch?v=VIDEO_ID"
VIDEO_ID is the 11 character ID in the hearing link. If the description has a time index for the bill, use it. Otherwise find the chair's call of the bill and the final motion; BILL_DIGITS is the bill number without letters (2915 for SF 2915):
grep -o '<text start="[0-9.]*" dur="[0-9.]*">[^<]*BILL_DIGITS[^<]*' subs/VIDEO_ID.en.srv1
The first line where the chair says the bill is "in front of us" or asks the author to "proceed" is the start, and the line with "recommended to pass", "laid over" or "re-referred" is the end. Add 10 seconds at both ends. A bill that appears in a hearing for only a minute (introduced and laid over) has nothing to brief; tell the user and leave that hearing out.
Then download only the agenda item, at 720p, which keeps name captions readable:
yt-dlp --js-runtimes node --extractor-args "youtube:player_client=web_embedded" --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 "hearing_LABEL_%(id)s.%(ext)s" --retries 5 "https://www.youtube.com/watch?v=VIDEO_ID"
START and END are HH:MM:SS, and LABEL is a short label such as commerce_20240305. --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 hearings.csv. When the legislature's site offers an mp4 instead, download it there and cut it with ffmpeg -v error -ss START -to END -i FULL.mp4 -c copy video/hearing_LABEL.mp4 (this path was not exercised in our test run).
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 the grep on the bill digits found the chair's call and the final motion in each hearing and nothing else, and the cuts kept the bill's agenda item out of hearings that ran for hours. The default YouTube client failed on both the section download and a full download with "HTTP Error 403: Forbidden"; the web_embedded client in the command above worked. A third committee had only introduced the bill for about a minute, so it was left out.
Done when video/ holds one mp4 per hearing, subs/ holds an srv1 caption file for each, and hearings.csv lists file, source_url and cut_start_s.
Step 4: Price, upload and index
Goal: every agenda item indexed in a private Vivu project, with the user's approval of the cost.
- Measure each file:
ffprobe -v error -show_entries format=duration -of csv=p=0 video/FILE, where FILE is the file name in video/. Write duration_s. - Call vivu_get_usage and show one table:
| These hearings | Plan allowance | Remaining this month | |
|---|---|---|---|
| Index minutes | sum of duration_s / 60 | from vivu_get_usage | from vivu_get_usage |
| Search credits | 5 per issue (estimate), plus 5 for each rewording and for the control | 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. A whole committee hearing is often two to three hours, which is why Step 3 cuts it to the bill.
- If the hearings do not fit, offer levers in this order: cut tighter to the bill's agenda item (drop other bills and recesses), index the hearing with the most testimony first, and only then move to a larger plan. Never drop a hearing the user asked for without saying which one, and never recompress a file to save minutes.
- Call vivu_list_projects and reuse a project named "Hearings 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; a team's issue tracking belongs in a private project.
- 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 hearing file is larger, so hearings normally go through the user's own browser or the Vivu web app. Never split or recompress a file to fit.
- 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 hearings.csv and state.json.
In our test run the two agenda items measured 22.25 minutes in all and both were ready about 6 minutes after the upload started; the names in vivu_list_videos matched the local files. 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 hearings.csv shows ready and has a video_id.
Step 5: Search each issue
Goal: a saved list of candidate windows for every issue.
One precise search per issue, because each issue is its own section of the brief. Every search is precise: only precise returns a time window, and fast returns whole files with an empty reason, which tells you nothing when the project holds two or three hearings. The chain behind each row: the precise search suggests windows where someone talks about the issue, the captions inside each window decide whether the issue is really discussed there and give the quote (Step 6), and frames from the same window give the speaker's name caption (Step 7). That last step is the flip from what is said to what is shown: the caption is the only place the recording says who is talking.
Run vivu_search_videos (project_id, query, mode "precise", maximum_results 10) for each issue. Ten covers the places one issue comes up in a bill's agenda item across two or three hearings (the author's opening, a section walkthrough, testimony, members' questions) with room for windows that Step 6 sets aside; it is also the recall ceiling, so raise it for more hearings or a longer item. 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/ISSUE_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 brief, candidates.csv or a post.
The queries from our test run, on two committee hearings of one consumer data privacy bill, show the pattern:
| Field | Query | Mode | maximum_results |
|---|---|---|---|
| enforcement | a legislator, the bill author or a witness talks about who would enforce the data privacy law: the attorney general's enforcement authority, whether there is a private right of action, or the attorney general's cost and staff to bring enforcement actions | precise | 10 |
| preemption | someone explains that the state data privacy law would preempt or supersede local city or county ordinances on the same subject | precise | 10 |
| other_states | someone compares the bill with data privacy laws already passed in other states, or says a federal law would be better | precise | 10 |
| exemptions | someone discusses who the bill covers and who is exempt or excluded from it: which businesses, organizations or kinds of data fall outside the law | precise | 10 |
| control (optional) | someone discusses a cure period that gives businesses time to fix a violation before the attorney general can seek penalties | precise | 10 |
| name caption (probe, not used in the brief; see Step 7) | the on-screen name caption at the bottom of the frame that identifies the person speaking, with their title or organization | precise | 20 |
All four issue queries above are first wordings; none was reworded. A precise search uses 5 credits in total.
In our test run the six precise searches (four issues, the control and one name caption probe) came to 30 credits (estimate, from that rule), and each search was complete 136 to 223 seconds after submission, with the searches running together.
Done when every issue 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 "on issue" or "other", with the deciding caption line, before anything reaches the brief.
- For each window, convert start_ms and end_ms to seconds and add cut_start_s from hearings.csv: the srv1 file is on the official video's clock. Read the caption lines that start inside the window, plus 60 seconds before it, because a window can start after an exchange has begun:
grep -o '<text start="SECONDS_PATTERN[0-9.]*" dur="[0-9.]*">[^<]*' subs/VIDEO_ID.en.srv1
SECONDS_PATTERN is a pattern for the whole seconds in the range; for 9440 to 9499 it is 94[4-9][0-9]. Use two patterns joined with \| when the range crosses a hundred.
2. Label the window:
- on issue: someone discusses this issue (the provision, an objection to it, a question or answer about it, its cost);
- other: a neighbouring section, the same words used about something else ("keeping the bill in line with the other chamber" is not about other states), a procedural remark.
- Write every window with its label, the caption line that decided it and Vivu's reason into candidates.csv, and count the "other" windows as false positives for the issue. Vivu's reason text never decides the label.
- Keep every "on issue" window. An issue with no "on issue" window in a hearing gets a line saying "not found in the indexed agenda item" and goes back to the user; an empty result does not prove the issue never came up.
- Before writing the brief, grep the whole agenda item's captions for the issue's own words (for example "attorney general", "preempt", "federal", "exempt") with the same command and a pattern covering the whole item, and read every hit that is not inside a kept window for that issue. This finds some missed statements, not all: people describe an issue in words nobody would think to grep for.
Worked example from our test run
The test corpus was two public committee hearings from a state senate's official channel on the same consumer data privacy bill (two different committees, a month apart), cut to the bill's agenda item: 22.25 minutes in all, with the author's presentation, a section walkthrough by committee counsel, one trade association witness, members' questions and a fiscal analyst. Before searching we marked in the automatic captions every statement on the four issues, passing one sentence mentions, neighbouring material that shares words with an issue, and a control issue nobody raised.
The four issue searches returned 13 windows: 13 real and 0 false, with 2 statements missed, on the first wordings. Enforcement and preemption found every marked statement, including one sentence each in counsel's walkthrough that sit back to back (section 12, then section 13), and each came back for the right issue. Other states found 3 of 4: it missed the author saying a federal law would be far better, which comes shortly after the returned window in the same opening statement. Exemptions missed the witness saying retailers should not be caught up in the bill. Neither "keep the bill in line with the other chamber" passage came back for other states, and the control issue returned 0 windows. The whole item grep for "federal" found the missed federal law remark; the grep for "exempt", "exclud", "cover" and "apply" did not find the witness remark, which says retailers are "caught up in this bill". Windows were 11 to 63 seconds wide; the fiscal note window started after the member's question had been asked, which is why the caption check starts a minute before each window. Both hearings had desk microphones and one speaker at a time; rooms with distant microphones, crosstalk or wide shots with small desk name plates were not in our test corpus, so expect more windows labeled "other" there.
Done when every window in results/ has a label and a caption line in candidates.csv, and the whole item grep has been run for each issue.
Step 7: Read the speaker from frames
Goal: for each kept window, who was speaking, read from the name caption on screen.
- Cut three frames spread across the window into one strip:
ffmpeg -v error -y -ss WIN_START -t WIN_LEN -i video/FILE -vf "fps=3/WIN_LEN,scale=640:-1,tile=3x1" -frames:v 1 frames/ISSUE_KEY_hN.png
WIN_START is start_ms / 1000 and WIN_LEN is (end_ms minus start_ms) / 1000, both in seconds in the file; FILE is the agenda item file in video/; ISSUE_KEY is the field name from the query table and N the window's number in its result file. 640 pixels wide keeps a lower third caption readable.
2. Look at the strip. Write the name and the title or organization exactly as the caption shows them, and the role the hearing gives that person (bill author, committee member, counsel, witness for ORGANIZATION). When the window holds two speakers (a question and its answer), name both and say which one said the quoted sentence.
3. When no frame shows a caption, cut a wider strip with fps=1 and tile=8x1 over the first 8 seconds after the speaker starts, because the caption appears when a speaker begins and is removed after a few seconds. If there is still none, use the chair's call in the captions ("Senator NAME", "Mr. NAME, please introduce yourself"). If neither identifies the speaker, leave speaker empty and write UNCERTAIN; never guess from the face, the voice or the seat.
In our test run a name caption was readable on at least one of the three frames in all 13 kept windows, so the wider strip and the chair's call were not exercised in our test run. The presiding chairs never had a caption; where one speaks inside a window, those frames show none. The name caption query in our test run returned 16 windows, 16 real, but it adds nothing the strip does not give, so the brief does not use it.
Done when every kept window has a frame strip in frames/ and a speaker value (or UNCERTAIN).
Step 8: Write the hearing brief
Goal: a brief the team can read in two minutes and check from.
- Show the user one sample row and the field mapping, and wait for a yes before writing the rest:
issue,hearing,file,start,end,gist,quote,speaker,speaker_source,frame,source_link,transcript_checked,follow_up
enforcement,State and Local Government 2024-04-05,hearing_stategov_20240405_PjIG2QnKhE4.mp4,04:19,04:43,"Author: attorney general enforces; no private right of action","this consumer data privacy Bill does not include a private right of action um any enforcement measures would be through the Attorney General's office",bill author (name caption),name_caption,frames/enforcement_h0_strip.png,https://www.youtube.com/watch?v=PjIG2QnKhE4&t=9469,yes,
| Field | Source | If unavailable |
|---|---|---|
| issue | the team's wording from config.json | none |
| hearing, file | hearings.csv | none |
| start, end | the window in the file, as MM:SS | none |
| gist | one line written from the captions in the window | none |
| quote | copied from the captions, with obvious caption errors marked in brackets | NOT VERIFIED when there are no captions |
| speaker, speaker_source | Step 7: name_caption or chair_call | UNCERTAIN |
| frame | path of the strip | 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 |
| follow_up | left empty for the team | stays empty |
- Write hearing_brief.csv, one row per kept window, and hearing_brief.md, one section per issue with one line per row (hearing, time, speaker role, gist, quote when it carries the point, link). Add a line for each issue not found and for the control.
- Tell the user the counts: rows written, windows set aside in candidates.csv, issues not found, rows with speaker UNCERTAIN.
In our test run the brief has 13 rows on four issues, every row with a quote and a speaker from a name caption. The user's approval of the sample row was not exercised in our test run.
Done when hearing_brief.csv and hearing_brief.md exist with one row per kept window and a line for each issue not found, the user has approved the sample row, and the counts are reported.
Step 9: Post the brief to Slack or Notion
Goal: the approved brief in the team's channel or page, posted once.
- Name the destination (the Slack channel or the Notion page) and show the full rendered message or page exactly as it will be posted. Posting acts as the user, so wait for an explicit yes.
- Slack: one message, one section per issue, one line per row with the hearing, time, speaker role, gist and the official video link with its time. Notion: a page with hearing_brief.md as the body and the CSV rows as a table.
- Use the official video links, never a Vivu result page link (it expires after four hours) or a local file path.
- Record the post in state.json so a rerun does not post it again.
Posting was not exercised in our test run; Step 9 rendered the Slack message and the Notion page as files and sent nothing.
Done when the user has approved the rendered sample, the brief is posted to the named destination, and state.json records it as posted.
Compliance
- Use only recordings the legislature or council published. Terms for reusing legislative video differ by state and city; check the legislature's website terms or ask its media office before Step 3. Keep the downloads for the team's internal analysis and do not redistribute the video or clips.
- 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 legislature's own mp4 when it offers one.
- Download to the user's computer and upload from there. The skill does not hand video links to a third party importer.
- The people in the recording are legislators, staff and witnesses speaking in a public hearing. Speakers come only from the on screen name caption, the chair's call or the committee's minutes; the skill does no face or voice recognition. Members of the public in the room are not named.
- The brief lists what was said in public, side by side. It does not predict votes, rate legislators or draft lobbying messages.
- The videos stay in the user's Vivu project until the user deletes them. The project is created private because the default visibility shows it to the whole Vivu organization. Delete a project or video only when the user asks, and confirm first.
- Posting to Slack or Notion acts as the user and needs an approved sample first (Step 9).
Known failure modes
| Symptom | Cause | Fix |
|---|---|---|
| (observed) yt-dlp prints "HTTP Error 403: Forbidden" on the section or the full download | YouTube refused the default player client | use the web_embedded player client, as in the Step 3 download command |
| (observed) a quote has a wrong word, such as "this chapter prints laws adopted by any um local government" | automatic captions misheard "preempts" | mark the error in brackets in the quote, listen to that second before the brief is posted, and never fix it from the reason text |
| (observed) a statement on an issue is not in the results | the search returned 2 statements fewer than we had marked: one remark right after a returned window in the same speech, one witness remark on who the bill should cover | run the whole item grep from Step 6 and read hits outside kept windows; it found the federal law remark but not the witness remark, so tell the team the brief can miss a remark |
| (observed) the window starts after a question was asked | precise windows cover part of an exchange, not all of it | read the captions from a minute before the window, and quote the sentence that carries the point |
| (observed) no name caption on some frames of a window | the presiding chair has no caption, and other speakers' captions are shown only for a few seconds | cut the wider 1 fps strip from Step 7, then use the chair's call; otherwise UNCERTAIN |
| a window is about the neighbouring section of a long walkthrough | sections are read back to back with shared words | Step 6 labels it "other" from the captions; reword the query with the issue's own details |
| a reason text names a speaker or states what was said | the reason paraphrases and can be wrong | never copy it; quote the captions and read the speaker from the frame |
| an issue gets no window in a hearing | the issue did not come up, or members used other words | grep the captions for the issue's words; an empty result does not prove it was never discussed |
| "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 hearing 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 |