Add Seriatim configuration contract

This commit is contained in:
2026-05-03 19:13:50 -05:00
parent 657a44d8fb
commit 7aedca2ca1
8 changed files with 291 additions and 8 deletions

View File

@@ -23,7 +23,7 @@ func TestLoadAndValidate(t *testing.T) {
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
timeout: 30s
binary: seriatim
audita:
timeout: 1h
analyzer:
@@ -93,6 +93,8 @@ unknown_field: true
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: ""
inputs:
@@ -108,6 +110,8 @@ inputs:
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -124,6 +128,8 @@ inputs:
root: /tmp/narratio
whisperx:
transcribe_url: ://
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -141,6 +147,8 @@ inputs:
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
timeout: definitely-not-a-duration
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -158,6 +166,8 @@ inputs:
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
retry_delay: not-a-duration
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -175,6 +185,8 @@ inputs:
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
retries: -1
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -192,6 +204,8 @@ inputs:
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
concurrency: 0
seriatim:
binary: seriatim
`,
sessionYAML: `session_id: 2026-05-03
inputs:
@@ -202,6 +216,140 @@ inputs:
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.whisperx.concurrency must be > 0",
},
{
name: "unknown seriatim field fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
bogus: true
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantLoadErr: "strict decode failed",
},
{
name: "unknown seriatim env field fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
env:
unknown_knob: 1.0
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantLoadErr: "strict decode failed",
},
{
name: "missing seriatim binary fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
timeout: 10m
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.binary is required",
},
{
name: "invalid seriatim timeout fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
timeout: not-a-duration
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.timeout must be a valid duration",
},
{
name: "invalid seriatim output schema fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
output_schema: invalid-schema
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.output_schema must be one of: seriatim-minimal, seriatim-intermediate, seriatim-full",
},
{
name: "negative seriatim coalesce gap fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
coalesce_gap: -0.1
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.coalesce_gap must be >= 0",
},
{
name: "invalid seriatim env float fails",
pipelineYAML: `workspace:
root: /tmp/narratio
whisperx:
transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe
seriatim:
binary: seriatim
env:
overlap_word_run_gap: 0
`,
sessionYAML: `session_id: 2026-05-03
inputs:
audio_dir: ./audio
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
`,
wantValidate: "pipeline config \"pipeline.yml\" invalid: pipeline.seriatim.env.overlap_word_run_gap must be > 0 when provided",
},
}
for _, tt := range tests {
@@ -247,6 +395,18 @@ inputs:
if cfg.Pipeline.WhisperX.Concurrency == nil || *cfg.Pipeline.WhisperX.Concurrency != 2 {
t.Fatalf("whisperx.concurrency = %v, want 2", cfg.Pipeline.WhisperX.Concurrency)
}
if cfg.Pipeline.Seriatim.Timeout != "10m" {
t.Fatalf("seriatim.timeout = %q, want %q", cfg.Pipeline.Seriatim.Timeout, "10m")
}
if cfg.Pipeline.Seriatim.OutputSchema != "seriatim-intermediate" {
t.Fatalf("seriatim.output_schema = %q, want %q", cfg.Pipeline.Seriatim.OutputSchema, "seriatim-intermediate")
}
if cfg.Pipeline.Seriatim.CoalesceGap == nil || *cfg.Pipeline.Seriatim.CoalesceGap != 3.0 {
t.Fatalf("seriatim.coalesce_gap = %v, want 3.0", cfg.Pipeline.Seriatim.CoalesceGap)
}
if cfg.Pipeline.Seriatim.Report == nil || *cfg.Pipeline.Seriatim.Report != true {
t.Fatalf("seriatim.report = %v, want true", cfg.Pipeline.Seriatim.Report)
}
}
err = Validate(cfg)
@@ -280,6 +440,13 @@ func TestValidateMissingAudioSource(t *testing.T) {
RetryDelay: "2s",
Concurrency: &concurrency,
},
Seriatim: SeriatimConfig{
Binary: "seriatim",
Timeout: "10m",
OutputSchema: "seriatim-intermediate",
CoalesceGap: float64Ptr(3.0),
Report: boolPtr(true),
},
},
Session: &SessionConfig{
SessionID: "2026-05-03",