# Stage: transcribe ## Purpose Generate per-speaker raw transcripts from prepared audio using WhisperX. ## Inputs and Outputs Inputs: - `audio/*.flac` prepared by `prepare` Outputs: - `transcripts/raw/.json` for each input audio file ## Boundaries Owns: - Discovering prepared audio inputs - Deriving speaker ids from audio basenames - Parallel WhisperX invocation with bounded concurrency - Validating produced JSON and materializing run-local outputs Does not own: - Transcript merge/polish/normalize/trim/analyze ## Config Fields Used - `session.session_id` - `session.campaign` - `pipeline.workspace.root` - `pipeline.whisperx.transcribe_url` - `pipeline.whisperx.language` - `pipeline.whisperx.timeout` - `pipeline.whisperx.retries` - `pipeline.whisperx.retry_delay` - `pipeline.whisperx.concurrency` ## External Adapters Used - WhisperX adapter (`env.WhisperX.Transcribe`). ## State and Manifest Behavior - Uses run-local output paths under `runs/{run_id}/transcribe/outputs/...` when run layout is enabled. - Validates each generated transcript JSON before materialization. - Materializes canonical outputs to `transcripts/raw/*.json`. - Records per-file metadata (attempts/status/duration/output path) in stage metadata. ## Skip and Resume Behavior - Runner-level skip applies for previously succeeded stage unless forced. - On forced upstream reruns, downstream succeeded stages can be marked `stale` by runner logic. ## Failure Behavior - Fails if no prepared audio exists, duplicate speaker basenames are detected, adapter output path mismatches expected path, any output JSON is invalid, or one worker fails. - Cancels in-flight workers after first terminal error. ## Tests to Inspect Before Changing - `internal/stage/transcribe_test.go` - `internal/app/whisperx_wiring_test.go` ## Architectural Invariants - Speaker identity is derived from `.flac` basename and must be unique. - Every successful speaker output must be valid JSON before materialization. - Canonical raw transcript set is the only supported merge input surface.