# Implementation Plan 0023: Narratio Scriptorium Credentials Status: in_progress Target executor: GPT-5.6-Terra Feature roadmap: [Feature 0023](features/0023-narratio-scriptorium-credentials.md) ## Objective Deploy Narratio v3.1.0 through the existing source-build roles and expose its Scriptorium credential list. The roadmap owns scope and rationale. This plan does not deploy to an operational controller or `pipeline-dnd`. ## Execution Rules and Starting State - Execute stages in numeric order. Before each stage, reread its listed policies (paths relative to the workspace), applicable local instructions, and inspect working trees. Preserve unrelated changes. Commit validated stages separately. - Use workspace `.venv/bin` tooling; harnesses select it themselves. A missing PATH entry is not a missing Ansible controller. - Integration harnesses use sudo and mutate the local development installation. Read setup/cleanup and confirm local paths are disposable before running them. Do not contact operational hosts, inference, transcription, or storage services. Public dependency downloads are expected. Report unsafe local mutation as a specific validation limit rather than silently running on another host. - Add no production tasks, state probes, wrappers, credential loaders, or application self-tests. Reuse ordinary source-build and template convergence. - Approval of this plan authorizes normal publication of the changed Narratio role, pipeline role, and collection commits to their `origin/main` branches for downstream public dependencies. No force pushes or tags. Do not publish consumer/workspace commits or unrelated work. Resolve any unrelated unpublished commits before pushing a branch that would include them. - The public Narratio v3.1.0 tag was verified on 2026-09-29 at `40cbf4243838b0a1db6caf4c8f790d914ccb96cc`, matching the reviewed contract. Install the released tag, not a moving branch. - Reviewed starting pins: Narratio role `3c0700b`, pipeline `37b1cf6`, collection `b3bc045`. Recheck actual heads; these identify context, not frozen assertions. The consumer already has local commits; preserve them. Record full resulting SHAs at each stage rather than inventing future commit IDs. - Scope: Narratio role, pipeline role, collection, consumer pins/guidance, and workspace tracking. Other roles, upstream applications, assets, Vault content, and operational deployments remain unchanged. ## Stage 1: Expose credentials in the standalone Narratio role Completion: complete (2026-09-29). Public role revision: `758aed7a74c9a64ad02e13ff551b4f7aea16b3af`. ### Required Policy Review Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, `docs/ansible.md`, and `docs/testing.md`, plus applicable repository-local instructions. ### Repository and Preconditions `ansible-role-narratio`; v3.1.0 must be fetchable. Review the released upstream `docs/config.md#scriptorium-credentials` and `docs/releases/v3.1.0.md`. ### Required Changes 1. Set `narratio_version: v3.1.0`. Add `narratio_scriptorium_credentials: null` and declare an optional list of strings in `meta/argument_specs.yml`. 2. Extend the Scriptorium section predicate in `templates/pipeline.yml.j2` and render `credentials` with `to_json` only when the variable `is not none`. Root YAML uses `scriptorium:`, without a new `pipeline:` wrapper. The field must render even when all other optional Scriptorium variables are null. 3. Document null omission, explicit `[]`, arbitrary provider reference names, load-time resolution, and environment/secrets provisioning. Keep provider policy out of the standalone role. 4. Extend existing tests: baseline explicitly omits this field; representative configuration supplies two synthetic names and checks that exact list; the existing empty-list case supplies and expects `[]`. Reuse existing synthetic names/values and pass them explicitly into native validation as the Narratio account. Cover credential-only section rendering within a focused configuration case, not a new exhaustive fixture matrix. 5. Include the new variable in baseline reset inputs so the existing v2.1.0 version-selection/recovery cases omit unsupported configuration. Preserve those cases. Explicitly request v3.1.0 in the representative case and verify its reported version; do not assert the role's current default version. ### Validation From this repository run `bash -n tests/integration`, `./tests/integration`, and `git diff --check`. The existing harness includes syntax/lint, native configuration validation, real convergence, and clean repeats. Require supplied list preservation, omission/empty-list semantics, the requested binary version, and zero changes on immediate reapplication. Do not simulate upstream provider requests or retest internal credential forwarding. ### Completion and Commit Commit `Support Scriptorium credentials in Narratio`. Publish the validated commit to the public role origin, verify with a remote lookup, and record its full SHA for Stage 2. ## Stage 2: Configure credentials in the D&D pipeline ### Required Policy Review Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, `docs/ansible.md`, and `docs/testing.md`, plus applicable repository-local instructions. ### Repository and Preconditions `ansible-role-dnd-pipeline`; Stage 1 is validated and public. ### Required Changes 1. Pin Stage 1's exact SHA in `requirements.yml`. Set `dnd_pipeline_narratio_version: v3.1.0`. Add `dnd_pipeline_narratio_scriptorium_credentials: [OPENROUTER_API_KEY]`, its optional list-of-strings argument specification, and the direct mapping to `narratio_scriptorium_credentials` in `meta/main.yml`. 2. Let the testing overlay inherit the base list. Preserve ordinary inventory replacement, `[]`, and null pass-through semantics; add no duplicate overlay default or per-stage setting. 3. Document that Notarius and Scriptorium can use the same provisioned key but have independent lists. Selected keys must resolve at load time even for inspection. Managed secret files are optional. Explain normal retry after upgrading, without forcing successful stages. 4. Extend the existing custom-credential fixture with an explicitly supplied Scriptorium list and synthetic values. Verify its presence in effective base and testing configurations, using existing native inspection and secret delivery. Do not assert the baseline default list or add subprocess stubs. Preserve the baseline's existing synthetic OpenRouter key. 5. Leave other application versions, model/profile choices, tasks, secrets policy, and dependency pins unchanged. ### Validation Run `bash -n tests/integration`, `./tests/integration`, and `git diff --check`. Require native base/testing acceptance and the existing immediate clean-repeat behavior, without live service calls. ### Completion and Commit Commit `Forward Scriptorium credentials in the D&D suite`. Publish and record the validated public pipeline SHA for Stage 3. ## Stage 3: Assemble the updated collection ### Required Policy Review Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, `docs/ansible.md`, and `docs/testing.md`, plus applicable repository-local instructions. ### Repository and Preconditions `ansible-collection-dnd`; Stage 2's exact source revision is public. ### Required Changes 1. Import the recorded full SHA through the existing public workflow: ```sh git subtree pull --prefix=roles/pipeline \ https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git \ --squash ``` Replace the placeholder; never edit the subtree directly or import a sibling path. Keep the normal subtree merge/squash commits. 2. Update the collection-owned `requirements.yml` Narratio role pin to Stage 1. Preserve other pins and collection metadata version; this is not a new tagged release. Update any current development compatibility guidance as needed. 3. Adjust collection-owned fixtures only if synthetic credentials are missing. The baseline already supplies `OPENROUTER_API_KEY`. Do not duplicate detailed role tests or add assertions that freeze suite defaults. ### Validation Run `bash -n tests/integration`, `./tests/integration`, and `git diff --check`. The harness builds/installs the artifact in isolated Ansible paths, resolves public dependencies, validates base/testing configuration, and checks repeats. Compare the imported `HEAD:roles/pipeline` Git tree with the source commit's tree; they must match exactly. ### Completion and Commit Commit collection-owned changes as `Ship the Narratio credential forwarding update`. Publish the validated collection head and record its full SHA. ## Stage 4: Refresh the consumer without deploying ### Required Policy Review Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, `docs/ansible.md`, and `docs/testing.md`, plus applicable repository-local instructions. ### Repository and Preconditions `rakestraw-ansible`; Stage 3 is validated and public. Preserve pre-existing local commits and unrelated requirements. ### Required Changes 1. Update only Narratio role and `rakestraw.dnd` pins in `requirements.yml` to the full Stage 1 and Stage 3 SHAs. 2. Update `docs/pipeline-dnd.md`'s explicit refresh SHA and source guidance links. Explain v3.1.0 credential selection and ordinary retry. Keep forced refresh instructions for development snapshots with unchanged collection metadata and preserve prior migration guidance. 3. Leave playbook, host variables, and Vault unchanged: the suite selects the existing Notarius key. No real keys or wrappers are needed. ### Validation Using workspace `.venv/bin/ansible-galaxy`, install the D&D dependencies and the pinned collection into fresh `mktemp -d` paths. Reuse the collection manifest for that dependency set rather than installing unrelated maximumdirect projects. Set `ANSIBLE_ROLES_PATH` and `ANSIBLE_COLLECTIONS_PATH` to the disposable paths. From the consumer repository, using its existing inventory configuration, run: ```sh ../.venv/bin/ansible-playbook playbooks/pipeline/dnd.yml --list-hosts ../.venv/bin/ansible-playbook playbooks/pipeline/dnd.yml --syntax-check git diff --check ``` Require only `pipeline-dnd` in the host list and successful dependency/syntax resolution. These checks do not deploy or require provider keys/Vault decryption. Do not add ansible-doc output, live host access, or API success as a gate. ### Completion and Commit Commit `Use Narratio with Scriptorium credential forwarding`. Leave consumer commits local; record validation and the selected collection revision. ## Stage 5: Record implementation results for review ### Required Policy Review Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, and `docs/planning.md`. ### Repository and Preconditions Workspace root; Stages 1–4 are completed and validated. ### Required Changes and Validation Update Feature 0023 and `docs/status.md` to `in_progress`, implementation complete and awaiting independent review. Record exact commits, public versus local status, validation commands/results, and deviations. Add concise stage evidence below. Run `git diff --check` and `scripts/status`; confirm changed repositories are clean after their commits. Do not mark the feature done or retire the plan. ### Completion and Commit Commit `Record the Scriptorium credential update handoff`. Leave workspace commits local. Report unverified behavior explicitly: offline checks do not prove the operator's actual key is valid or that live trim succeeds. ## Progress Notes Stage 1 passed shell syntax, the full role integration harness, and whitespace checks. Its exact commit was published to the existing Narratio-role Gitea origin and verified after fetch. ## Open Questions None.