Mining and verifying sources

Stages S1 to S3: rival videos as leads, a teardown of what they do, and independent research that builds the fact base.

TL;DR

Sources are mined in three layers, and only the last one counts as evidence. S1 searches YouTube for the topic, pulls the captions of the top videos and has a language model extract dated events, figures and causes, with each quote checked in code. S2 reads the strongest rival videos closely to find what they all do, where they are weak and which of their claims not to repeat. S3 is independent research from outside YouTube (long-form magazines, rating-agency notes, tribunal and court records, wire reports) that builds FACTS.md, where every row has a status and every cause has a source for the link itself.

  • Rule 1: everything from S1 and S2 is a lead. Auto-captions garble names and numbers, and "several sources" can be one claim repeated.
  • Rule 2: research the person before the company; verify the causal link, not only the numbers; cross-check each key figure in a second source.
  • Rule 3: if a causal claim has no source, change the thesis, not the evidence.
  • Time and cost: S1 with 3 videos took 8 min 21 s (an 8-video run is estimated at 20 to 25 min). S2 option A needs subagents and therefore the user's say-so.

The three layers

S1

Rival-video research brief

"What does YouTube already say about this topic?" Output: research/<slug>/report.md, synthesis.json, search.json, transcripts/, extractions/.

Evidence value: leads and rival claims. Nothing is marked [V] from here.

S2

Teardown of rival videos

"What do they do, how, where are they weak?" Output: research/<slug>/teardown/SYNTHESIS.md (plus run/ files for options A and B).

Evidence value: craft analysis. It cannot show that a move caused reach.

S3

Independent fact base

"What is actually true, and what does the record not show?" Output: FACTS.md with five tables; the script ledger is derived from it.

Evidence value: the only source of facts for the script.

S1: the rival-video brief

Tool: src/topic-research/cli.js. Cached and resumable. Full procedure: references/s1-rival-brief.md.

Before you start

Run

node src/topic-research/cli.js "the fall of cafe coffee day" --entity="Coffee Day" --max=8 \
  --also="cafe coffee day siddhartha" --also="cafe coffee day kaise doob gaya"
FlagMeaning
--entity="..."Name a video's title or channel must contain to count.
--max=NHow many videos to take (default 8; 6 to 8 is the working range).
--also="query"Extra searches on top of the fixed eight, repeatable. Use for the local-language title, the founder's name, or an angle.
--refreshRedo this stage's own files only (search.json, transcripts/, extractions/, synthesis.json, report.md, .llm-cache/). It once deleted the whole topic folder including script/; that was fixed on 2026-10-25. Avoid it unless needed.

The cache means a re-run with the same arguments costs nothing. A change to --also or --max takes effect only with --refresh, because the search is cached.

What it does

  1. Search. Eight fixed query templates (topic; entity; entity documentary; explained; what happened; case study; rise and fall; collapse scandal) plus any --also, 20 results each. Every video seen is kept in search.json under candidates.
  2. Filter. Dropped if the entity is in neither title nor channel name, if the title looks like noise (ads, trailers, songs, unboxing, prices), or if shorter than three minutes. The reason is stored.
  3. Rank. score = log10(views + 10) + 0.5 x queries that found it (max 4) + 1 if 5 to 60 minutes + 1.5 if the title carries a story word + 1 if the entity is in the title. The top --max are selected. The score does not read the angle: "The Rebirth of Nokia" was selected on a test run.
  4. Transcripts. Picks the caption track in the video's original spoken language, not the first listed. A video with no captions is skipped.
  5. Extract. One model pass per about 6,000 words of each transcript at temperature 0.1: relevance, summary, events, figures, surprises, causes, entities, claims to verify. The prompt says use only the transcript, keep numbers and units as spoken, quote verbatim up to 25 words, mark each stated, hedged or attributed. In code, each quote is checked against the transcript; verified is true only if it occurs, and that pins the timestamp.
  6. Synthesise. Facts merged across videos into a timeline, a figures table, surprising points and causes. Each merged item must cite fact ids; items without a valid id are dropped; source counts and verified-quote counts are computed in code. A final pass writes the one-line story, entities, open questions, contested claims and 6 to 12 verification queries.
  7. Report. report.md: story in brief, timeline, hard numbers, surprising points, why it happened, people, contested claims, what is open, the queued verification queries, a sources table and a method note.

