2026-09-22-transcript-integrity.md
Transcript Integrity Audit — talks/inventory.json
Date: 2026-09-22
Bead: craig-talks-inventory-has-transcript-audit-wht
Trigger: Session 20 finding — bitcoin-and-markets row carried has_transcript: true before the file existed (Agent C wrote it during S20 to close the gap). Suspicion: other rows may have similar drift.
Scope
Verify every has_transcript flag in /home/a/Projects/craig/talks/inventory.json against the actual contents of /home/a/Projects/craig/talks/transcripts/.
Inventory shape: 113 talks. Fields observed: title, event, date, url, duration, has_transcript, category, notes, embed_id, source. No slug field — the bead description assumes one, but the mapping from row → file is derived from the title via slugify. This is itself a fragility (see recommendation 3).
Slugify used for matching: three historical variants attempted (from rumble-download-transcribe.py, transcript-scraper.py, and one collapse-then-truncate variant), plus fuzzy fallback via difflib.SequenceMatcher at ratio ≥ 0.85 (strong) / ≥ 0.70 (weak, hand-verified).
Summary counts
| Bucket | Count | Meaning |
|---|---|---|
has_transcript: true — correct |
15 | Row asserts a transcript AND a real (>100 word) file exists |
has_transcript: true — drift |
0 | Row asserts a transcript but no file / stub file |
has_transcript: false — correct |
98 | Row asserts no transcript AND no file exists |
has_transcript: false — under-claimed |
0 | Row asserts no transcript but one exists |
| Total rows | 113 | |
| Orphan transcript files (see §3) | 7 | File exists but is unreferenced by any row |
Headline: the has_transcript field itself is currently 100% honest on both sides. The bitcoin-and-markets case in S20 was the last aspirationally-true-factually-false row, and it was closed the same session by Agent C generating the transcript. No new drift found.
The real remaining issue is the inverse: 6+1 transcript files sit on disk that no row in inventory.json points at. That's a completeness gap in the inventory, not a truthfulness gap in the flag.
§1 — has_transcript: true rows (all 15 verified)
Every one of the 15 flagged rows maps to a real transcript with word count > 100:
| idx | Title | Transcript file | Words |
|---|---|---|---|
| 9 | Future of Bitcoin Conference Talk | future-of-bitcoin-2017.md |
6,974 |
| 50 | Craig Wright tells Richard Heart he is Satoshi… | craig-wright-tells-richard-heart-he-is-satoshi-wrote-the-bitcoin-whitepaper-put-.md |
(large) |
| 81 | What do XRP, Tether and Craig Wright have in common? | what-do-xrp-tether-and-craig-wright-have-in-common-live-ama-with-simon-d.md |
(medium) |
| 89 | Craig Wright vs. Peter McCormack, Judge Calls CSW a Liar | craig-wright-vs-peter-mccormack-judge-calls-csw-a-liar-ep-543.md |
(large) |
| 90 | CRAIG WRIGHT VS. HODLONAUT | craig-wright-vs-hodlonaut.md |
(large) |
| 91 | USA Is Completely Insolvent w/ Greg Foss | usa-is-completely-insolvent-w-greg-foss.md |
(large) |
| 92 | SPECIAL REPORT: Hodlonaut v Craig Wright Defamation Trial | special-report-hodlonaut-v-craig-wright-defamation-trial.md |
(large) |
| 93 | Craig Wright Full Testimony: Hodlonaut v Craig Wright - Day 3 | craig-wright-full-testimony-hodlonaut-v-craig-wright--day-3.md |
(large) |
| 94 | Bitcoin and Markets | bitcoin-and-markets.md |
(large — added S20) |
| 95 | Who's Winning the Craig Wright vs. Hodlonaut Trial? EP 578 | whos-winning-the-craig-wright-vs-hodlonaut-trial-ep-578.md |
(medium) |
| 96 | Emotional Testimony | emotional-testimony.md |
(large) |
| 97 | Hodlonaut v Craig Wright Full Trial Recap | hodlonaut-v-craig-wright-full-trial-recap.md |
(medium) |
| 100 | Craig Wright LOSES Oslo Trial | craig-wright-loses-oslo-trial.md |
(large) |
| 101 | Gavin Andresen says Craig Wright is Satoshi Nakamoto | gavin-andresen-says-craig-wright-is-satoshi-nakamoto.md |
(small — 194) |
| 103 | Dr Craig Wright: Why Hal Finney, Nick Szabo, Adam Back… | dr-craig-wright-why-hal-finney-nick-szabo-adam-back-brittoschwartz-are-not-satos.md |
(medium) |
Note on idx=9 — this row's file (future-of-bitcoin-2017.md) is not the slug my slugify would derive from its title (future-of-bitcoin-conference-talk). The file is a curated 2017 conference transcript from the Harding gist, named by hand at import time. This is filename-drift (row → file mapping is not mechanical), not has_transcript drift — the claim itself is true. See §3 recommendation 3.
§2 — DRIFT rows (has_transcript:true, file missing or stub)
Zero. No rows in this state.
§3 — Under-claimed rows (has_transcript:false, file exists)
Zero rows where a has_transcript: false row has a corresponding transcript that the fuzzy matcher can link back to it.
However, 7 orphan transcript files exist that no inventory row currently references:
| Orphan file | Words | Notes |
|---|---|---|
agora-dr-craig-wright.md |
4,618 | Agora podcast with Sol Mayweather — no inventory row |
bitchute-interview-craig-wright.md |
6,780 | BitChute interview — no inventory row |
chatter-248-craig-wright-bsv-bitcoin.md |
10,334 | Chatter podcast episode 248 — no inventory row |
crypto-show-craig-wright.md |
177 | The Crypto Show interview — no inventory row |
messy-times-origins-of-blockchain.md |
7,901 | Messy Times podcast — no inventory row |
valuetainment-bitcoins-most-hated-man.md |
15,115 | Valuetainment / Patrick Bet-David — no inventory row |
gavin-andresen-says-craig-wright-is-satoshi.md |
194 | Duplicate of the longer -nakamoto.md variant used by row 101 |
Total orphan words: ~45,000. Five of these are substantial standalone interviews / podcast episodes that belong in the inventory. One is a duplicate stub. crypto-show-craig-wright.md is thin (177 words) and either needs to be re-transcribed at length or treated as a promo clip.
§4 — Recommendations
Per-row fix decisions belong to Craig / Adam. This audit does not modify inventory.json.
1. Do nothing for the 15 has_transcript:true rows — all verified true. No flip needed.
2. Add 5 inventory rows for the substantial orphan transcripts (agora, bitchute, chatter-248, messy-times, valuetainment). Populate title, event, date, url, source, category, has_transcript: true, notes. These are archive material sitting unindexed — a bead should be raised to backfill the inventory.
3. Address the row → file mapping fragility. Adding a slug field to every inventory row (populated once, then used as the source of truth for filename lookups) would eliminate the guess-the-slug step this audit had to perform. Otherwise any drift audit relies on best-effort slugify + fuzzy match, which will silently miss cases where filename conventions have shifted (as with future-of-bitcoin-2017.md).
4. Decide on the gavin-andresen-says-craig-wright-is-satoshi.md duplicate stub. Either delete (it duplicates the -nakamoto variant already used by row 101) or promote it into its own inventory row if it's a distinct clip. wc=194 suggests it's the same 61-second Rumble clip cut short.
5. Decide on crypto-show-craig-wright.md — 177 words is one paragraph. Either add an inventory row + treat it as a fragment, or run re-transcription (which needs Groq — outside this audit's scope).
§5 — Method notes (reproducibility)
- Traversal:
python3stdlib only (json,os,re,difflib). - Slug candidates per title generated from three historical slugify variants observed in the codebase (
scripts/rumble-download-transcribe.py:174,scripts/transcript-scraper.py:53, and a collapse-and-truncate variant). - Fallback fuzzy match:
difflib.SequenceMatcheron canonical slug vs. filename stem, threshold 0.85 accepted; 0.60–0.85 hand-inspected (5 candidates, all rejected as false positives). - Word count = whitespace-split length of the raw file (includes YAML frontmatter, so real body word counts are 5–20 words lower than listed).
- Row-to-file matches are 1-to-1: once a file is matched to a
has_transcript:truerow, it is removed from the pool available to matchhas_transcript:falserows, so a shared file cannot be counted as both correct and under-claimed.
§6 — Frozen vs derived interpretation
Per [[lesson_frozen_vs_derived_tracks]]: the has_transcript flag is a derived judgement (the archivist's claim that a transcript exists), not a frozen copy of upstream state. The failure mode this audit was built to catch — a derived judgement that is confidently wrong — is currently absent. The absent-transcript case in S20 (bitcoin-and-markets) has been closed. Good news for the flag's honesty; the residual archive gap (7 orphan files) is a different failure mode that requires an inventory-side backfill, not a flag flip.