| name | media-analysis |
| description | Content analysis for video and audio — YouTube, TikTok, podcasts, audio files. Transcription-first pipeline (captions API, user transcript, or Whisper opt-in). Dual-lens (Creator View + Engineer View). Two user- invokable depths (Standard / Deep); Quick Scan is triage-only. Outputs to .research/analysis/<media-slug>/. |
Document Version: 2.0
Last Updated: 2026-04-15
Status: ACTIVE
Shared conventions: See .claude/skills/shared/CONVENTIONS.md
/analyze router: This skill is the media-handler arm of /analyze —
direct invocation and router dispatch both supported. Handoff contract: the
router passes {target, auto_detected_type: "media"} as if the skill were
invoked directly.
Media Analysis
Content analysis of video and audio as knowledge artifacts. Mirrors
/repo-analysis structure for cohesion with sibling CAS handlers. Transcription
is the first step — once text is available, analysis follows the same pattern as
all other handlers.
Warm-up (shown at invocation)
/media-analysis <url-or-path> [--depth=standard|deep] [--transcript=<path>]
depth: standard (default) | deep | quick (triage)
phases: PHASE N of M (M = 10 Standard / Deep, 1 Quick)
est. time: Quick ~30s | Standard 3-5m | Deep 5-15m
(Whisper adds processing time based on duration)
output: .research/analysis/<slug>/
prior feedback: {replay per CONVENTIONS §18 if prior state file exists}
Routing Guide
| You want to… | Use this |
|---|
| Analyze a video or audio / podcast | /media-analysis (here) |
| Let router auto-pick repo vs site vs PDF | /analyze <target> |
| Cross-source synthesis across 3+ | /synthesize |
| GitHub repo | /repo-analysis |
| Website | /website-analysis |
| PDF / article / gist | /document-analysis |
Critical Rules (MUST follow)
- Transcription before analysis. No analysis without text. If captions
aren't available and Whisper isn't installed, offer manual transcript input.
transcript.md is MUST (CONVENTIONS §13.3).
analysis.json.transcript_source MUST be set to captions, whisper, or
manual.
- Write-to-disk-first. Every phase writes output before proceeding.
- State file on every phase transition. Update
.claude/state/media-analysis.<slug>.state.json after each phase.
- Creator View is mandatory for Standard/Deep. Written as conversational
prose, NOT tables or clinical output.
- No silent skips. If a SHOULD step fails, retry once, then report.
- Bands over numbers. Display categorical bands with scores in parens.
- Home context MUST be loaded for Creator View — SESSION_CONTEXT.md,
ROADMAP.md, CLAUDE.md,
.claude/skills/ listing, MEMORY.md user entries.
- Schema validation. analysis.json MUST validate against
scripts/lib/analysis-schema.js. See CONVENTIONS.md §12.
- Whisper is opt-in. Runtime detection only. Never fail because Whisper
isn't installed — fall back to captions or manual transcript.
When to Use
- User provides a YouTube, TikTok, or other video platform URL
- User provides a podcast URL or audio file path
- Evaluating media content as a knowledge source
When NOT to Use
- GitHub repo →
/repo-analysis
- Website →
/website-analysis
- PDF / document →
/document-analysis
- Testing webapp →
/webapp-testing
Input
/media-analysis <url-or-path>
/media-analysis <url> --depth=standard
/media-analysis <url> --depth=deep
/media-analysis --transcript <path> # Analyze pre-existing transcript
Type detection (when called via /analyze router):
| Input Pattern | Detected As |
|---|
youtube.com/*, youtu.be/* | YouTube video |
tiktok.com/* | TikTok video |
*.mp3, *.wav, *.m4a, *.ogg | Audio file |
*.mp4, *.mkv, *.webm | Video file |
| Podcast RSS/episode URL | Podcast episode |
Output
.research/analysis/<media-slug>/ produces:
| Artifact | Phase | Format / Notes |
|---|
analysis.json | 0+ | Core record (schema v3.0) + transcript_source |
transcript.md | 1 | MUST — raw transcript |
findings.jsonl | 2/5 | One JSON object per line |
creator-view.md | 4 | Conversational prose, 6 sections |
summary.md | 5 | Health bands |
value-map.json | 6 | Candidates ranked |
deep-read.md | 2b | Timestamps + linked resources catalog |
content-eval.jsonl | 3.5 | Evaluated description links |
coverage-audit.jsonl | 6b | Unexplored segments + user decisions |
extraction-journal.jsonl | routing | Append-only cross-source record |
Full schemas in REFERENCE.md §1.
Process Overview (M=10 for Standard/Deep)
VALIDATE Guards -> URL valid? Platform supported? File exists? Prior feedback replay (§18)?
PHASE 0 of 10 Quick Scan -> Metadata (title, duration, description), caption availability, creator lens
GATE Interactive -> Captions? Transcript? Whisper? Skip?
PHASE 1 of 10 Transcription -> Captions API / user transcript / Whisper
PHASE 2 of 10 Dimension Wave -> 6 dims: depth, speaker expertise, actionability, novelty, clarity, production
PHASE 2b of 10 Deep Read -> Timestamps, linked resources in description/show notes
PHASE 3.5 of 10 Content Eval -> Evaluate description/show-note links — BEFORE Creator View
PHASE 4 of 10 Creator View -> 6 sections, home context comparison
PHASE 5 of 10 Engineer View -> Quality bands via shared scoring
PHASE 6 of 10 Value Map -> Pattern/knowledge/content/anti-pattern candidates
PHASE 6b of 10 Coverage Audit -> Unanalyzed segments, unfollowed refs
PHASE 6c of 10 Tag Suggestion -> Per _shared/TAG_SUGGESTION.md
SELF-AUDIT + ROUTING
v2.0 phase renumber (BREAKING): Per Pattern 10 — Phase 4b (Content Eval) →
Phase 3.5 (matches execution order). State files with phase-4b-content-eval
auto-migrate on resume through v2.2 transition window.
Phase markers: ========== PHASE N of M: [NAME] ==========
Quick Scan (Phase 0 of M)
Fetch metadata without transcription:
- YouTube: Use oEmbed API as primary
(
https://www.youtube.com/oembed?url=<url>&format=json or noembed fallback) —
WebFetch on YouTube returns JS config, not rendered HTML. Returns title,
author_name, thumbnail_url. Captions check: youtube-transcript-api fetch
success = captions exist.
- TikTok: WebFetch page for title, creator, description.
- Audio files: Read metadata if available (duration, format).
- Podcast URLs: WebFetch episode page for title, show notes, duration.
Lightweight creator lens (MUST): From description/title, write 2-3 sentences
about what the content appears to cover.
Gate: Quick Scan is a preview — not a peer user tier. All --depth
flags bypass. Interactive gate with transcript options:
- Captions available → "Run Standard/Deep? [Y/n]"
- No captions →
[T] Transcript / [W] Whisper / [N] Skip (per CONVENTIONS §13.3
— manual transcript is valid; mark transcript_source: "manual")
source_tier: Media spans T1-T3. Default T2; named experts T1,
anonymous YouTube T3.
Done when: analysis.json (Quick tier) exists AND creator-lens teaser written
AND caption availability recorded.
Transcription (Phase 1 of 10)
Three paths, in priority order. Sets analysis.json.transcript_source.
Path A: Captions API (preferred)
YouTube: youtube-transcript-api (Python). Save raw transcript to
transcript.md. Mark transcript_source: "captions".
Python bootstrap detail (Windows path, embedded Python ._pth edit, pip
install, graceful fallback) — see REFERENCE §5.1.
Path B: User-Provided Transcript
User pastes text directly or provides a file path. Save to transcript.md. Mark
transcript_source: "manual" in analysis.json.
Path C: Whisper (opt-in, runtime detected)
Detection: python -c "import faster_whisper; print('ok')". If succeeds,
Whisper is available.
If available: Offer transcription. Use faster-whisper with large-v3 if
GPU available, base on CPU. Save to transcript.md. Mark
transcript_source: "whisper".
Scope-explosion soft prompt: Audio/video >60 min duration → prompt:
"Media is N minutes. Transcribe all / first 30 min / chapters only / custom?"
User decides; never hard-block. Particularly important when Whisper path is
chosen (processing time scales with duration).
Done when: transcript.md exists AND non-empty AND transcript_source set
in analysis.json.
Dimension Wave (Phase 2 of 10)
Score the transcript across 6 dimensions (0-100 scale):
| Dimension | What It Measures |
|---|
| Content Depth | How thoroughly topics are covered |
| Speaker Expertise | Demonstrated knowledge, credibility signals |
| Actionability | How directly applicable the ideas are |
| Novelty | Original insights vs common knowledge |
| Clarity | Organization, coherence, signal-to-noise ratio |
| Production Quality | Audio/video quality signals from transcript |
Done when: all 6 dimension scores written to findings.jsonl.
Deep Read (Phase 2b of 10 — MUST for Standard/Deep)
From transcript and description, identify and catalog:
- Timestamps of key segments/chapters
- Linked resources in description (tools, repos, papers, websites)
- Show notes references
- Guest/speaker credentials
- Referenced books, papers, or projects
Output: deep-read.md.
Done when: deep-read.md exists AND resources cataloged for Phase 3.5.
Content Evaluation (Phase 3.5 of 10 — MUST for Standard/Deep)
Phase renumbered from 4b to 3.5 in v2.0 — runs BEFORE Creator View and
feeds into it.
Evaluate linked resources from description/show notes. For each:
{category, name, url, relevance, applicability, home_connection}. Output to
content-eval.jsonl.
Done when: content-eval.jsonl exists AND every link has a relevance rating
AND feeds Creator View §2.
Creator View (Phase 4 of 10 — MUST for Standard/Deep)
Same 6 sections as repo-analysis. Written in conversational prose.
- What This Content Understands (+ Blindspots)
- What's Relevant To Your Work
- Where Your Approach Differs
- The Challenge
- Knowledge Candidates
- What's Worth Avoiding
Load home context before writing. Reference specific content from Deep Read
(Phase 2b) and Content Eval (Phase 3.5) — cite timestamps where applicable.
Done when: creator-view.md exists AND all 6 sections written AND
home-context claims reference actual files/projects.
Engineer View (Phase 5 of 10)
Quality bands from Phase 2 dimensions. Absence pattern classification where
applicable.
Done when: summary.md contains all 6 bands.
Value Map (Phase 6 of 10)
4 candidate types: pattern, knowledge, content, anti-pattern. Same ranking
fields.
Promotion rules (MUST):
- Content Eval high-relevance links → content candidates.
- Creator View §6 actionable warnings → anti-pattern candidates.
Write value-map.json. Update .research/extraction-journal.jsonl.
Done when: value-map.json exists AND promotion rules applied.
Coverage Audit (Phase 6b of 10 — MUST for Standard/Deep)
Scan for unanalyzed segments (by timestamp), unfollowed description links,
unresolved speaker references. Interactive prompt: Analyze all / Select / Skip.
Record in coverage-audit.jsonl.
Done when: every item has user_decision (analyze/skip) or
status: analyzed.
Tag Suggestion (Phase 6c of 10 — MUST for Standard/Deep)
Follow the canonical protocol in
.claude/skills/_shared/TAG_SUGGESTION.md. Per
CONVENTIONS §14: at least 3 semantic tags per entry, 8 categories, no upper
bound.
Signal sources for media-analysis: creator-view.md, entry notes,
engineer-view.md, transcript.md, speaker/channel context.
Done when: user-approved tags written to analysis.json.tags AND each
extraction-journal.jsonl row.
Delegation & Defaults
| Gate | Default |
|---|
--depth unspecified | standard |
| Quick → Standard gate unanswered | proceed to Standard |
| No-captions gate unanswered | [N] Skip to Quick Scan only |
| Scope-explosion (>60 min) | first 30 min |
| Coverage Audit unanswered | skip all (logged) |
| Tag Suggestion unanswered | never auto-approve — block |
| Routing menu unanswered | 7. Done (cleanup + invocation track) |
| Prior Feedback Replay (CONV §18) | continue unchanged (logged as shown) |
Tag Suggestion auto-approve is forbidden (CONVENTIONS §14.6).
Guard Rails (top 5)
- Transcription first — no analysis without
transcript.md +
transcript_source. Blocks at Phase 2 if absent.
- Whisper opt-in — runtime detection; never error on missing dep; fall back
to captions/manual path.
- Duration cap guard — >60 min → scope-explosion soft prompt.
- YouTube oEmbed fallback — if noembed/oembed both fail, degrade to manual
title entry rather than aborting.
- Write-rejection bypass — hook-rejected transcript/prose writes → retry
via Bash/Python, never silently skip.
Full guard catalog + Python bootstrap details — REFERENCE §3.1, §9.
Self-Audit (MUST — penultimate phase)
Per CONVENTIONS §8 plus domain checks:
- Artifact presence — all MUST files (analysis.json, transcript.md,
value-map.json, creator-view.md, summary.md, deep-read.md,
content-eval.jsonl, coverage-audit.jsonl, extraction-journal entries)
- Transcript contract —
transcript.md exists AND non-empty AND
analysis.json.transcript_source ∈ {captions, whisper, manual}
- Schema contract — analysis.json validates
- Completeness — all phases that ran produced output
- Tags populated —
analysis.json.tags non-empty (user-approved)
- Coverage decisions — every item has
user_decision
- Phase ordering — state file shows
phase-3.5-content-eval before
phase-4-creator-view, phase-6c-tags before self-audit
- Prior feedback replay —
prior_feedback_shown: true if prior state
existed (CONVENTIONS §18)
Routing Menu
Same 8 options as repo-analysis:
| Option | Action |
|---|
| 1. Extract value | Present candidates from value-map |
| 2. Send to TDMS | Transform findings to TDMS format |
| 3. Deep-plan this | Inject analysis as research context |
| 4. Save to memory | Persist key findings |
| 5. Adoption verdict | Full assessment (if applicable) |
| 6. Explore insights | Deeper conversation about findings |
| 7. Done | Cleanup, confirm artifacts, track invocation |
| 8. Cross-source synthesis | If 3+ sources analyzed, offer /synthesize |
State File & Resume
State file: .claude/state/media-analysis.<slug>.state.json.
Update after every phase. On re-invocation with same URL: offer Resume / Re-run
/ Compare. Resume skips transcription if transcript.md exists —
transcripts are reusable non-CAS artifacts. State file stores process_feedback
(nullable) from retro.
Integration
- Siblings:
/repo-analysis, /website-analysis, /document-analysis
- Router:
/analyze (auto-detects media sources)
- Companion:
/synthesize (cross-source, requires 3+ sources)
- Consumers:
/deep-plan (as research context), JASON-OS
- Cross-skill contract: MUST preserve
last_synthesized_at field on
analysis.json when writing — this field is set by /synthesize Phase 5 and
must not be dropped by handler re-runs (v2.0 contract, Session #284).
- Shared artifacts:
.research/extraction-journal.jsonl,
.research/EXTRACTIONS.md, .research/reading-chain.jsonl
- Reusable artifact:
transcript.md is a non-CAS artifact usable by any
downstream consumer (e.g., direct quoting, citation building)
Retro & Prior Feedback Replay
Retro (CONVENTIONS §10): Before the routing menu, ask: "What worked well?
What would you change next time?" Save to process_feedback in the state file.
Optional structured dimensions: worked_well, would_change, longest_phase,
signal_quality.
Prior Feedback Replay (CONVENTIONS §18): On re-invocation for the same
target, replay prior process_feedback during VALIDATE and ask whether to
adjust approach. Log prior_feedback_shown: true.
Invocation tracking — at Done routing:
cd scripts/reviews && npx tsx write-invocation.ts --data '{
"skill":"media-analysis","type":"skill","success":true,
"schema_version":1,"completeness":"stub",
"origin":{"type":"manual"},
"context":{"target":"MEDIA_SLUG","mode":"media","depth":"DEPTH",
"transcript_source":"captions|whisper|manual",
"score":SCORE,"decisions":DECISION_COUNT,
"candidates":CANDIDATE_COUNT}
}'
Version History
| Version | Date | Description |
|---|
| 2.0 | 2026-04-15 | Skill-audit batch 2026-04-15-analysis-quartet Wave 2. Breaking: Phase 4b → 3.5 (Content Eval) per Pattern 10. Structural: /analyze router ack, Warm-up, Routing Guide, NEW Integration section (siblings + reusable transcript.md), NEW Retro section, NEW Invocation tracking with transcript_source context, Delegation & Defaults, consolidated Guard Rails top-5, duration scope-explosion soft prompt (>60 min), Done-when gates, PHASE N of M, Tag Suggestion → _shared ref, Prior Feedback Replay per CONVENTIONS §18, output table, Python bootstrap detail deferred to REFERENCE §3.1 pointer. T28 tagline removed from user-visible description (preserved in v1.0 history). |
| 1.1 | 2026-04-09 | Full output list, oEmbed fallback, Python bootstrap docs, v1.1 (Session #270 E2E test) |
| 1.0 | 2026-04-08 | Initial creation (T28 CAS, Session #269) |