Read the output (this is the work of S1)

  1. Were the right videos selected? In search.json check each selected title is about the collapse. A rebirth, stock-tip or product video is the wrong source. To change the set, copy entries from candidates into selected, re-run without --refresh (new transcripts are fetched), and record the swap and why. The Cafe Coffee Day run swapped three: two "Malavika Hegde success story" videos and "The Inspiring Comeback Story of Cafe Coffee Day"; one added video said "CCD" in its title and had been rejected on the entity rule.
  2. How many sources were usable? Fewer than four: widen with --also and --max.
  3. Mine the report into FACTS.md as [CHECK] rows:
Report sectionGoes intoHow to treat it
Timelinefacts table, in orderThe "support" column says how many rival videos say it. One source with an unverified quote is the weakest.
Hard numbersmagnitude cross-check tableConflicts are the first things to verify.
Why it happenedcausal-claims tableEvery cause is a claim to find a source for. Causes every video repeats are table stakes.
Surprising pointscandidate teases and landingsVerify first; rivals already lead with them.
Key peoplepeople tableStart person research in S3 from these names.
Contested or shaky claimsdo-not-use table (until verified)
Still openthe list of what a viewer will askMaterial for the destination hint.
Verification queriesthe S3 search listWritten for exactly this.

Gate to leave S1

Failure modes

SymptomFix
GEMINI_API_KEY is not setPut it in .env or run Ollama.
Rate or daily limit, then slow progressPer-project quota, resets at midnight Pacific. Cached answers are reused on re-run.
[transcript] <id> skippedCaptions disabled. Take the next candidate by editing selected.
Selected videos off-topicThe score is blind to angle. Edit selected or tighten --entity.
Names or numbers garbledAuto-captions. Verify every name in S3.
Fewer transcripts on disk than citedHappened on Cafe Coffee Day: 3 of 8 on disk; four cited timestamps could not be audited. Say so in the hand-off; do not build the story on them.
AI Mode sourceNot wired in (sources/google-ai-mode.js throws). A Playwright proof of concept and a long design thread exist (data/ai-mode-poc/, docs/google_ai_search_automation_thread.md); verification queries are searched by hand in S3.

Observed test (topic "the fall of nokia", --max=3): 8 queries, 116 videos seen, 99 passed the filter, 3 selected (two were "rebirth" videos). 94 facts, 83 with a verified quote (88%); 33 timeline items, 38 figures, 8 causes, 12 verification queries; 8 min 21 s.

Optional exports (needed for S2)

node src/topic-research/export-csv.js research/<slug>            # all-videos.csv with channel subscriber counts (visits every channel; slow)
node src/topic-research/export-cohort.js research/<slug> research/<slug>/teardown/cohort-<slug> <videoId> ...

Shortcut that worked: copy search.json to search.json.full, trim candidates to the videos you care about, run the export, restore the file. Views per day use YouTube's rounded age text, so they are approximate.

S2: the teardown of rival videos

Skill: winning-video-teardown. Full procedure: references/s2-teardown.md. Goal: write down, with quotes, what the rival videos all do (table stakes), what the big ones do that the small ones do not, what their packaging promises, where they are weak, and which of their claims you must not repeat.

Do you need it?

SituationDo
The series already has a teardown of its winners (it does: 20 videos) and this topic's rivals add littleRead the 20-video aggregate and do a lite pass (option C) on the 2 or 3 biggest rival videos.
3 or more rival videos with real reach (hundreds of thousands of views)Full S2: option A if the user authorised subagents, else option B on the top 2 or 3.
Fewer than 3 usable rivalsOption C, and say so in the hand-off.

Who may run the analysts

