diff --git a/docs/config.md b/docs/config.md index e9f7e5b..ac07d51 100644 --- a/docs/config.md +++ b/docs/config.md @@ -66,7 +66,8 @@ whisperx: Why this is sufficient: -- `workspace.root` and `whisperx.transcribe_url` are the core required pipeline fields. +- `whisperx.transcribe_url` is required. +- `workspace.root` is optional and defaults to `/var/lib/narratio`. - Seriatim and Audita sections may be omitted; defaults are applied. - Archive, storage, spool, normalize, and other optional sections get defaults when omitted. @@ -135,7 +136,7 @@ Defaults listed here are effective runtime defaults after load. | Path | Type | Required | Default | | --- | --- | --- | --- | -| `pipeline.workspace.root` | string | Yes | none | +| `pipeline.workspace.root` | string | No | `/var/lib/narratio` | | `pipeline.workspace.cleanup_after_archive` | bool | No | `false` | | `pipeline.secrets.env_dir` | string | Conditional | none | | `pipeline.storage.backend` | string | No | empty | diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 42d0dc3..3993f6e 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -11,6 +11,7 @@ const ( DefaultS3AccessKeyIDEnv = "OBJECT_STORAGE_KEY_ID" DefaultS3SecretAccessKeyEnv = "OBJECT_STORAGE_KEY" DefaultStorageS3RootPrefix = "dnd" + DefaultWorkspaceRoot = "/var/lib/narratio" DefaultSpoolRoot = "/var/spool/narratio" DefaultWhisperXLanguage = "en" diff --git a/internal/config/load.go b/internal/config/load.go index 06c7ee7..b50a4ce 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -152,6 +152,7 @@ func applyPipelineDefaults(cfg *PipelineConfig) { if cfg == nil { return } + applyWorkspaceDefaults(&cfg.Workspace) applyStorageDefaults(&cfg.Storage) applySpoolDefaults(&cfg.Spool) applyArchiveDefaults(&cfg.Archive) @@ -166,6 +167,15 @@ func applyPipelineDefaults(cfg *PipelineConfig) { applyScriptoriumDefaults(cfg.Scriptorium) } +func applyWorkspaceDefaults(cfg *WorkspaceConfig) { + if cfg == nil { + return + } + if cfg.Root == "" { + cfg.Root = DefaultWorkspaceRoot + } +} + func applyStorageDefaults(cfg *StorageConfig) { if cfg == nil { return diff --git a/internal/config/load_validate_test.go b/internal/config/load_validate_test.go index fd39437..2c2bc6a 100644 --- a/internal/config/load_validate_test.go +++ b/internal/config/load_validate_test.go @@ -15,6 +15,7 @@ func TestLoadAndValidate(t *testing.T) { wantLoadErr string wantValidate string checkDefault bool + wantRoot string }{ { name: "valid minimal config", @@ -39,6 +40,7 @@ inputs: glossary_file: ./glossary.yml `, checkDefault: true, + wantRoot: "/tmp/narratio", }, { name: "seriatim and audita sections can be omitted", @@ -59,6 +61,26 @@ inputs: glossary_file: ./glossary.yml `, checkDefault: true, + wantRoot: "/tmp/narratio", + }, + { + name: "workspace root defaults when omitted", + pipelineYAML: `whisperx: + transcribe_url: https://transcription.ai.rakestrawhome.com/transcribe +analyzer: + timeout: 20m +notification: + timeout: 15s +`, + sessionYAML: `session_id: 2026-05-03 +inputs: + audio_dir: ./audio + speakers_file: ./speakers.yml + autocorrect_file: ./autocorrect.yml + glossary_file: ./glossary.yml +`, + checkDefault: true, + wantRoot: DefaultWorkspaceRoot, }, { name: "unknown pipeline field fails", @@ -713,6 +735,9 @@ inputs: t.Fatalf("SessionPath = %q, want %q", cfg.SessionPath, sessionPath) } if tt.checkDefault { + if tt.wantRoot != "" && cfg.Pipeline.Workspace.Root != tt.wantRoot { + t.Fatalf("workspace.root = %q, want %q", cfg.Pipeline.Workspace.Root, tt.wantRoot) + } if cfg.Pipeline.WhisperX.Language != "en" { t.Fatalf("whisperx.language = %q, want %q", cfg.Pipeline.WhisperX.Language, "en") }