Media Transcription
SkillFiles & storageRun, monitor, cancel, and resume the durable media transcription pipeline (media-transcription-pipeline-v2) for raw meeting media on /Volumes/badass-media. Use when the user asks to transcribe a meeting or media file from the NAS, check transcription progress, cancel a transcription, resume a failed/partial run, or debug ASR/diarization actors. Flagg-host-only execution.
Use Media Transcription in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Media Transcription and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Media Transcription skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by joelhooks/joelclaw in skills/media-transcription/SKILL.md and read by Ahel’s review.
Durable, event-driven transcription of raw meeting media on the NAS. Inngest
orchestrates; MLX Whisper (chunked ASR) and pyannote (whole-file diarization)
run as detached local actor processes — no Inngest step ever holds a
request open across inference. Built 2026-07-11 after the v1 monolith died to
request-bound 2h timeouts and Whisper hallucination loops (design receipt:
.brain/projects/transcription-pipeline-v2-2026-07-11.svx).
Where it runs (hard constraints)
- Flagg host worker only (
hostFunctionDefinitions, launchdcom.joel.system-bus-worker). Needs the direct NFS mount/Volumes/badass-mediaand the rig checkout. - Local inference implementation:
~/Code/joelhooks/transcript-rig(public repojoelhooks/transcript-rig; override path withTRANSCRIPT_RIG_ROOT). Raw media on the NAS is immutable — the pipeline only writes derived artifacts. - From any other fleet machine: send the event (Inngest routes it to flagg's worker) or SSH to flagg to inspect on-disk state.
Start a transcription
joelclaw send media/transcription.requested -d '{
"requestId": "req-'$(uuidgen | tr 'A-Z' 'a-z')'",
"sourcePath": "/Volumes/badass-media/joel/meetings/<meeting-dir>"
}'
requestIdis the idempotency key — always mint a fresh one; a reused id is silently deduped. Optional flags:"publish": false,"index": false(both default true).sourcePathmust be under/Volumes/badass-media/or the run fails NonRetriable.
Monitor
joelclaw event <event-id>→ run id;joelclaw run <run-id>for step trace. Orchestrator steps keepNN-prefixes for the pijob-monitorwidget (packages/pi-extensions/inngest-monitor).- Progress events:
media/transcription.chunk.completed(per chunk, with index/total/cached), terminalmedia/transcription.completedor.failed. - On-disk truth (flagg):
<rig>/.transcript-rig-work/<artifactId>/orchestration/plan.v1.json— chunk plan (requestId, tracks, chunk ids)orchestration/actors/<chunkId>/status.v1.json— actor heartbeat/stateorchestration/actors/<chunkId>/actor.log— inference stdout/stderrstate.v1.json— rig stage (staged → transcribed → … → complete)editorial/transcript.{md,txt,srt,vtt,tsv}— final outputs
- Published result:
<sourcePath>/derived/transcripts/current.v1.jsonpointer + artifact directory.
Cancel
joelclaw send media/transcription.cancelled -d '{"requestId": "<the-request-id>"}'
Cancels all runs (cancelOn) AND triggers transcription-cleanup-v1, which
SIGTERM→10s→SIGKILLs live actor process groups (identity-verified via ps —
PID reuse safe) and writes orchestration/cancelled.v1.json, which blocks
new actor spawns. Optionally include artifactId to skip the plan scan.
Resume / re-drive
Re-send media/transcription.requested with a fresh requestId and the
same sourcePath. Everything valid on disk is adopted, nothing recomputes:
- Whole-track
raw/asr/<sourceId>/asr.jsonpassing the repetition screen ⇒ track done. A repetitive one is quarantined (.rejected-<ts>) and the track re-chunks. - Existing chunk WAV layouts (
raw/chunked/<sourceId>/chunks/NNN.wav) are adopted; offsets recomputed from ffprobe. Valid chunkout/<i>/asr.json⇒ cached, no actor spawned. - Diarization
raw/diarization/<sourceId>.jsonl(first line parses) ⇒ cached. - Remove
orchestration/cancelled.v1.jsonfirst if the artifact was previously cancelled.
Failure modes (typed, in actor status / run errors)
| Error | Meaning | Action |
|---|---|---|
repetitive_output: … | Whisper hallucination loop survived collapse (decode mostly padding) | Retries respawn actors; deterministic loops usually pass after collapse-then-screen. Inspect the chunk WAV — genuinely silent/broken audio fails honestly |
inference_required: … | A fast rig stage (resume --no-inference) found a missing claim check | Inference didn't complete/adopt; check chunk statuses |
cancelled_by_signal | Actor's child died to un-initiated SIGTERM/SIGKILL (group kill, operator, or Bun's in-process signal-dispatch race) | Expected during cancel/reap; standalone occurrences mean someone killed processes manually |
actor stalled | Heartbeat stale >3m | Watchdog killed + retried automatically |
chunk_result_missing | Aggregation found no valid chunk output | Chunk failed all retries; see its actor.log |
mount_unavailable | NFS mount down | media/transcription.blocked emitted; remount and re-drive |
Design invariants (don't regress these)
- ASR outputs are parsed with
parseAsrJson(mlx_whisper emits bareNaN). - Repetition screening is collapse-then-screen (
screenWithCollapse): consecutive-duplicate segments collapse to one; >50% collapsed ⇒ failed decode. Aggregation persists the collapsed form. - ASR actors run
--condition-on-previous-text False --hallucination-silence-threshold 2; diarization uses MPS (TRANSCRIPT_RIG_DIARIZE_DEVICE=cputo opt out). waitForEventresults are verified in code against the spawned actorId — the dev-mode Inngest server leaks foreign events past match expressions.- Known dev-server gap: concurrency keys (
transcription-gpulimit 1) are not enforced; expect parallel whispers until the Inngest server is upgraded.
Code: packages/system-bus/src/transcription/ +
packages/system-bus/src/inngest/functions/{media-transcription-pipeline,transcription-asr-chunk,transcription-diarize,transcription-cleanup}.ts.
Signals
- GitHub stars
- 64
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
media-transcription- Source
- github.com/joelhooks/joelclaw