613 lines
32 KiB
Markdown
613 lines
32 KiB
Markdown
# Configuration Reference
|
|
|
|
## Purpose
|
|
|
|
Narratio resolves three YAML documents:
|
|
|
|
- `pipeline.yml`: pipeline/runtime settings
|
|
- `campaign.yml`: campaign identity and stable input defaults
|
|
- `session.yml`: session identity, metadata, and audio source selection
|
|
|
|
## Discovery and Selection
|
|
|
|
### `pipeline.yml`
|
|
|
|
When `--config` is omitted, search order is:
|
|
|
|
1. `/usr/local/etc/narratio/pipeline.yml`
|
|
2. `/etc/narratio/pipeline.yml`
|
|
|
|
### `campaign.yml`
|
|
|
|
Selection rules:
|
|
|
|
- if `--campaign-file` is 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:
|
|
|
|
1. `/usr/local/etc/narratio/session.yml`
|
|
2. `/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.
|
|
|
|
### Read-only effective pipeline inspection
|
|
|
|
`narratio config validate`, `narratio config show`, `narratio config sources`,
|
|
and `narratio config artifacts` use the same `--config`, `--campaign`,
|
|
`--campaign-file`, and
|
|
`--profile` selection rules as pipeline commands, but do not select, discover,
|
|
or load a session. They resolve configured typed credential references as part
|
|
of the ordinary ConfigKit load but expose only their environment-variable names;
|
|
they do not create runtime state.
|
|
`narratio config diff <left-profile> <right-profile>` uses the same pipeline and
|
|
campaign selectors, resolves each named profile with an independent ConfigKit
|
|
load, and does not accept a separate `--profile` flag.
|
|
|
|
Campaign selection is optional only when the resolved pipeline has no
|
|
`scriptorium.artifact_families`. When families are declared, Narratio selects a
|
|
campaign through an explicit flag or `pipeline.campaigns.default_campaign_id`,
|
|
then parses the campaign-owned party and expands concrete artifacts and any
|
|
family publish rules before validation. `config validate` prints the resulting
|
|
root, profile, and effective digest. `config show` emits the normalized
|
|
effective pipeline YAML, with defaults and concrete expansion included but
|
|
ConfigKit directives and family declarations omitted. This review projection is
|
|
not promised to be a reloadable authoring document. `config sources` prints a stable
|
|
source projection instead of effective values: root/import/profile/default
|
|
ownership plus campaign/party and generated-family records. Canonical derived
|
|
players trace to the party. `config artifacts` lists the concrete artifact map,
|
|
effective dependencies, and defining sources. The [CLI reference](cli.md#config-validate-config-show-config-sources-config-artifacts-and-config-diff)
|
|
owns command syntax and output conventions.
|
|
|
|
`config diff` compares normalized field values rather than YAML text or source
|
|
ownership. It emits sorted `added`, `removed`, and `changed` records, uses
|
|
compact deterministic JSON values, treats lists atomically, and reports `no
|
|
differences` when the complete effective configurations are equal. Concrete
|
|
family members and generated publish rules participate after expansion; moving
|
|
an equal value between eligible root/import sources does not create a
|
|
difference.
|
|
|
|
### Migrating to the maintained bundle
|
|
|
|
Use the [production/testing bundle](../examples/production-testing/pipeline.yml)
|
|
as the complete copyable migration reference. Keep production settings in the
|
|
base, split them into explicit additive imports, and place testing differences
|
|
in the fixed `profiles/testing.yml` overlay. Put ordinary artifacts and families
|
|
in the recommended one-definition files shown by that bundle. Convert campaign
|
|
rosters to [canonical party input](integrations/party.md), then express character
|
|
work as families. Inspect the result with `config validate`, `config show`,
|
|
`config sources`, and `config artifacts`; use `config diff default testing` to
|
|
review the overlay before running a session. Unversioned party documents are
|
|
rejected.
|
|
|
|
### 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
|
|
|
|
- ConfigKit performs strict typed YAML decoding and accepts exactly one document;
|
|
unknown fields, duplicate keys, and trailing documents fail load.
|
|
- A pipeline file may explicitly import additive YAML fragments through the
|
|
root-only `configkit.imports` list. Imported files contribute fields to one
|
|
logical pipeline document; they do not override fields supplied by the root
|
|
or another import.
|
|
- An omitted profile, an empty profile option, and the exact name `default`
|
|
select the base configuration. Any other name selects
|
|
`profiles/<name>.yml` relative to the pipeline root.
|
|
- Campaign, session, and canonical-party documents are strict single-source
|
|
ConfigKit schemas. They do not enable imports, profiles, or `configkit`
|
|
directives.
|
|
- 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.
|
|
- Session and party inputs inspected before typed loading are limited to 8 MiB.
|
|
- Pipeline defaults are applied before validation.
|
|
- Defaults apply only to absent fields. Explicit empty strings, zero values,
|
|
`false`, and `null` retain ConfigKit's typed meaning and are then checked by
|
|
Narratio domain validation; they are not silently replaced by defaults.
|
|
Explicit null optional stage sections stay absent, while required sections
|
|
fail validation.
|
|
- Campaign and session identities must agree.
|
|
- Required stable files (`speakers_file`, `autocorrect_file`, `glossary_file`,
|
|
`party_file`) are campaign-owned; the first three may be overridden by the
|
|
session. The optional `spell_catalog_file` also inherits a campaign value
|
|
when omitted by the session.
|
|
- `party_file` is parsed when pipeline and campaign configuration are combined.
|
|
It must be a versioned [canonical party](integrations/party.md), is
|
|
campaign-owned and derives the players input internally. `players_file` and
|
|
session `party_file` are unsupported configuration keys.
|
|
- Exactly one audio mode must be configured in session input:
|
|
- local (`audio_dir` or `audio_files`), or
|
|
- S3 (`audio_s3.prefix`).
|
|
|
|
### Pipeline imports and profiles
|
|
|
|
Large pipeline configurations may be split into explicitly named fragments and
|
|
may use fixed-path profile overlays:
|
|
|
|
```yaml
|
|
configkit:
|
|
imports:
|
|
- path: config/storage.yml
|
|
- path: config/integrations.yaml
|
|
|
|
campaigns:
|
|
root: /usr/local/share/narratio/campaigns
|
|
```
|
|
|
|
The maintained [production/testing bundle](../examples/production-testing/pipeline.yml)
|
|
is a complete copyable example of this structure, including canonical-party
|
|
artifact families.
|
|
|
|
Imports are resolved relative to the directory containing the root pipeline
|
|
file and are loaded in declaration order. Narratio does not scan directories or
|
|
infer fragments. Each import must be a confined regular `.yml` or `.yaml` file:
|
|
absolute paths, traversal, symlinks, directories, duplicate files, and an
|
|
import of the root pipeline itself are rejected. Imported files cannot declare
|
|
another `configkit` control section.
|
|
|
|
Base merging is additive. A map may be extended by multiple files when every
|
|
leaf is distinct, but a scalar, list, or map/list/scalar kind cannot be claimed
|
|
more than once, even when the repeated values are identical. Conflict errors
|
|
name the full field path and every source that claimed it. Narratio additionally
|
|
rejects an artifact or artifact-family key declared by more than one base file,
|
|
even when those files contribute disjoint children.
|
|
|
|
Profile names are case-sensitive and use ConfigKit's safe fixed-path naming
|
|
rules. Only the selected overlay is opened; a malformed unselected overlay does
|
|
not affect a base or different-profile load. Maps merge recursively, overlay
|
|
scalars replace base scalars, and overlay lists replace base lists completely.
|
|
Explicit `false`, zero, empty strings, empty containers, and null values remain
|
|
explicit inputs and are not refilled by defaults. Profiles cannot inherit,
|
|
stack, import files, or declare another ConfigKit control section.
|
|
|
|
During ConfigKit loading, Narratio applies fresh typed defaults, recorded
|
|
entry-level defaults and normalization, read-only file-local validation, and
|
|
ordinary path resolution before computing a deterministic effective
|
|
configuration digest. The digest represents the normalized, secret-free
|
|
runtime pipeline mapping; it excludes ConfigKit directives, source
|
|
provenance, profile identity, and raw environment secret values. Equivalent
|
|
effective mappings therefore have the same digest regardless of how fields are
|
|
split among the root and imports.
|
|
|
|
An imported field has the same meaning it would have in a monolithic root
|
|
pipeline. In particular, ordinary relative pipeline paths continue to resolve
|
|
from the root pipeline directory, not from the importing fragment's directory.
|
|
|
|
## Minimal Working Configuration
|
|
|
|
`pipeline.yml`
|
|
|
|
```yaml
|
|
campaigns:
|
|
root: /usr/local/share/narratio/campaigns
|
|
default_campaign_id: sample-campaign
|
|
whisperx:
|
|
transcribe_url: https://transcription.example.com/transcribe
|
|
```
|
|
|
|
`campaign.yml`
|
|
|
|
```yaml
|
|
campaign_id: sample-campaign
|
|
inputs:
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
party_file: ./party.yml
|
|
```
|
|
|
|
`session.yml` (local audio)
|
|
|
|
```yaml
|
|
session_id: 2026-05-03
|
|
inputs:
|
|
audio_dir: ./audio
|
|
```
|
|
|
|
## Secrets Handling
|
|
|
|
- Do not place raw secrets in YAML.
|
|
- Credential fields contain environment-variable names, represented internally
|
|
as ConfigKit typed secret references (for example
|
|
`pipeline.notarius.llm_api_key: NOTARIUS_LLM_API_KEY`). A configured reference
|
|
must resolve to a nonempty environment value during load.
|
|
- Every surviving reference is resolved during ordinary pipeline loading,
|
|
regardless of whether its integration is disabled, outside the selected
|
|
stage range, or eligible for resume. Omit the field or set it to `null` when
|
|
that deployment should not require the credential.
|
|
- Every command that loads a pipeline accepts `--secrets-dir <path>`. When the
|
|
flag is omitted, Narratio uses a present `secrets/` directory beside the
|
|
resolved root `pipeline.yml`; an absent conventional directory is ignored.
|
|
Explicit relative paths are resolved from the caller's working directory,
|
|
and a missing or empty explicit selection is an error.
|
|
- Each immediate regular file whose name is a valid environment-variable name
|
|
supplies one value. ConfigKit removes trailing CR/LF, permits a symlink as the
|
|
selected directory, rejects symlink entries, and limits input to 1 MiB per
|
|
file, 8 MiB total, and 1024 entries.
|
|
- An existing process environment value takes precedence over a credential file.
|
|
- On POSIX, operators must provision the directory with no group/other access
|
|
(normally `0700`) and files with no group/other access (normally `0600`);
|
|
ConfigKit validates type and bounds but does not enforce permission modes.
|
|
- Bootstrap happens once per command, before any configuration load or adapter
|
|
construction. Safe reports contain filenames, paths, and statuses, never values.
|
|
|
|
## Publish Configuration Summary
|
|
|
|
Publish rules live under `pipeline.publish`.
|
|
|
|
```yaml
|
|
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
|
|
```
|
|
|
|
Rules:
|
|
|
|
- `outputs[].source` is required.
|
|
- `outputs[].dest` may be omitted when derivable from source.
|
|
- extraction sources require an explicit `outputs[].dest` and publish only when
|
|
a rule names that source; the Notarius index and complete bundle are not
|
|
publish sources.
|
|
- `outputs[].required` defaults to `true`.
|
|
- publish locks are independent remote session objects managed with
|
|
`narratio session locks`; they are not pipeline configuration fields.
|
|
|
|
## Full Schema
|
|
|
|
### Pipeline
|
|
|
|
| Field | Type | Required | Default / Rule |
|
|
| --- | --- | --- | --- |
|
|
| `configkit.imports[].path` | string | No | explicit additive pipeline fragment relative to the root pipeline directory; `.yml` or `.yaml` regular files only |
|
|
| `pipeline.workspace.root` | string | No | `/var/lib/narratio` |
|
|
| `pipeline.workspace.cleanup_after_publish` | bool | No | `false`; selects the published run's workspace target for final cleanup and requires effective `pipeline.publish.enabled=true` and `pipeline.publish.upload_run=true` |
|
|
| `pipeline.campaigns.root` | string | No | `/usr/local/share/narratio/campaigns` |
|
|
| `pipeline.campaigns.default_campaign_id` | 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` | secret reference | Conditional | unset; must be paired with `secret_access_key` |
|
|
| `pipeline.storage.s3.secret_access_key` | secret reference | Conditional | unset; must be paired with `access_key_id` |
|
|
| `pipeline.spool.root` | string | No | `/var/spool/narratio` |
|
|
| `pipeline.spool.delete_audio_after_publish` | bool | No | `false`; selects the published run's spool-audio target for final cleanup and requires effective `pipeline.publish.enabled=true` and `pipeline.publish.upload_run=true` |
|
|
| `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.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` | secret reference | No | unset |
|
|
| `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.llm_api_key` | secret reference | No | unset; exact environment-variable name forwarded to 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.references` | map[string]string | No | empty; maps normalized Notarius selectors to supported prepared Narratio source IDs; maximum 256 entries |
|
|
| `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.scriptorium.artifact_families` | map | No | empty; expands one ordinary artifact per canonical party character |
|
|
| `pipeline.notification.mode` | string | No | `noop`; the only supported notification mode until a provider is implemented |
|
|
|
|
### Notarius Credential
|
|
|
|
`pipeline.notarius.llm_api_key` optionally names the one environment variable
|
|
to forward to the Notarius child process:
|
|
|
|
```yaml
|
|
notarius:
|
|
llm_api_key: OPENROUTER_API_KEY
|
|
```
|
|
|
|
The field contains the variable name, not a credential value. That name must
|
|
match `api_key_env` in the Notarius/PromptKit profile selected by the deployed
|
|
Notarius pipeline; Narratio does not infer or remap provider names. Omission or
|
|
`null` forwards nothing. A non-null selected reference must resolve at pipeline
|
|
load time through the process environment or existing secrets-directory
|
|
bootstrap, even when Notarius is disabled, extract is outside the requested
|
|
range, or a completed extraction can be reused.
|
|
|
|
The Notarius child receives only Narratio's minimal execution environment plus
|
|
this exact selected name and loaded value. Other credentials are not forwarded.
|
|
Changing the value, name, presence, or absence does not invalidate extract's
|
|
semantic resume evidence. The public name remains part of safe effective
|
|
inspection, so renaming it may appear in `config diff` and change the effective
|
|
configuration digest; rotating only its value does neither.
|
|
|
|
See the [Notarius integration contract](./integrations/notarius.md) for the
|
|
delivery and redaction boundary.
|
|
|
|
### Notarius Reference Bindings
|
|
|
|
`pipeline.notarius.references` maps a Notarius CLI selector to a prepared
|
|
Narratio source, not to a filesystem path:
|
|
|
|
```yaml
|
|
notarius:
|
|
references:
|
|
glossary: narratio.input.glossary
|
|
party: narratio.input.party
|
|
players: narratio.input.players
|
|
spell_catalog: narratio.input.spell_catalog
|
|
```
|
|
|
|
Supported sources are `narratio.input.party`, `narratio.input.players`,
|
|
`narratio.input.glossary`, and `narratio.input.spell_catalog`. Each map entry is
|
|
required by its presence: omit a binding when the selected Notarius pipeline
|
|
does not need it. A spell-catalog binding additionally requires an effective
|
|
campaign or session `spell_catalog_file`.
|
|
|
|
Selectors accept Notarius's `slot`, `chunk.slot`, `lane.slot`,
|
|
`lane.extract.slot`, `lane.merge.slot`, and `lane.normalize.slot` forms.
|
|
Narratio trims whitespace around
|
|
selectors and their dot-separated components, rejects empty components and
|
|
`=`, rejects duplicate normalized selectors, and limits the map to 256 entries.
|
|
It validates only selector structure and the prepared source vocabulary;
|
|
Notarius owns target-slot declarations and media compatibility.
|
|
|
|
Before extraction, Narratio resolves every binding from the current prepared
|
|
session manifest and streams it into a verified invocation-local snapshot whose
|
|
absolute path is passed to Notarius. Missing, unsafe, empty,
|
|
changed-during-copy, or checksum-inconsistent prepared evidence fails with
|
|
guidance to force `prepare`. Bindings are sorted by normalized selector and are
|
|
part of extraction fingerprint and resume identity. See the
|
|
[Notarius integration contract](./integrations/notarius.md) for the subprocess
|
|
boundary and the [complete example](../examples/pipeline.full.annotated.yml)
|
|
for a copyable configuration.
|
|
|
|
### 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](../examples/pipeline.full.annotated.yml) for the
|
|
current ten-lane D&D mapping and the [Notarius contract](./integrations/notarius.md)
|
|
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 | explicit ordering-only edges; must reference configured artifact keys, may not self-reference, and join inferred input edges in one acyclic graph |
|
|
| `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.
|
|
|
|
Without `--artifacts`, analyze executes enabled configured artifacts. With an
|
|
explicit `--artifacts` list, the exact named configured artifacts are the
|
|
one-invocation targets even if their `enabled` values are false. Analyze closes
|
|
those targets over the effective dependency graph: a current prerequisite is reused, while a
|
|
stale, missing, or failed prerequisite is rebuilt before its dependent.
|
|
Unrelated artifacts are not executed. Named targets and any prerequisite that
|
|
may require rebuilding must therefore have valid executable fields. This
|
|
override affects analyze planning only; publish uses the list only to filter
|
|
configured `narratio.artifact.<name>` output rules.
|
|
|
|
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.
|
|
|
|
Each `narratio.artifact.<name>` input source automatically contributes an
|
|
effective dependency on that configured artifact. Narratio unions these inferred
|
|
edges with explicit `depends_on` entries, then trims, deduplicates, and sorts the
|
|
result during final configuration resolution. Authors use `depends_on` only for
|
|
ordering constraints that are not already expressed by an artifact input.
|
|
Use [`narratio config artifacts`](./cli.md#config-validate-config-show-config-sources-config-artifacts-and-config-diff)
|
|
to inspect keys, definition sources, outputs, and effective dependencies without
|
|
loading a session or creating runtime state.
|
|
|
|
### Scriptorium Artifact Families
|
|
|
|
`pipeline.scriptorium.artifact_families` declares a shared artifact template
|
|
for every canonical campaign character. Configuration resolution expands each
|
|
family into ordinary `pipeline.scriptorium.artifacts` entries before analyze
|
|
planning or Scriptorium invocation. Party parsing rejects unsupported document
|
|
schemas before family expansion.
|
|
|
|
For each `pipeline.scriptorium.artifact_families.<name>`:
|
|
|
|
| Field | Type | Required | Rule |
|
|
| --- | --- | --- | --- |
|
|
| `enabled`, `prompt_id`, `profile_id`, `timeout`, `render_debug`, `depends_on`, `inputs`, `vars` | ordinary artifact fields | No | copied to each generated artifact under the corresponding ordinary rules |
|
|
| `for_each` | string | Yes | exactly `party.characters` |
|
|
| `output_path_pattern` | string | Yes | safe path beneath `artifacts/` with exactly one `{character_id}` token and no other brace syntax |
|
|
| `member_vars` | map | No | maps an ordinary Scriptorium variable name to a supported canonical character selector |
|
|
| `member_dependencies` | list | No | unique family keys; each generated member depends on the corresponding generated member of each listed family |
|
|
| `publish` | map | No | typed family publish policy (`enabled`, `required`, `dest_pattern`) expanded into concrete publish outputs when enabled |
|
|
|
|
Generated keys are `<family>_<character_id>` and generated output paths must
|
|
not collide with explicit artifacts or another generated artifact. Families
|
|
expand even when disabled; normal analyze selection still omits disabled
|
|
artifacts unless they are explicitly selected by their concrete key.
|
|
|
|
Supported `member_vars` selectors are `character_id`, `player.name`,
|
|
`character.name`, `character.class_summary`, and `character.alias_summary`.
|
|
Their resolved values are strings. A member variable may not reuse a static
|
|
`vars` name; `session_id` remains owned and overwritten by Narratio as for any
|
|
other Scriptorium artifact.
|
|
|
|
Within a family only, an input source may use
|
|
`narratio.member_artifact.<family>`. Resolution rewrites the source to the
|
|
corresponding ordinary `narratio.artifact.<family>_<character_id>` source and
|
|
infers the concrete member dependency. Use `member_dependencies` only for
|
|
additional same-character ordering constraints that are not already inputs.
|
|
This syntax is rejected in explicit artifacts and never reaches runtime stages
|
|
or Scriptorium.
|
|
|
|
### 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.party_file` | string | Yes | stable campaign party source; relative paths resolve from `campaign.yml` |
|
|
| `inputs.spell_catalog_file` | string | No | optional spell-catalog overlay default; required when a Notarius reference selects `narratio.input.spell_catalog` |
|
|
|
|
### 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.spell_catalog_file` | string | No | overrides the optional campaign spell catalog; empty or omitted inherits the campaign value |
|
|
| `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_dir` or `audio_files`) or S3 mode (`audio_s3.prefix`), not both.
|
|
- `audio_s3` requires `pipeline.storage.backend: s3` and 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](../examples/README.md) for complete pipeline,
|
|
campaign, session, template, and input fixtures. Keep complete copyable files
|
|
there rather than duplicating them in this reference.
|