OptionWhatCost
AOne Sonnet subagent per video, full JSON analysis, validator, aggregate, report, synthesis. Only if the user asked for subagents.Most
BYou act as the analyst on the 2 or 3 biggest videos, one at a time, with the same task files, JSON and validator.Medium
CLite: read the 2 or 3 biggest transcripts yourself and write SYNTHESIS.md; every claim carries a quote and a timestamp.Low

Steps (A and B)

node .claude/skills/winning-video-teardown/scripts/prepare.js --cohort research/<slug>/teardown/cohort-<slug> --out research/<slug>/teardown/run --perf-unknown
node .claude/skills/winning-video-teardown/scripts/validate.js --file run/analyses/V01.json --case run/cases/V01 --strict 1
node .claude/skills/winning-video-teardown/scripts/aggregate.js --run research/<slug>/teardown/run
node .claude/skills/winning-video-teardown/scripts/report.js    --run research/<slug>/teardown/run

The synthesis (the only prose)

teardown/SYNTHESIS.md: read-this-first limits; table stakes (in N of N, so they do not explain why one video beat another); common but not universal; where big videos differ from small (a lead only); moves worth copying with quotes; where these videos are weak (the opening a new video can take); claims they make that you could not verify (this feeds the do-not-use table); new mechanisms found by one analyst; spot-checks; packaging notes. The Moser Baer synthesis is the model.

What the Moser Baer teardown found (7 videos; 3 with reach)
  • Table stakes in 7 of 7: rise-and-fall arc; specific numbers; peak-versus-trough numbers; a disaster word and household brand in the title; the logo and strong colour in the thumbnail.
  • The bigger videos open on a human moment (an employee returning to a locked gate; "do you remember this name?"); the smaller ones lean on a formula title and a tidy thesis. Three against four, so a lead.
  • Weak points: promise delivered fully in 1 of 7; long flat middles; ads and subscribe asks between hook and story; numbers (354.51 crore, 787 crore, 8,000 crore) not reconciled across videos.
  • 159 of 160 quotes verified literally.

Pitfalls

S3: independent research and the fact base

Procedure: references/research-protocol.md. This stage decides the thesis. It changed the Moser Baer thesis once (v4) and its whole shape once (v5).

The eight rules, each earned by a mistake

  1. The person before the company. The first Moser Baer fact base was built from rival videos and results; two Business Today profiles of the founder (2003 and 2011) were never opened. Opening them turned a story about a bond into a story about a man who always left what was running out.
  2. Verify the link, not just the numbers. v3 said the solar bond turned decline into debt; sources showed the debt was already there in 2005 and none says where the bond's money went.
  3. Cross-check the magnitude of every key figure in a second source. One article's "In 2004, 3,500 crore" was a garble: another magazine had total debt at 1,620 crore in 2005 and 3,500 crore in 2011.
  4. Prefer primary or near-primary sources: rating-agency notes, liquidator and tribunal documents, results as reported by a wire, press conferences as reported by the trade press, court reports, long-form business magazines. Wikipedia is a map to the cited page, not a source.
  5. Mark every row with a status (below).
  6. Rival-video claims you cannot verify go in the do-not-use table with the reason. Moser Baer: "solar unit sold for 72 crore", "787 crore", "8,000 crore", market shares of 17, 70 and 80 percent, workers burning effigies.
  7. Sources disagree; say so, and use the safer one. The gate closing was 3 November in one report and 4 November in another, so the script says "November 2017".
  8. A person named in the script needs a record: on-record quotes in a national outlet, not a rumour. A private person is the user's decision.

Status tags

[V]
Checked against a non-YouTube page you opened and read.
[V-search]
Seen only in a search-result summary; the page could not be opened. Confirm before filming.
[CHECK]
Unverified.
derived
Computed; the arithmetic is shown.
analysis
Your reasoning; the voice-over must flag it as such.

