# Stage: merge ## Purpose Normalize per-speaker raw transcripts and merge them into the base transcript via Seriatim. ## Inputs and Outputs Inputs: - `transcripts/raw/*.json` - `inputs/speakers.yml` - `inputs/autocorrect.yml` Outputs: - `transcripts/base.json` - optional `artifacts/seriatim.report.json` (when report enabled) ## Boundaries Owns: - Raw transcript discovery/validation - Per-input normalize calls to Seriatim - Final merge call to Seriatim - Run-local log/config/report path wiring - Materialization of base/report outputs to canonical paths Does not own: - Transcript polishing or downstream artifact generation ## Config Fields Used - `session.session_id` - `session.campaign` - `pipeline.workspace.root` - `pipeline.seriatim.binary` - `pipeline.seriatim.timeout` - `pipeline.seriatim.output_schema` - `pipeline.seriatim.coalesce_gap` - `pipeline.seriatim.report` - `pipeline.seriatim.env.*` ## External Adapters Used - Seriatim adapter: - `Normalize` for each raw input - `Run` for final merge ## State and Manifest Behavior - Reads transcript inputs from transcribe stage outputs in manifest when present; falls back to canonical raw directory. - Writes run-local outputs/logs/config under `runs/{run_id}/merge/...` when enabled. - Materializes canonical base transcript and optional report. - Records normalized-input provenance and adapter metadata in stage metadata. ## Skip and Resume Behavior - Runner-level skip applies when already succeeded and not forced. - Forced rerun of this or upstream stages can stale downstream succeeded stages via runner invalidation. ## Failure Behavior - Fails on missing/invalid raw transcripts, missing speakers/autocorrect files, normalize failure, merge failure, invalid base output JSON, or invalid report JSON when enabled. ## Tests to Inspect Before Changing - `internal/stage/merge_test.go` - `internal/adapters/seriatim/subprocess_test.go` ## Architectural Invariants - Merge consumes normalized forms of each raw transcript. - Base transcript must validate before materialization. - Report output is optional and gated by config.