# Ansible Role: Narratio Installs and configures [Narratio](https://gitea.maximumdirect.net/eric/narratio) from source on Ubuntu 26.04 (`x86_64` or `aarch64`). The role requires gathered facts and uses task-level privilege escalation for dependencies and managed application state. ## Variables ```yaml narratio_version: v3.1.0 narratio_repository_url: https://gitea.maximumdirect.net/eric/narratio.git narratio_source_dir: /usr/local/src/narratio narratio_binary_path: /usr/local/bin/narratio narratio_manage_build_dependencies: true narratio_go_snap_channel: 1.26/stable narratio_go_binary: /snap/bin/go narratio_user: narratio narratio_group: narratio narratio_config_path: /usr/local/etc/narratio/pipeline.yml narratio_config_owner: root narratio_config_group: narratio narratio_config_directory_mode: "0750" narratio_config_file_mode: "0640" narratio_workspace_root: /var/lib/narratio narratio_campaigns_root: /usr/local/share/narratio/campaigns narratio_spool_root: /var/spool/narratio narratio_cache_root: /var/cache/narratio ``` `narratio_whisperx_transcribe_url` is required and must be an absolute HTTP or HTTPS URL. Every other pipeline setting is optional and defaults to `null`: ```yaml narratio_configkit_imports: null narratio_workspace_cleanup_after_publish: null narratio_campaigns_default_campaign_id: null narratio_storage_backend: null narratio_storage_s3_bucket: null narratio_storage_s3_root_prefix: null narratio_storage_s3_region: null narratio_storage_s3_endpoint: null narratio_storage_s3_force_path_style: null narratio_storage_s3_access_key_id: null narratio_storage_s3_secret_access_key: null narratio_spool_delete_audio_after_publish: null narratio_cache_s3_audio: null narratio_publish_enabled: null narratio_publish_upload_run: null narratio_publish_outputs: null narratio_whisperx_language: null narratio_whisperx_timeout: null narratio_whisperx_retries: null narratio_whisperx_retry_delay: null narratio_whisperx_concurrency: null narratio_seriatim_binary: null narratio_seriatim_timeout: null narratio_seriatim_output_schema: null narratio_seriatim_coalesce_gap: null narratio_seriatim_report: null narratio_seriatim_env_overlap_word_run_gap: null narratio_seriatim_env_overlap_word_run_reorder_window: null narratio_seriatim_env_backchannel_max_duration: null narratio_seriatim_env_filler_max_duration: null narratio_audita_binary: null narratio_audita_timeout: null narratio_audita_credentials: null narratio_audita_modules: null narratio_audita_overlay: null narratio_audita_proposal_profile: null narratio_audita_validation_profile: null narratio_audita_transcript_description: null narratio_audita_config_path: null narratio_audita_output_schema: null narratio_normalize_output_path: null narratio_normalize_output_schema: null narratio_normalize_report: null narratio_trim_enabled: null narratio_trim_output_path: null narratio_trim_bounds_prompt_id: null narratio_trim_bounds_profile_id: null narratio_trim_bounds_transcript_input_name: null narratio_trim_bounds_output_path: null narratio_trim_bounds_timeout: null narratio_trim_bounds_render_debug: null narratio_trim_bounds_render_output_path: null narratio_trim_seriatim_report: null narratio_render_enabled: null narratio_render_format: null narratio_render_title: null narratio_render_include_timestamps: null narratio_render_include_segment_ids: null narratio_render_include_metadata: null narratio_scriptorium_binary: null narratio_scriptorium_credentials: null narratio_scriptorium_config_path: null narratio_scriptorium_timeout: null narratio_scriptorium_render_debug: null narratio_scriptorium_artifacts: null narratio_scriptorium_artifact_families: null narratio_notarius_enabled: null narratio_notarius_binary: null narratio_notarius_config_path: null narratio_notarius_config_overlay: null narratio_notarius_pipeline_id: null narratio_notarius_timeout: null narratio_notarius_working_directory: null narratio_notarius_credentials: null narratio_notarius_resume: null narratio_notarius_chunk_cache: null narratio_notarius_references: null narratio_notarius_outputs: null narratio_notification_mode: null ``` With dependency management enabled, the role installs Git and the classic Go Snap from `narratio_go_snap_channel`. When disabled, Git and the executable at `narratio_go_binary` must already be available. The role checks out `narratio_version`, builds `./cmd/narratio` to `narratio_binary_path`, and rebuilds only when the checkout changes or the binary is absent. The `narratio` account owns the workspace, spool, and cache roots, which are group-writable setgid directories. The campaign registry is `root:narratio` and operator-readable; its content remains caller-managed. Configuration ownership and modes are independently configurable: the standalone defaults are `root:narratio`, mode `0750` for the directory and `0640` for the managed pipeline file. Composing roles may override these inputs without changing the writable-root policy. Null pipeline values and their empty parent mappings are omitted; non-null falsey values are preserved. `narratio_publish_outputs`, `narratio_notarius_references`, `narratio_notarius_outputs`, `narratio_scriptorium_artifacts`, and `narratio_scriptorium_artifact_families` are complete native caller values, so callers may compose them before assigning them and the role does not merge or rewrite them. The optional `narratio_notarius_config_overlay` selects a Notarius ConfigKit overlay without coupling it to Narratio's own overlay name. The optional `narratio_notarius_resume` and `narratio_notarius_chunk_cache` settings expose Narratio's native extraction and chunk-plan choices; this generic role assigns no D&D-specific credential or cache policy. ConfigKit imports and selected overlays are externally managed, and this role does not install the downstream applications, campaign content, or suite policy. ## Upgrading from Narratio v2 Narratio v3 removes these role variables and their native fields: `narratio_audita_llm_api_key`, `narratio_audita_base_url`, `narratio_audita_model`, `narratio_audita_total_llm_concurrency`, `narratio_audita_proposal_llm_concurrency`, `narratio_audita_validation_model`, `narratio_audita_validation_llm_concurrency`, `narratio_audita_work_dir_retention`, and `narratio_audita_report`. Replace `narratio_notarius_llm_api_key` with the list-valued `narratio_notarius_credentials`; rename `narratio_notarius_config_profile` to `narratio_notarius_config_overlay`. Existing deployments that cannot migrate these inputs should retain their previous role pin. See the tagged [v3.0.0 release notes](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.0.0/docs/releases/v3.0.0.md). `narratio_audita_credentials` and `narratio_notarius_credentials` are lists of environment-variable or secret-reference **names**, never credential values. Callers supply nonempty values through Narratio's run environment or supported secret source. Narratio resolves configured names when loading a pipeline, including when the downstream stage will be skipped. Audita v2 needs names for every credential in its configured backends, even backends not selected by the current profiles; Notarius names must match its selected provider profiles. The role does not inspect downstream files or resolve secrets. Null omits a list or selector, `[]` emits an explicit empty list, and `""` emits an explicit empty selector. A Narratio overlay replaces a credential list rather than appending to it. `narratio_scriptorium_credentials` is likewise an optional list of exact environment-variable or secret-reference names, not credential values. Null omits the field; `[]` writes an explicit empty list and forwards nothing. When nonempty, Narratio resolves every selected name to a nonempty value at pipeline load time, even for inspection commands that do not run Scriptorium. Provision those values through Narratio's existing process environment or secrets-directory mechanism. Provider/profile selection remains Scriptorium's responsibility, and this standalone role does not choose provider names. Audita v2 owns its configuration, backend/model definitions, PromptKit profiles, reporting, and debug policy. Configure it independently before using polish; the role does not generate downstream files or guess replacements for the removed tuning fields. The Audita overlay, proposal profile, and validation profile selectors are independent of each other and Narratio's selected overlay. The Notarius `config_overlay` selector is likewise independent; null adds no downstream selection, while empty, `default`, and named strings are passed to Notarius unchanged. Selected downstream features require compatible Audita and Notarius executables; this role adds no version gate. See the tagged [Audita](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.0.0/docs/integrations/audita.md) and [Notarius](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.0.0/docs/integrations/notarius.md) integration contracts. For Narratio itself, replace `--profile` with `--overlay` and move selected `profiles/.yml` files to `overlays/.yml` beside the pipeline root. Explicit ConfigKit imports from a directory named `profiles` remain valid; PromptKit LLM-profile files are a separate concept. Notarius's renamed `config_overlay` selects its own `overlays/` files, replacing its retired configuration-profile selection. The D&D suite's testing file and selector migrate later with coordinated suite integration, not in this generic role. Before opening an affected existing session, follow the tagged [manifest migration procedure](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.0.0/docs/operations.md#migrating-manifest-overlay-provenance): back up the local manifest and change only `effective_config.selected_profile` to `selected_overlay` (or remove the retired informational member), preserving local progress and checkpoints. Immutable remote snapshots are not edited in place. For named Notarius selectors, the renamed field changes extraction resume evidence: the next applicable run regenerates extraction with normal dependent invalidation. Omitted/base selection does not gain invalidation solely from the rename. The role performs no manifest migration, cache cleanup, or blanket forced reruns. ## Example ```yaml - hosts: narratio_hosts roles: - role: ansible-role-narratio vars: narratio_whisperx_transcribe_url: https://whisperx.example.test/transcribe ``` ## Validation The repository-local integration suite installs its pinned collection and runs syntax checking and production-profile lint. It validates a baseline managed pipeline through Narratio as its application account and requires immediate clean repeated convergence. It explicitly selects `v2.1.0` and checks native version output, then combines missing-binary recovery with a caller-supplied Go executable while dependency management is disabled. A representative pipeline checks null omission, falsey values, caller-composed native collections, credential-name lists, downstream selectors, and the native Notarius `resume` and chunk-cache fields. It validates named and explicit-empty configurations offline and requires clean repeats. The suite restores the baseline deployment during cleanup. ```sh tests/integration ```