17 KiB
Configuration Reference
Purpose
Narratio resolves three YAML documents:
pipeline.yml: pipeline/runtime settingscampaign.yml: campaign identity and stable input defaultssession.yml: session identity, metadata, and audio source selection
Discovery and Selection
pipeline.yml
When --config is omitted, search order is:
/usr/local/etc/narratio/pipeline.yml/etc/narratio/pipeline.yml
campaign.yml
Selection rules:
- if
--campaign-fileis set, use that path; - else if
--campaign <id>is set, use{pipeline.campaigns.root}/{id}/campaign.yml; - else use
{pipeline.campaigns.root}/{pipeline.campaigns.default_campaign_id}/campaign.yml.
session.yml
When --session is omitted, local search order is:
/usr/local/etc/narratio/session.yml/etc/narratio/session.yml
If local session discovery fails and a session_id is known, Narratio attempts remote session loading from:
{root_prefix}/campaigns/{campaign}/sessions/{session_id}/session.yml
using configured object storage.
The downloaded remote session file is command-scoped: Narratio removes it after the command finishes and records only the remote object provenance alongside the durable copied session input.
Identity segments
Campaign IDs (campaign_id and default_campaign_id), session IDs, previous
session IDs, and Narratio run IDs are opaque portable segments. They must use
only ASCII letters, digits, ., _, and -; empty values, ./.., path
separators, drive forms, whitespace, control characters, and non-ASCII text are
rejected. Narratio does not trim or rewrite these values. Existing manifests or
remote state with an unsafe legacy identity must be migrated before use.
Validation and Merge Rules
- YAML decode is strict (
KnownFields(true)) and accepts exactly one document: unknown fields or trailing documents fail load. - Configured timeout and retry-delay durations must be positive. An omitted artifact timeout continues to inherit its configured Scriptorium timeout.
- Session files must be concrete; unresolved
{{ ... }}placeholders fail load. - Pipeline defaults are applied before validation.
- Campaign and session identities must agree.
- Stable files (
speakers_file,autocorrect_file,glossary_file,players_file,party_file) resolve from session overrides when provided, otherwise from campaign defaults. - Exactly one audio mode must be configured in session input:
- local (
audio_diroraudio_files), or - S3 (
audio_s3.prefix).
- local (
Minimal Working Configuration
pipeline.yml
campaigns:
root: /usr/local/share/narratio/campaigns
default_campaign_id: sample-campaign
whisperx:
transcribe_url: https://transcription.example.com/transcribe
campaign.yml
campaign_id: sample-campaign
inputs:
speakers_file: ./speakers.yml
autocorrect_file: ./autocorrect.yml
glossary_file: ./glossary.yml
players_file: ./players.yml
party_file: ./party.yml
session.yml (local audio)
session_id: 2026-05-03
inputs:
audio_dir: ./audio
Secrets Handling
- Do not place raw secrets in YAML.
- Use env var names in config (for example
pipeline.audita.llm_api_key_env). - Optionally load credential files from
pipeline.secrets.env_dir. Each valid environment-variable filename supplies one value; trailing CR/LF is removed. - An existing process environment value takes precedence over a credential file.
- Credential directories and files must not be symlinks and must be regular,
bounded files (at most 8 KiB per value). On POSIX, provision the directory
with no group/other access (normally
0700) and files with no group/other access (normally0600). - Commands that need storage/auth load filesystem secrets before constructing adapters.
Publish Configuration Summary
Publish rules live under pipeline.publish.
publish:
enabled: true
upload_run: true
outputs:
- source: narratio.transcript.final_trimmed
dest: transcripts/final.trimmed.json
required: true
- source: narratio.transcript.final_markdown
dest: transcripts/final.md
required: true
- source: narratio.transcript.final_trimmed_markdown
dest: transcripts/final.trimmed.md
required: true
- source: narratio.artifact.session_recap
dest: artifacts/session_recap.md
required: true
locks:
- source: narratio.artifact.session_recap
reason: manual post-publish edits
Rules:
outputs[].sourceis required.outputs[].destmay be omitted when derivable from source.- extraction sources require an explicit
outputs[].destand publish only when a rule names that source; the Notarius index and complete bundle are not publish sources. outputs[].requireddefaults totrue.- static locks (
pipeline.publish.locks) merge with remote locks ({session_prefix}/locks.yml), with static locks taking precedence on duplicates.
Full Schema
Pipeline
| Field | Type | Required | Default / Rule |
|---|---|---|---|
pipeline.workspace.root |
string | No | /var/lib/narratio |
pipeline.workspace.cleanup_after_publish |
bool | No | false |
pipeline.campaigns.root |
string | No | /usr/local/share/narratio/campaigns |
pipeline.campaigns.default_campaign_id |
string | No | empty |
pipeline.secrets.env_dir |
string | No | empty |
pipeline.storage.backend |
string | No | local; supported values are local and s3 (case-insensitive) |
pipeline.storage.s3.bucket |
string | Conditional | required when backend is s3 and S3 session-audio or publish upload is enabled |
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_publish |
bool | No | false |
pipeline.cache.root |
string | No | /var/cache/narratio |
pipeline.cache.s3_audio |
bool | No | true |
pipeline.publish.enabled |
bool | No | true |
pipeline.publish.upload_run |
bool | No | true |
pipeline.publish.outputs[] |
list | No | defaults to final trimmed JSON plus final and final-trimmed Markdown outputs |
pipeline.publish.outputs[].source |
string | Yes (per rule) | must reference built-in or configured artifact source |
pipeline.publish.outputs[].dest |
string | Conditional | derived if omitted and source supports derivation |
pipeline.publish.outputs[].required |
bool | No | true |
pipeline.publish.locks[] |
list | No | empty |
pipeline.publish.locks[].source |
string | Yes (per lock) | must reference supported publish source |
pipeline.publish.locks[].reason |
string | No | empty |
pipeline.whisperx.transcribe_url |
string | Yes | absolute http or https URL |
pipeline.whisperx.language |
string | No | en |
pipeline.whisperx.timeout |
duration | No | 30m |
pipeline.whisperx.retries |
int | No | 3 |
pipeline.whisperx.retry_delay |
duration | No | 2s |
pipeline.whisperx.concurrency |
int | No | 2 |
pipeline.seriatim.binary |
string | No | seriatim |
pipeline.seriatim.timeout |
duration | 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 | 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/final.json |
pipeline.normalize.output_schema |
string | No | seriatim-intermediate |
pipeline.normalize.report |
bool | No | true |
pipeline.trim.enabled |
bool | No | true |
pipeline.trim.output_path |
string | No | transcripts/final.trimmed.json |
pipeline.trim.bounds.prompt_id |
string | No | dnd.session_bounds |
pipeline.trim.bounds.profile_id |
string | No | empty |
pipeline.trim.bounds.transcript_input_name |
string | No | transcript |
pipeline.trim.bounds.output_path |
string | No | artifacts/session_bounds.json |
pipeline.trim.bounds.timeout |
duration | No | 10m |
pipeline.trim.bounds.render_debug |
bool | No | false |
pipeline.trim.bounds.render_output_path |
string | Conditional | required when render_debug is true |
pipeline.trim.seriatim.report |
bool | No | false |
pipeline.notarius.enabled |
bool | No | false |
pipeline.notarius.binary |
string | No | notarius |
pipeline.notarius.config_path |
string | Conditional | required when enabled; relative paths resolve from the pipeline file directory |
pipeline.notarius.pipeline_id |
string | Conditional | required when enabled |
pipeline.notarius.timeout |
duration | No | 3h; must be positive |
pipeline.notarius.working_directory |
string | No | directory containing resolved config_path; relative paths resolve from the pipeline file directory |
pipeline.notarius.outputs |
map | Conditional | at least one entry when enabled |
pipeline.render.enabled |
bool | No | true |
pipeline.render.format |
string | No | markdown (only supported value) |
pipeline.render.title |
string | No | empty (falls back to session.title when set) |
pipeline.render.include_timestamps |
bool | No | true |
pipeline.render.include_segment_ids |
bool | No | true |
pipeline.render.include_metadata |
bool | No | false |
pipeline.scriptorium.binary |
string | No | scriptorium |
pipeline.scriptorium.config_path |
string | No | empty |
pipeline.scriptorium.timeout |
duration | No | 10m |
pipeline.scriptorium.render_debug |
bool | No | false |
pipeline.scriptorium.artifacts |
map | No | empty |
pipeline.notification.mode |
string | No | noop; the only supported notification mode until a provider is implemented |
Notarius Output Entries
For each pipeline.notarius.outputs.<name>:
| Field | Type | Required | Rule |
|---|---|---|---|
lane_id |
string | Yes | unique Notarius lane ID |
media_type |
string | Yes | exact accepted descriptor media type |
schema_id |
string | Yes | exact accepted descriptor schema ID |
schema_version |
string | Yes | exact accepted descriptor schema version |
module_key |
string | No | exact accepted module key when set |
Output names must match ^[a-z][a-z0-9_]*$ and become selectable sources named
narratio.extraction.<name>. Lane IDs must be unique. Every declared output is
required from a successful Notarius result; a missing, rejected, duplicate, or
contract-incompatible lane fails extraction. See the
complete maintained example for the
current ten-lane D&D mapping and the Notarius contract
for compatibility ownership.
Scriptorium Artifact Entries
For each pipeline.scriptorium.artifacts.<name>:
| Field | Type | Required | Rule |
|---|---|---|---|
enabled |
bool | No | false if omitted |
depends_on[] |
list[string] | No | must reference configured artifact keys; no self-reference; enabled graph must be acyclic |
render_debug |
bool | No | per-artifact override |
prompt_id |
string | Conditional | required when artifact is enabled |
profile_id |
string | No | empty |
output_path |
string | Conditional | required when enabled; also required when referenced by publish/output/input rules |
timeout |
duration | No | artifact override |
inputs |
map | No | input key names must be non-empty |
vars |
map | No | values must be string or bool; session_id is reserved and overwritten by Narratio |
Narratio adds session_id=narratio-session-<session_id> to every Scriptorium request for sticky upstream LLM routing. If an artifact config sets vars.session_id, Narratio replaces that value before invoking Scriptorium. Use a different variable name if a prompt needs the raw Narratio session ID as content.
For each artifact input pipeline.scriptorium.artifacts.<name>.inputs.<input_name>:
| Field | Type | Required | Rule |
|---|---|---|---|
source |
string | Yes | built-in runtime source, prepared input source, narratio.extraction.<name>, narratio.artifact.<name>, or narratio.previous_session.artifact.<name> |
required |
bool | No | optional input requirement |
artifact and path are obsolete and rejected by strict configuration
loading. Use the canonical source identifier to select the input; Narratio
does not provide adapter-specific input passthrough fields.
Notifications
Narratio currently supports only notification.mode: noop, which is also the
default when the section is omitted. The notify stage performs no delivery in
this mode. Backend, recipient, timeout, and other provider settings are
rejected by strict configuration loading until Narratio has a provider
integration.
Campaign
| Field | Type | Required | Notes |
|---|---|---|---|
campaign_id |
string | Yes | canonical opaque campaign identity |
session_template_file |
string | No | used by session init when set |
inputs.speakers_file |
string | Yes | stable input default |
inputs.autocorrect_file |
string | Yes | stable input default |
inputs.glossary_file |
string | Yes | stable input default |
inputs.players_file |
string | Yes | stable input default |
inputs.party_file |
string | Yes | stable input default |
Session
| Field | Type | Required in session file | Notes |
|---|---|---|---|
session_id |
string | Yes | opaque identity; must match CLI session target when provided |
previous_session_id |
string | No | opaque identity; must not equal session_id |
campaign |
string | No | opaque identity; filled from campaign_id during resolve if omitted |
date |
string | No | metadata |
title |
string | No | metadata |
inputs.speakers_file |
string | No | overrides campaign stable input |
inputs.autocorrect_file |
string | No | overrides campaign stable input |
inputs.glossary_file |
string | No | overrides campaign stable input |
inputs.players_file |
string | No | overrides campaign stable input |
inputs.party_file |
string | No | overrides campaign stable input |
inputs.audio_dir |
string | Conditional | local audio mode |
inputs.audio_files[] |
list[string] | Conditional | local audio mode |
inputs.audio_s3.prefix |
string | Conditional | S3 audio mode |
Audio rules:
- configure local mode (
audio_diroraudio_files) or S3 mode (audio_s3.prefix), not both. audio_s3requirespipeline.storage.backend: s3and a configured S3 bucket.
Storage backend selection
local is the default and disables remote object-store operations. Configure
s3 explicitly before supplying storage.s3; a populated S3 block does not
select a backend on its own. Unknown backend names and an S3 block paired with
local are rejected during configuration validation.
Previous-session expectation
previous_session_id is optional in a session file. When a command supplies
--previous-session-id, however, the session file must contain the same value;
an omitted or different value is rejected before the command performs work.
Maintained Examples
See the maintained examples index for complete pipeline, campaign, session, template, and input fixtures. Keep complete copyable files there rather than duplicating them in this reference.