14 KiB
14 KiB
Configuration
1. Overview
Narratio loads two YAML files:
pipeline.yml: pipeline-level runtime configuration.session.yml: per-session metadata and input selection.
These commands load and validate both files before running:
narratio runnarratio plannarratio resumenarratio run-stagenarratio restore
Behavior:
- strict YAML decode is enabled (
KnownFields(true)): unknown fields fail. - session templates render before session YAML decode.
- defaults are applied for optional pipeline fields.
- validation enforces required fields, value formats, and cross-field constraints.
2. Config file discovery
Pipeline config lookup for run, plan, resume, run-stage, and restore:
- if
--config <path>is provided, that path is used. - if omitted, Narratio searches in order:
/usr/local/etc/narratio/pipeline.yml/etc/narratio/pipeline.yml
- first existing file wins.
3. Session file discovery and templating
Session config lookup for run, plan, resume, run-stage, and restore:
- if
--session <path>is provided, that path is used. - if omitted, Narratio searches in order:
./session.yml/usr/local/etc/narratio/session.yml/etc/narratio/session.yml
- first existing file wins.
Template behavior:
- supported placeholders:
{{session_id}}{{ session_id }}{{previous_session_id}}{{ previous_session_id }}
--session-id <value>supplies the placeholder value.--previous-session-id <value>supplies the previous-session placeholder value.- unresolved placeholders fail load.
- if rendered
session_idmismatches--session-id, load fails. - if rendered
previous_session_idmismatches--previous-session-id, load fails.
4. Minimal pipeline config
whisperx:
transcribe_url: "https://transcription.example.com/transcribe"
Why this is sufficient:
whisperx.transcribe_urlis required.workspace.rootdefaults to/var/lib/narratio.- optional sections (
seriatim,audita,archive,scriptorium,trim,normalize, etc.) receive defaults or stay inactive.
5. Minimal session template
session_id: "{{ session_id }}"
previous_session_id: "{{ previous_session_id }}"
campaign: sample-campaign
inputs:
audio_dir: ./audio
speakers_file: ./examples/speakers.yml
autocorrect_file: ./examples/autocorrect.yml
glossary_file: ./examples/glossary.yml
Usage:
narratio run --config /path/to/pipeline.yml --session ./session.yml --session-id 2026-05-03
6. Production-oriented config
workspace:
root: /var/lib/narratio/workspace
cleanup_after_archive: true
storage:
backend: s3
s3:
bucket: my-dnd-archive
root_prefix: dnd
region: us-east-1
access_key_id_env: OBJECT_STORAGE_KEY_ID
secret_access_key_env: OBJECT_STORAGE_KEY
spool:
root: /var/spool/narratio
delete_audio_after_archive: true
archive:
enabled: true
upload_run: true
promote_artifacts:
- source: narratio.transcript.trimmed
dest: transcripts/trimmed.json
required: true
- source: narratio.artifact.session_recap
dest: artifacts/session_recap.md
required: true
whisperx:
transcribe_url: "https://transcription.example.com/transcribe"
scriptorium:
artifacts:
session_recap:
enabled: true
prompt_id: dnd.session_recap
output_path: artifacts/session_recap.md
inputs:
transcript:
source: narratio.transcript.trimmed
required: true
Operational notes:
- archive promotion is explicit and source-based via
archive.promote_artifacts. sourceis required;destis optional and derived when omitted.- Narratio does not auto-promote all generated analyze artifacts.
restorereads the same config/session inputs and restore scope is bounded by committed archive current state.
7. Full pipeline reference
| Path | Type | Required | Default |
|---|---|---|---|
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 |
pipeline.storage.bucket |
string | No | empty |
pipeline.storage.prefix |
string | No | empty |
pipeline.storage.s3.bucket |
string | Conditional | empty |
pipeline.storage.s3.root_prefix |
string | No | dnd |
pipeline.storage.s3.region |
string | No | empty |
pipeline.storage.s3.endpoint |
string | No | empty |
pipeline.storage.s3.force_path_style |
bool | No | false |
pipeline.storage.s3.access_key_id_env |
string | No | OBJECT_STORAGE_KEY_ID |
pipeline.storage.s3.secret_access_key_env |
string | No | OBJECT_STORAGE_KEY |
pipeline.spool.root |
string | No | /var/spool/narratio |
pipeline.spool.delete_audio_after_archive |
bool | No | false |
pipeline.archive.enabled |
bool | No | true |
pipeline.archive.upload_run |
bool | No | true |
pipeline.archive.promote_artifacts[] |
list | No | trimmed transcript rule |
pipeline.archive.promote_artifacts[].source |
string | Yes (per rule) | none |
pipeline.archive.promote_artifacts[].dest |
string | No | derived from source |
pipeline.archive.promote_artifacts[].required |
bool | No | true |
pipeline.whisperx.transcribe_url |
string | Yes | none |
pipeline.whisperx.language |
string | No | en |
pipeline.whisperx.timeout |
duration string | No | 30m |
pipeline.whisperx.retries |
int | No | 3 |
pipeline.whisperx.retry_delay |
duration string | No | 2s |
pipeline.whisperx.concurrency |
int | No | 2 |
pipeline.seriatim.binary |
string | No | seriatim |
pipeline.seriatim.timeout |
duration string | No | 10m |
pipeline.seriatim.output_schema |
string | No | seriatim-intermediate |
pipeline.seriatim.coalesce_gap |
float | No | 3.0 |
pipeline.seriatim.report |
bool | No | true |
pipeline.seriatim.env.overlap_word_run_gap |
float | No | unset |
pipeline.seriatim.env.overlap_word_run_reorder_window |
float | No | unset |
pipeline.seriatim.env.backchannel_max_duration |
float | No | unset |
pipeline.seriatim.env.filler_max_duration |
float | No | unset |
pipeline.audita.binary |
string | No | audita |
pipeline.audita.timeout |
duration string | No | 3h |
pipeline.audita.llm_api_key_env |
string | No | empty |
pipeline.audita.modules[] |
list[string] | No | empty |
pipeline.audita.base_url |
string | No | empty |
pipeline.audita.model |
string | No | empty |
pipeline.audita.total_llm_concurrency |
int | No | unset |
pipeline.audita.proposal_llm_concurrency |
int | No | unset |
pipeline.audita.validation_model |
string | No | empty |
pipeline.audita.validation_llm_concurrency |
int | No | unset |
pipeline.audita.transcript_description |
string | No | empty |
pipeline.audita.config_path |
string | No | empty |
pipeline.audita.output_schema |
string | No | empty |
pipeline.audita.work_dir_retention |
string | No | empty |
pipeline.audita.report |
bool | No | true |
pipeline.normalize.output_path |
string | No | transcripts/normalized.json |
pipeline.normalize.output_schema |
string | No | seriatim-intermediate |
pipeline.normalize.report |
bool | No | true |
pipeline.trim.enabled |
bool | No | false |
pipeline.trim.output_path |
string | Conditional | none |
pipeline.trim.bounds.prompt_id |
string | Conditional | none |
pipeline.trim.bounds.profile_id |
string | No | empty |
pipeline.trim.bounds.transcript_input_name |
string | Conditional | none |
pipeline.trim.bounds.output_path |
string | Conditional | none |
pipeline.trim.bounds.timeout |
duration string | No | 10m |
pipeline.trim.bounds.render_debug |
bool | No | false |
pipeline.trim.bounds.render_output_path |
string | Conditional | none |
pipeline.trim.seriatim.report |
bool | No | false |
pipeline.scriptorium.binary |
string | No | scriptorium |
pipeline.scriptorium.config_path |
string | No | empty |
pipeline.scriptorium.timeout |
duration string | No | 10m |
pipeline.scriptorium.render_debug |
bool | No | false |
pipeline.scriptorium.artifacts |
map | No | empty |
pipeline.scriptorium.artifacts.<name>.enabled |
bool | No | false |
pipeline.scriptorium.artifacts.<name>.depends_on[] |
list[string] | No | empty |
pipeline.scriptorium.artifacts.<name>.render_debug |
bool | No | unset |
pipeline.scriptorium.artifacts.<name>.prompt_id |
string | Conditional | none |
pipeline.scriptorium.artifacts.<name>.profile_id |
string | No | empty |
pipeline.scriptorium.artifacts.<name>.output_path |
string | Conditional | none |
pipeline.scriptorium.artifacts.<name>.timeout |
duration string | No | empty |
pipeline.scriptorium.artifacts.<name>.inputs.<key>.source |
string | Conditional | none |
pipeline.scriptorium.artifacts.<name>.inputs.<key>.artifact |
string | No | empty |
pipeline.scriptorium.artifacts.<name>.inputs.<key>.path |
string | No | empty |
pipeline.scriptorium.artifacts.<name>.inputs.<key>.required |
bool | No | false |
pipeline.scriptorium.artifacts.<name>.vars.<key> |
map value | No | empty |
pipeline.analyzer.binary_path |
string | No | empty |
pipeline.analyzer.timeout |
duration string | No | empty |
pipeline.analyzer.artifacts.output_dir |
string | No | empty |
pipeline.analyzer.artifacts.types[] |
list[string] | No | empty |
pipeline.notification.backend |
string | No | empty |
pipeline.notification.recipient |
string | No | empty |
pipeline.notification.timeout |
duration string | No | empty |
Scriptorium artifact-key and dependency rules:
- artifact keys must match
^[a-z][a-z0-9_]*$. - enabled artifacts require
prompt_idandoutput_path. output_pathmust be relative, traversal-safe, and underartifacts/.- configured artifact input sources use
narratio.artifact.<name>. - if input source references
narratio.artifact.<name>, artifact<name>must exist and must be listed independs_on. - every
depends_onentry must be a configured artifact key. - self-dependency is rejected.
- enabled dependency cycles are rejected.
- any artifact referenced by
depends_onornarratio.artifact.<name>source must defineoutput_path(even if not enabled).
Allowed pipeline.scriptorium.artifacts.<name>.inputs.<key>.source values:
previous_session_artifactnarratio.previous_session.artifact.<configured_artifact_key>narratio.transcript.mergednarratio.transcript.polishednarratio.transcript.fullnarratio.transcript.trimmednarratio.bounds.sessionnarratio.artifact.<configured_artifact_key>
pipeline.archive.promote_artifacts[].source values:
narratio.transcript.mergednarratio.transcript.polishednarratio.transcript.fullnarratio.transcript.trimmednarratio.bounds.sessionnarratio.artifact.<configured_artifact_key>
Archive promotion destination rules:
destmust be a clean relative path (not absolute, no traversal).- duplicate
destvalues are rejected. - if
destis omitted:- built-in sources derive their canonical destination path;
- configured sources derive from
pipeline.scriptorium.artifacts.<name>.output_path; - derivation failure is a config validation error.
Restore-related implications:
- restore remote identity requires archive S3 identity to resolve (
pipeline.storage.s3.bucketand session prefix derivation inputs). - restore scope considers only committed current state and durable paths (
manifest.json,transcripts/**,artifacts/**, optionalaudio/**).
8. Full session reference
| Path | Type | Required | Default |
|---|---|---|---|
session.session_id |
string | Yes | none |
session.previous_session_id |
string | No | empty |
session.campaign |
string | Yes | none |
session.date |
string | No | empty |
session.title |
string | No | empty |
session.inputs.audio_dir |
string | Conditional | empty |
session.inputs.audio_files[] |
list[string] | Conditional | empty |
session.inputs.audio_s3.prefix |
string | Conditional | none |
session.inputs.speakers_file |
string | Yes | none |
session.inputs.autocorrect_file |
string | Yes | none |
session.inputs.glossary_file |
string | Yes | none |
Audio-source rule:
- configure exactly one mode:
audio_dir, oraudio_files(at least one), oraudio_s3.prefix
audio_s3cannot be combined with local audio fields.
Previous-session rule:
- if
session.previous_session_idis set, it must not equalsession.session_id.
9. Secrets
Narratio supports filesystem-based secret injection via pipeline.secrets.env_dir.
Behavior:
env_dirmay be absolute or relative.- relative
env_dirresolves from current working directory. - files with valid env-var names (
[A-Za-z_][A-Za-z0-9_]*) are loaded. - values are loaded from file contents with trailing newline trimming.
- existing process env vars are preserved.
- invalid names and subdirectories are skipped.
- missing/unreadable
env_dirfails command execution.
Guidance:
- do not put secret values directly in YAML.
- configure env var names in config and provide values via env/secrets files.
10. Examples
Maintained examples:
examples/pipeline.minimal.ymlexamples/pipeline.production.ymlexamples/pipeline.full.annotated.ymlexamples/session.template.ymlexamples/session.local-audio.ymlexamples/session.s3-audio.yml
These examples are validated by internal/config tests.