Order of work

  1. Read the S1 brief: timeline with support counts, contested claims, verification queries. They are the first search list.
  2. The person and the early company: founder profile, family, first jobs, first company, why they left, partners, the first big bet, who doubted it.
  3. The rise: who financed it, the cost advantage, capacity, the peak numbers, the rival that was ahead, the company's own explanation then.
  4. The turn: the first bad result, what the company blamed, what changed in the market. Write the prediction your thesis makes and look for the figure that tests it.
  5. The responses: each diversification or rescue with dates and amounts, and what the company said in public at the time.
  6. The debt and the date: rating notes, bond terms, due dates, restructuring agreements, missed payments.
  7. The end: the insolvency petition, buyers who walked away, the liquidation order, the claims and the liquidation value.
  8. The people: workers' accounts (named, on record), when the signs began, what happened afterwards.
  9. The blame question: cases, agencies, amounts, court decisions, appeals; compute the scale of the allegations against the claims.
  10. The rival claims you will refute: search for each number a rival used and you did not; write "not found in any court record or news report" only after you looked.

Asking the fetch tool so it does not paraphrase

Fetch tools summarise. Ask: "Give the exact sentences, quoted verbatim, about X"; "What is the publication date or issue date of this article, and the year?"; "Return the article text verbatim as far as available; say if it is paywalled or truncated". If a page cannot be opened, search for the title and key names, accept the summary and mark the row [V-search].

Query templates (replace the entity)

<founder> founder profile early life how he started <first product> <city>
<company> history founded <year> <partner> <first plant>
<company> <year> results net loss revenue <business> Business Standard OR Storage Newsletter OR pv-magazine
<company> bond OR FCCB OR debenture <amount> due <year> recast OR restructuring
<company> CARE OR ICRA OR CRISIL rating <year> continuing losses negative net worth
<company> workers plant closed <year> salary unpaid <city> union president
<company> insolvency NCLT petition <lender> liquidation order claims <year>
<company> CBI OR ED case <bank> crore discharged OR chargesheet
<industry> price fall <years> <industry body>
"<company>" <exact figure a rival video used>

For each fact, note the stake

Whose loss it is, which belief of the viewer's it breaks, or which contrast it makes. A figure with no stake goes in the ledger and not in the voice-over (Lesson A). The same note becomes the stake line and the landing in S5.

FACTS.md: five tables

TableHolds
FactsColumns: claim, status, source (URL and date), stake (whose loss, which belief, which contrast).
Causal claimsEvery "X caused Y" the script leans on, with a source for the link.
Magnitude cross-checkEach key figure with at least two independent sources, and the basis and date of each.
PeopleWho, role, what is on record, whether naming them is safe.
Do-not-useRival claims you could not verify, with the reason.

When to stop

Stop when each planned beat has at least one sourced fact for its claim, every causal link has a source or has been softened, and every key figure appears in two places. Do not stop at the first plausible account. Do not keep researching past the point where the open items are things only a primary document can answer (the bond's use of proceeds); list them and say aloud in the script that you could not find them.

Resolving conflicting figures (Cafe Coffee Day)

Resolve each conflicting figure by its date and basis before choosing. Three of the S1 brief's conflicts were different dates or bases, not errors: Rs 7,200 crore was the debt at the start of 2019, Rs 3,200 crore the debt in July 2020; Rs 6,550 crore (March 2019) and Rs 4,970 crore (group, August 2019) are different entities or dates. A real error (the 2015 IPO at Rs 50 crore; it raised about Rs 1,150 crore) was visible only against a second source.

The research record

Every search and fetch of a session is written to the repository, so the research behind a version is not only in the chat.

node .claude/skills/video-script-production/scripts/session-log.js --since <start of the run> --out research/<slug>/script/RESEARCH-LOG-vN.md

Existing records: references/research-log.md (every search and fetch behind Moser Baer v4 to v6, by phase), research-log-round7.md (v7), and research/the-fall-of-cafe-coffee-day/script/RESEARCH-LOG-v1.md (20 searches, 15 fetches, 0 subagents). For Cafe Coffee Day a PROGRESS.md logged each stage, its output, the gate result and the next action, so that a session that lost context could resume.

Special care: people, deaths and allegations

Written 2026-10-27 from the repository files and the project memory notes. If a page and a file disagree, the file is right: fix the page.