diff --git a/docs/roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md b/docs/roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md index 2bc6cff..07b54ed 100644 --- a/docs/roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md +++ b/docs/roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md @@ -1,6 +1,6 @@ # Feature 0016: Deploy the D&D Pipeline to `pipeline-dnd` -Status: proposed +Status: ready ## Summary @@ -10,10 +10,10 @@ host through `host_vars`, enroll `eric` as the initial human operator, keep credential values in Ansible Vault, and prove the complete pipeline through a real repeatable deployment and representative D&D session. -[Feature 0015](0015-dnd-s3-storage-and-publishing.md) must first provide the -storage and publishing behavior needed for an operational end-to-end pipeline. -Feature 0016 consumes that reviewed interface; it does not invent a temporary -storage contract. +[Feature 0015](0015-dnd-s3-storage-and-publishing.md) has implemented and passed +independent review of the storage and publishing behavior needed for an +operational end-to-end pipeline. Feature 0016 consumes that reviewed interface +and its suite defaults. ## Problem or Opportunity @@ -43,10 +43,11 @@ synthetic scenario. - Map the role's `dnd_pipeline_secrets` interface to host-specific Vault variables. Store credential values only in an Ansible Vault-encrypted host variables file. -- Carry the storage and publishing settings selected by Feature 0015 through - its final public pipeline interface. Preserve the operational intent of the - existing Backblaze B2 endpoint, bucket, prefix, region, and path-style - settings where they remain applicable. +- Inherit Feature 0015's storage and publishing defaults, which already match + the intended Backblaze B2 deployment. Host inventory contains only actual + host choices and deliberate overrides, without copying suite defaults. +- Preserve the existing default campaign choice, `dilfs`, through the + standalone role's `narratio_campaigns_default_campaign_id` variable. - Reconcile existing legacy Narratio host variables so they cannot silently override the suite policy selected by the new pipeline role. - Update `rakestraw-ansible/requirements.yml` so a clean controller can install @@ -93,9 +94,9 @@ consumer playbook equivalent to: ``` The existing inventory selects the host's connection identity. A dedicated -host-variable file selects the pipeline's non-secret public inputs, including -the WhisperX endpoint, the initial operator list, and the storage and -publishing values exposed by Feature 0015. It maps runtime credential names to +host-variable file selects the WhisperX endpoint, the initial operator list, +and the default campaign. Storage, caching, publication, and cleanup inherit +the reviewed suite defaults. The file maps runtime credential names to Vault-backed variables without embedding credential values in the playbook or ordinary plaintext inventory, for example: @@ -106,6 +107,8 @@ dnd_pipeline_operator_users: dnd_pipeline_whisperx_transcribe_url: >- https://transcription.ai.rakestrawhome.com/transcribe +narratio_campaigns_default_campaign_id: dilfs + dnd_pipeline_secrets: AUDITA_LLM_API_KEY: "{{ vault_dnd_audita_llm_api_key }}" OPENROUTER_API_KEY: "{{ vault_dnd_openrouter_api_key }}" @@ -117,11 +120,19 @@ The corresponding credential variables reside in a tracked file encrypted in full with Ansible Vault. The Vault password or identity mechanism remains outside Git and outside this feature's managed content. -The controller dependency manifest selects one reviewed, publicly reachable -suite snapshot containing Features 0014 and 0015. It also installs that -snapshot's exact standalone role and native collection dependencies. A clean -controller therefore does not depend on sibling development checkouts or -previously installed roles. +The controller dependency manifest selects public collection commit +`46913446765e86ecfb29ebad9955d579ef6a4c7e`, containing the reviewed Features +0014 and 0015 and pipeline commit +`51566afcf69083cdbb5b5718f2544c86b079001c`. Its compatibility manifest selects +the five standalone roles at `v0.1.0`, `ansible.posix` at `2.2.0`, and +`community.general` at `13.3.0`. A clean controller therefore does not depend +on sibling development checkouts or previously installed roles. + +The published collection `v0.1.0` predates these features. The selected +development snapshot still declares collection version `0.1.0`, so the +deployment instructions explicitly refresh an already-installed collection +from the pinned commit instead of allowing an equal-version installation to +be skipped. Unrelated controller dependencies remain preserved. On `pipeline-dnd`, the role converges the full application suite and its D&D configuration. The `narratio` service identity can run the pipeline, and @@ -148,9 +159,9 @@ immediate identical Ansible run reports no changes. ## Constraints and Settled Decisions -- Feature 0015 is a prerequisite and must settle, implement, and review the - storage and publishing interface before Feature 0016 becomes ready for an - implementation sprint. +- Feature 0015's implementation and independent review satisfy the storage + and publishing prerequisite. Its workspace completion record should be + closed out before the Feature 0016 sprint. - The target is the inventory alias `pipeline-dnd` as currently defined in `rakestraw-ansible`, not a new `pipeline.dnd` alias. - The playbook follows the repository's established style: hosts and roles @@ -161,33 +172,63 @@ immediate identical Ansible run reports no changes. - API credentials use the existing typed `dnd_pipeline_secrets` interface and Ansible Vault. Plaintext secret values must not enter Git, command lines, logs, examples, or ordinary variable files. -- The public Gitea repositories are the sole dependency sources. The - deployment must not reference this workspace's sibling checkout paths. -- The dependency manifest must select an immutable release when Feature 0015 - produces one. Otherwise, it must pin the exact reviewed public Git commit; - it must not track an unbounded branch for the production deployment. +- Public Gitea repositories supply the suite's Git dependencies; native + collections come from Ansible Galaxy. The deployment must not reference + this workspace's sibling checkout paths. +- The collection is pinned to the reviewed public commit identified above. + Feature 0015 did not create a release; this deployment does not track an + unbounded branch or require a new coordinated release. - The collection artifact does not itself install arbitrary Git-hosted role dependencies. The operational manifest must therefore include the five standalone roles as well as the collection and its native collection dependencies. -- The legacy host variables must be compared with the final Feature 0015 - interface. Applicable values move to the new suite configuration, while - obsolete or conflicting variables are removed rather than left to win by - inventory precedence. +- Remove the legacy `narratio_s3_*` host variables because their intended + values are supplied by the suite defaults. Replace + `narratio_default_campaign_id` with + `narratio_campaigns_default_campaign_id: dilfs`. The standalone role already + exposes this host-specific setting; no new pipeline variable is required. - The initial real-host run is an operational acceptance exercise. It should test observable pipeline behavior and convergence, not module task traces or the current text of defaults. +## Operational Prerequisites + +Before implementation, establish the concrete deployment context and record +the non-secret choices in the implementation plan or deployment runbook: + +- Identify the operational Ansible controller and its deployment checkout. + The repository configuration currently selects `/etc/ansible/inventory`, + `/etc/ansible/roles`, and `/etc/ansible/collections`. Confirm the effective + paths so dependency installation and playbook execution use the same + inventory and installed content. Distinguish those paths from this + development workspace. +- Confirm that `pipeline-dnd` runs the supported Ubuntu 26.04 environment and + that its existing `eric` account provides SSH access and the sudo access + required by the roles. +- Establish the controller's existing Vault password or identity mechanism + and operator availability to populate the four credential values in the + encrypted host file. Record how Vault is selected, never its password or + decrypted contents. +- Have the operator select the acceptance campaign, session identity, and + audio input, with the corresponding session file and accessible input + location. This is a real processing and publication exercise using the + selected providers; session selection remains an operator decision. + +These are deployment inputs and operational checks, not additional production +tasks or a new automated preflight framework. + ## Simplest Viable Implementation -After Feature 0015 is reviewed, select its exact public collection revision -and use the associated compatibility manifest to update the controller's -single root requirements file. Add the minimal playbook and one ordinary -host-variable file for public inputs. Add one fully encrypted host Vault file -for the two credential values, populated by the operator without exposing its -plaintext during implementation or review. +Use the reviewed collection revision and associated compatibility manifest to +update the controller's single root requirements file. Add the minimal playbook and one ordinary +host-variable file for the endpoint, operator, campaign, and credential +references, inheriting the suite's storage and publication defaults. Add one +fully encrypted host Vault file for the four credential values, populated by +the operator without exposing its plaintext during implementation or review. -Install or update dependencies from the root manifest, confirm that Ansible +Install or update dependencies from the root manifest at the confirmed +controller paths, explicitly refreshing the collection from its pinned commit +even when `0.1.0` is already installed. Confirm that Ansible resolves `rakestraw.dnd.pipeline`, syntax-check the playbook, and converge only `pipeline-dnd`. Start a fresh operator login after enrollment, validate the native Narratio configuration under the intended runtime identity, rerun the @@ -213,11 +254,10 @@ would make a later controller bootstrap select an unreviewed compatibility set. An exact public commit retains development flexibility until the next release while still making this deployment reproducible. -Running the real-host deployment before Feature 0015 would establish only an -installation demonstration: the pipeline still could not complete its -required storage and publishing path. Making Feature 0015 an explicit -prerequisite avoids temporary inventory variables and gives the acceptance -run a meaningful end-to-end boundary. +Feature 0015 now supplies the reviewed storage and publishing path needed for +meaningful end-to-end acceptance. Inheriting that policy keeps host inventory +focused on deployment choices and avoids maintaining a second copy of the +suite defaults. ## Acceptance Criteria @@ -227,7 +267,8 @@ run a meaningful end-to-end boundary. `rakestraw.dnd.pipeline`, and contains no deployment variables or procedural setup. - Host inventory sets the confirmed WhisperX endpoint, enrolls only `eric`, - and supplies the final Feature 0015 storage and publishing inputs. + preserves `dilfs` as the default campaign through the existing standalone + role variable, and inherits Feature 0015's storage and publishing defaults. - `dnd_pipeline_secrets` maps the required typed runtime keys to host Vault variables, and the actual values exist only in a valid Ansible Vault-encrypted file. @@ -240,6 +281,9 @@ run a meaningful end-to-end boundary. and installs the exact reviewed public collection snapshot, its five standalone role dependencies, and its required native collections without using local repository paths. +- The controller uses the selected collection commit even if collection + version `0.1.0` was already installed. The documented inventory, role, and + collection paths correspond to the operational controller. - On a controller bootstrapped from that manifest, `ansible-doc` resolves `rakestraw.dnd.pipeline` and each role dependency, and the new playbook passes syntax checking. @@ -263,9 +307,10 @@ run a meaningful end-to-end boundary. ## Dependencies and Follow-up Work -[Feature 0015](0015-dnd-s3-storage-and-publishing.md) is the immediate next unit -of work and a hard prerequisite. It selects the pipeline interface, -credentials, and observable publishing boundary that Feature 0016 will deploy. +[Feature 0015](0015-dnd-s3-storage-and-publishing.md) supplies the implemented +and independently reviewed pipeline interface, credentials, and publishing +boundary consumed here. Its administrative closeout remains before the +Feature 0016 sprint; its runtime implementation needs no further remediation. Features 0013 and 0014 provide the public collection installation path and existing-operator enrollment required here. Features 0009 and 0011 provide diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index defa380..8b0327c 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,575 +1,364 @@ -# Implementation Plan 0015: Enable D&D S3 Storage and Publishing +# Implementation Plan 0016: Deploy the D&D Pipeline to `pipeline-dnd` -Status: in_progress +Status: ready Target executor: GPT-5.6-Terra -Feature roadmap: -`docs/roadmap/features/0015-dnd-s3-storage-and-publishing.md` +Feature roadmap: `docs/roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md` Active plan location: `docs/roadmap/implementation.md` ## Objective -Configure the authoritative D&D pipeline role to use the selected Backblaze -S3-compatible archive, typed object-storage credential references, maximum S3 -audio caching, immutable run publication, selected transcript and D&D artifact -outputs, and cleanup of successfully published workspace state. Advance the -pipeline to Narratio v2.1.1 so explicit publish requiredness composes with -native destination derivation. Validate the configuration through Narratio's -native interface, import the exact reviewed pipeline commit into the collection -from public Gitea, and leave the result ready for the real-host deployment in -Feature 0016. - -The Feature 0015 roadmap remains authoritative for scope, rationale, target -state, and acceptance criteria. This plan does not authorize a second storage -implementation, real object-storage calls from repository tests, per-session -configuration management, stable publication of every Notarius extraction -lane, or changes to the generic Narratio role. +Deploy the reviewed collection through a minimal consumer playbook, host +inventory, and Ansible Vault. Demonstrate clean repeated convergence and one +operator-selected session through real publication. The feature roadmap owns +scope, rationale, target state, and acceptance criteria. ## Execution Rules -- Execute stages in numeric order. -- Before each stage, confirm its preconditions and the working-tree state of - its owning repository. -- Before each stage, reread every document listed in that stage's Required - Policy Review. Do not rely on policy recalled from an earlier stage. -- Preserve unrelated and pre-existing changes. Stop and report unexpected - worktree changes or branch divergence rather than overwriting them. -- Do not make unresolved product or architecture decisions during execution; - stop and report the decision required. -- Implement storage and publication entirely through the standalone Narratio - role's existing field-specific variables. Do not add a production task, - template, handler, fact, probe, command, wrapper, state file, or validation - layer to the pipeline role. -- Keep `dnd_pipeline_secrets` as the existing generic empty-by-default map. - Add no real, generated, placeholder, or fallback credential value to role - defaults, templates, documentation, tests, logs, or ordinary inventory. -- Keep the S3 access-key and secret-key reference variables nullable as a - pair. Do not add an Ansible assertion for pairing or secret presence; - Narratio owns native configuration validation and AWS provider selection. -- Do not configure `narratio_spool_delete_audio_after_publish` or - `narratio_notarius_chunk_cache`. Preserve the roadmap's single-owner - decisions for spool retention and Notarius cache policy. -- Treat accepted Notarius outputs and published outputs as separate - interfaces. Preserve `narratio.extraction.` sources for future - analyze inputs without adding publication rules or new artifacts for them. -- Exercise explicitly supplied representative values in the detailed pipeline - integration scenario. Do not assert that those values are current defaults - or duplicate Narratio's own storage and publication test matrix. -- Do not make a real S3 request or paid model request during repository-local - validation. -- Run every stage's validation before completing the stage. Do not proceed - after a validation failure. -- Commit each completed stage with the stated plain-English intent. Push the - authoritative pipeline commit before importing it into the collection. -- Use only the public Gitea pipeline URL for the subtree update. Do not import - from the local sibling repository. +- Execute stages in order. Before each stage, reread its Required Policy + Review and check the owning repository's working tree. Preserve unrelated + changes. Validate and commit each completed stage with its stated intent. +- Keep the playbook limited to hosts and roles. Use existing interfaces; + add no wrapper, preflight framework, custom module, or test harness. +- Inherit suite storage, publication, caching, cleanup, version, and asset + defaults. Set only the roadmap-selected host choices. +- Never print decrypted inventory, credential values, or Vault passwords in + commands, logs, documentation, or Git. Do not use decrypted inventory dumps + as validation evidence. The operator supplies secrets directly through + Ansible Vault's encrypted-file workflow, using an established secure editor. + Do not solicit secrets in chat or create placeholder credentials. +- Stop dependent work when operational inputs are missing or validation fails. + Record the concrete blocker; local checks do not prove a live deployment. +- Retain the historical playbook and proof-of-concept role. Role, collection, + application, and asset repositories remain read-only during this feature. +- Deployment and paid provider execution occur only during the approved sprint + with the selected controller, target, credentials, and session. Do not + substitute an arbitrary session or broaden the host limit. ## Starting State and Preconditions -- Features 0009, 0011, 0012, 0013, and 0014 are complete. -- The approved Feature 0015 roadmap and this implementation plan are committed - in the workspace repository before the sprint begins. -- `ansible-role-dnd-pipeline` remains based on - `c13f726a0a846180a1aa95d110b8bbc801edaae5`, equal to `origin/main`, with the - interrupted Stage 1 edits preserved and uncommitted in `README.md`, - `defaults/main.yml`, `meta/argument_specs.yml`, `meta/main.yml`, and - `tests/integration`. Review and complete those edits; do not discard them. -- `ansible-collection-dnd` starts clean on `main` at - `c0b0ebd13e92199f3d94e138c6cc50d1ece5dadd`, equal to `origin/main`. -- `ansible-role-narratio` is clean at - `292d8669e7aad5cfe80b0c469d22b6177e8cf0f1`, equal to `origin/main`, and its - `v0.1.0` role release contains the field-specific interface required by this - feature and can install Narratio v2.1.1 through `narratio_version`. -- The sibling Narratio application repository is clean at public release - `v2.1.1`, commit `442469b9f57e65ce17f09059609dd1a37cf8c3b6`. That - backward-compatible release corrects destination derivation with explicit - publish requiredness and is a read-only contract source during the resumed - sprint. -- The workspace `.venv` supplies the tested `ansible-playbook`, - `ansible-galaxy`, and `ansible-lint` commands used by the repository test - drivers. -- The local host remains the approved Ubuntu 26.04 proxy, and passwordless - test-time sudo is available for the existing integration fixtures. -- Git credentials can push the pipeline and collection commits to their public - Gitea origins. -- No actual Backblaze or model-provider credential is required or available to - the implementation. Tests use conspicuously synthetic values only. +- Feature 0015 passed independent review without findings. Its pipeline commit + is `51566afcf69083cdbb5b5718f2544c86b079001c`; the reviewed public collection + commit is `46913446765e86ecfb29ebad9955d579ef6a4c7e`. +- `rakestraw-ansible` starts clean on `main` at + `d86ec29a9cbd821fead248736171b5cdd8440ad6`. Inspect and preserve any subsequent + changes before adapting this plan. +- Root `requirements.yml` already has an unpinned Gitea `rakestraw.dnd` entry + alongside unrelated collections. The historical playbook is + `playbooks/apps/dnd.yml`; it invokes `pipeline_dnd` on `automation-dnd`. +- Host `pipeline-dnd` already connects as `eric` to + `pipeline-dnd.rakestrawhome.com`. Preserve its connection settings. +- `inventory/host_vars/pipeline-dnd/narratio.yml` contains the legacy campaign + and S3 variables to migrate. +- The selected collection still declares version `0.1.0`. An installed + release with that number is not sufficient evidence of the selected content. +- Approve and commit the planning documents before execution. Resolve the + operational inputs under Open Questions before the sprint, as required by + the roadmap; do not invent controller topology, credentials, or session data. ## Repository Scope -- `ansible-role-dnd-pipeline` owns the suite defaults, argument specification, - Narratio dependency mappings, consumer documentation, and detailed - representative integration behavior. -- `ansible-collection-dnd` owns the artifact-level fixture update, faithful - squashed subtree import, assembled-artifact validation, and resulting public - collection snapshot. -- `ansible-workspace-dnd` records the implementation handoff after the two - implementation repositories are complete. -- `ansible-role-narratio`, all standalone roles, application sources, - asset repositories, and `rakestraw-ansible` may be inspected but must remain - unchanged. +- `rakestraw-ansible`: requirements, playbook, host configuration, encrypted + credentials, and `docs/pipeline-dnd.md` runbook linked from README. +- Workspace: feature status, implementation progress, and review handoff. +- Other repositories: read-only compatibility and application references. -## Stage 1: Implement D&D Storage and Publication Policy +## Stage 1: Establish the Operational Context -Completion: complete (`51566afcf69083cdbb5b5718f2544c86b079001c`) +### Objective and Owning Repository -### Objective - -Expose the approved suite-level S3 and publishing inputs through the -authoritative pipeline role, map them directly into Narratio, document the -operator contract, and prove representative composition without networked -storage access. +Record deployment prerequisites in `rakestraw-ansible` and close the reviewed +Feature 0015 in the workspace. ### Required Policy Review -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/ansible.md` -- `docs/testing.md` -- `docs/planning.md` -- `docs/roadmap/features/0015-dnd-s3-storage-and-publishing.md` -- `ansible-role-dnd-pipeline/README.md` -- `../narratio/AGENTS.md` -- `../narratio/docs/development.md` -- `../narratio/docs/config.md` -- `../narratio/docs/operations.md` +Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, +`docs/ansible.md`, `docs/testing.md`, `docs/planning.md`, the Feature 0016 +roadmap, and `rakestraw-ansible/README.md` before this stage. ### Preconditions -- The workspace planning commit containing the original approved plan and this - resumed-plan revision are present. -- `ansible-role-dnd-pipeline` is based on the starting revision, is not behind - or diverged from `origin/main`, and its only working-tree changes are the - preserved interrupted Stage 1 edits identified in Starting State and - Preconditions. -- The current `rakestraw.narratio` dependency mapping and existing integration - driver still match the structures reviewed while preparing this plan. -- Narratio v2.1.1 remains publicly available and accepts the roadmap-selected - storage, publish, cleanup, cache, and typed credential-reference fields, - including rules with explicit `required` and omitted derivable `dest`. - -### Owning Repository - -`ansible-role-dnd-pipeline` +The plan is approved, repositories have been checked, and the operator has +supplied the missing operational inputs below. ### Required Changes -1. Advance the existing application default to - `dnd_pipeline_narratio_version: v2.1.1`. Do not change the standalone - Narratio role release pin: its existing public interface can install this - compatible application patch release. -2. Add the following exact suite defaults to `defaults/main.yml` near the - existing Narratio policy variables: +1. Create `rakestraw-ansible/docs/pipeline-dnd.md` and link it from README. + Record the actual controller, checkout, effective Ansible configuration, + inventory, role/collection paths, Vault selection method, and acceptance + campaign/session/audio location. Record only non-secret information. +2. Confirm controller Ansible Core is at least 2.18 and the public suite + repositories and Galaxy are reachable. Inspect effective configuration + without dumping decrypted host variables. Existing repository defaults are + `/etc/ansible/inventory`, `/etc/ansible/roles`, and `/etc/ansible/collections`; + establish how the operational checkout supplies those paths. +3. Use ordinary read-only host checks to confirm Ubuntu 26.04 and the existing + `eric` account's SSH and required sudo access. Record the outcome. Report + discrepancies before deployment rather than changing platform/account policy. +4. Mark Feature 0015 `done` in its roadmap and workspace status, citing its + reviewed commits and the successful independent standalone/collection + integration runs. Leave historical remediation records unchanged. Mark + Feature 0016 `in_progress` when execution begins. - ```yaml - dnd_pipeline_narratio_workspace_cleanup_after_publish: true - dnd_pipeline_narratio_storage_backend: s3 - dnd_pipeline_narratio_storage_s3_bucket: rakestraw-assets - dnd_pipeline_narratio_storage_s3_root_prefix: dnd - dnd_pipeline_narratio_storage_s3_region: us-east-1 - dnd_pipeline_narratio_storage_s3_endpoint: https://s3.us-east-005.backblazeb2.com - dnd_pipeline_narratio_storage_s3_force_path_style: true - dnd_pipeline_narratio_storage_s3_access_key_id: OBJECT_STORAGE_KEY_ID - dnd_pipeline_narratio_storage_s3_secret_access_key: OBJECT_STORAGE_KEY - dnd_pipeline_narratio_cache_s3_audio: true - dnd_pipeline_narratio_publish_enabled: true - dnd_pipeline_narratio_publish_upload_run: true - dnd_pipeline_narratio_publish_outputs: - - source: narratio.transcript.final - required: true - - source: narratio.transcript.final_trimmed - required: true - - source: narratio.transcript.final_markdown - required: true - - source: narratio.transcript.final_trimmed_markdown - required: true - - source: narratio.artifact.session_recap - required: true - - source: narratio.artifact.hostile_rumors - required: true - - source: narratio.artifact.deranged_rumors - required: false - ``` +### Validation and Completion Criteria - Keep every `dest` omitted. Narratio derives transcript destinations from - built-in sources and artifact destinations from the already managed - artifact output paths. -3. Add matching public entries to `meta/argument_specs.yml`. Use `type: bool` - for the cleanup, path-style, cache, enabled, and upload settings; `type: str` - for the backend and S3 string fields; and `type: list` for the complete - publish output list. The S3 child fields, including both credential - references, must be non-required so callers may set every S3 child to - `null` when deliberately selecting the local backend or set the credential - pair to `null` when selecting the AWS SDK provider chain. The remaining - concrete suite-policy fields follow the role's existing required/defaulted - argument-spec convention. -4. In the `rakestraw.narratio` dependency entry in `meta/main.yml`, map every - new suite variable directly to its same-purpose standalone variable: - `narratio_workspace_cleanup_after_publish`, the eight - `narratio_storage_*` fields, `narratio_cache_s3_audio`, - `narratio_publish_enabled`, `narratio_publish_upload_run`, and - `narratio_publish_outputs`. -5. Do not map `narratio_spool_delete_audio_after_publish`. Do not map - `narratio_notarius_chunk_cache`. Do not add a new import, fragment, - template, task, handler, assertion, or configuration-validation command. -6. Revise the README's application-version reference, upstream links, variable - reference, and processing-policy sections for Narratio v2.1.1 and - document the selected S3 destination, paired nullable credential - references, complete-list publish semantics, native destination derivation, - maximum S3 audio caching, successful-publication workspace cleanup, and - deliberate omission of spool deletion. -7. Extend the README's managed-credential example to show - `OBJECT_STORAGE_KEY_ID` and `OBJECT_STORAGE_KEY` mapped from encrypted - inventory beside the existing Audita and OpenRouter entries. Explain that - values remain outside ordinary configuration and that setting both S3 - credential references to `null` selects Narratio's ambient AWS SDK provider - chain. -8. Replace the README's statement that storage and publishing are deferred - with concise operator-facing descriptions and public upstream links for S3 - session audio, publish, restore, publication locks, status, and cleanup. - Explain that accepted Notarius lanes remain - `narratio.extraction.` analyze inputs independently of whether - they have stable publish rules. -9. Adapt the existing `tests/integration` baseline rather than adding a new - scenario. Add two synthetic object-storage values to - `dnd_pipeline_secrets`; explicitly unset `OBJECT_STORAGE_KEY_ID` and - `OBJECT_STORAGE_KEY` alongside the existing provider variables when - invoking Ansible; and explicitly pass representative non-default S3, - cleanup, cache, and publish values through the new public variables. -10. Use representative values that exercise the interface without freezing the - defaults: for example an `.invalid` HTTPS endpoint and fixture bucket, - prefix, and region; intentional `false` values for cleanup, path style, and - S3 audio caching; the two configured credential reference names; enabled - run publication; and a short complete publish list containing one built-in - transcript source and `narratio.artifact.session_recap` with omitted - destinations. -11. Extend the existing secret-safe effective-configuration inspection only - enough to demonstrate the explicitly supplied representative storage - fields, typed credential names, falsey cache/cleanup choices, enabled - publication, and Narratio-derived destinations. Continue to use - `narratio config validate` as the native validity boundary. Do not inspect - role task results, call S3, or reproduce Narratio's validation rules. -12. Extend the current non-disclosure check to cover both synthetic - object-storage values. Preserve the complete existing integration matrix, - cleanup behavior, and immediate clean-repeat assertions. -13. Run the complete repository validation. Commit the valid result with the - stated plain-English message, push `main` to public Gitea, and record the - full pushed commit hash for Stage 3. - -### Validation - -Run from the workspace root: - -```text -(cd ansible-role-dnd-pipeline && tests/integration && git diff --check) -``` - -Expected result: syntax checking and production-profile lint pass; all five -applications remain valid; the explicitly supplied S3 and publish values -resolve through Narratio v2.1.1's native configuration interface; explicit -publish requiredness and omitted destinations produce the derived destinations; -only reference names appear in effective output; no synthetic credential value -appears in captured output; no external S3 or model request occurs; and the -immediate identical repeat reports `changed=0` and `failed=0`. - -### Completion Criteria - -- The pipeline selects Narratio v2.1.1, and defaults, argument specifications, - dependency mappings, and documentation implement exactly the Feature 0015 - contract. -- No production task, template, fragment, validation command, or second secret - path was added. -- The representative integration scenario exercises public inputs rather than - snapshotting defaults and retains the existing clean-repeat boundary. -- The full standalone integration suite and `git diff --check` pass. -- The pipeline repository is clean after the plain-English commit. -- The exact commit is present on public `origin/main` and its full hash is - available for the collection import. +Operational inputs are concrete and target platform/access checks pass. +Run `git diff --check` in both changed repositories. No deployment or provider +request is necessary for this stage. ### Commit -Commit intent: `Enable D&D storage and publishing` +Consumer: `Document the D&D deployment context`. +Workspace: `Close storage review and begin host deployment`. -## Stage 2: Prepare the Collection Credential Fixture +## Stage 2: Prepare the Consumer Playbook and Inventory -Completion: complete (`cf3de016ee09edf91afc3bc1addfd926d4a172ad`) +### Objective and Owning Repository -### Objective - -Make the collection's artifact-level fixture compatible with the forthcoming -pipeline snapshot while its currently bundled role remains valid. +Make `rakestraw-ansible` a complete consumer of the reviewed suite snapshot. ### Required Policy Review -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/ansible.md` -- `docs/testing.md` -- `docs/planning.md` -- `docs/roadmap/features/0015-dnd-s3-storage-and-publishing.md` -- `ansible-collection-dnd/README.md` +Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, +`docs/ansible.md`, `docs/testing.md`, `docs/planning.md`, the Feature 0016 +roadmap, `ansible-collection-dnd/README.md`, its `requirements.yml`, and the +Stage 1 runbook before this stage. ### Preconditions -- Stage 1 is complete, validated, committed, and pushed. -- `ansible-collection-dnd` is clean at the starting revision, is not behind or - diverged from `origin/main`, and contains no unrelated changes. -- Its top-level `tests/integration` fixture still supplies the two existing - synthetic provider credentials through `dnd_pipeline_secrets`. - -### Owning Repository - -`ansible-collection-dnd` +Stage 1 is complete. The operator can populate and unlock the encrypted host +file using the recorded Vault mechanism. ### Required Changes -1. Update only the collection-level `tests/integration` fixture outside - `roles/pipeline`. Add conspicuously synthetic values for - `OBJECT_STORAGE_KEY_ID` and `OBJECT_STORAGE_KEY` to its existing - `dnd_pipeline_secrets` input. -2. Explicitly unset those two environment variables beside the existing - Audita and OpenRouter variables when the fixture runs Ansible so ambient - controller state cannot replace the managed synthetic files. -3. Do not add storage assertions or duplicate the standalone pipeline's - detailed representative test. The collection fixture owns only enough - input to validate the assembled artifact after Stage 3. -4. Do not edit anything under `roles/pipeline`, alter dependency manifests, - or change collection release metadata. -5. Check the fixture's shell syntax and whitespace, then commit the compatible - preparation with the stated message. Do not push separately unless needed; - Stage 3 will push both collection commits after full artifact validation. +1. Add `playbooks/pipeline/dnd.yml` in the roadmap's exact minimal shape: + one play targeting `pipeline-dnd` with only `rakestraw.dnd.pipeline` in its + roles list. No play variables, tasks, or play-level privilege escalation. +2. Replace the legacy contents of + `inventory/host_vars/pipeline-dnd/narratio.yml` with the roadmap's public + inventory example: operator `eric`, the confirmed WhisperX URL, + `narratio_campaigns_default_campaign_id: dilfs`, and the four Vault-backed + `dnd_pipeline_secrets` mappings. Remove obsolete `narratio_s3_*` and + `narratio_default_campaign_id` settings. Preserve unrelated intervening edits + and the separate connection file. Do not copy suite defaults into inventory. +3. Have the operator create `inventory/host_vars/pipeline-dnd/vault.yml`, fully + Ansible Vault-encrypted, defining the four exact `vault_dnd_*` names from + the roadmap. Commit ciphertext only. +4. Pin the existing `rakestraw.dnd` Git entry in root `requirements.yml` to + `46913446765e86ecfb29ebad9955d579ef6a4c7e` with its existing public URL. +5. Copy the five `roles` entries from that collection's compatibility manifest, + retaining role names, public Gitea URLs, `scm: git`, and `v0.1.0` tags. + Reconcile native collection entries to `ansible.posix: 2.2.0` and + `community.general: 13.3.0`, without duplicates. Preserve unrelated + dependencies; report demonstrated conflicts rather than silently changing + the reviewed suite pins. +6. Extend the runbook with the concrete commands for dependency installation, + collection refresh, Vault selection, deployment, fresh login, and native + validation used below. Link upstream Narratio v2.1.1 operator documentation. ### Validation -Run from the workspace root: +Parse edited plaintext YAML and run `git diff --check`. In isolated controller +dependency paths, install from public sources with +`ansible-galaxy install -r requirements.yml`. Configure role and collection +destinations through Ansible configuration/environment; avoid a role-only +custom path that would skip the collection section of the mixed manifest. +Confirm resolution with `ansible-doc -t role rakestraw.dnd.pipeline` and the +five `rakestraw.` role names. + +From the consumer checkout, using the established Vault options, run: ```text -(cd ansible-collection-dnd && bash -n tests/integration && git diff --check) +ansible-playbook -i inventory playbooks/pipeline/dnd.yml --limit pipeline-dnd --list-hosts +ansible-playbook -i inventory playbooks/pipeline/dnd.yml --limit pipeline-dnd --syntax-check ``` -Expected result: the collection integration driver remains valid shell; the -diff changes only its generic managed-secret input and environment scrub; and -no subtree, dependency, or release file changed. Full semantic validation -occurs once against the imported snapshot in Stage 3. +Use the concrete inventory path from Stage 1 if different. Do not impose +whole-repository lint changes on the established minimal-playbook style. ### Completion Criteria -- The artifact-level fixture provides all four synthetic operational - credential names without exposing real values. -- No detailed storage behavior was duplicated in the collection. -- Only the collection-owned fixture changed. -- Shell syntax and `git diff --check` pass. -- The collection repository is clean after the plain-English commit. +Only the intended host is selected. Public dependencies resolve without local +sibling checkouts, syntax checking succeeds with encrypted inventory, and the +diff contains no plaintext secrets. ### Commit -Commit intent: `Prepare collection storage credentials` +`Add the D&D pipeline deployment playbook`. -## Stage 3: Import and Validate the Reviewed Pipeline Snapshot +## Stage 3: Deploy and Verify Clean Convergence -Completion: complete (merge `46913446765e86ecfb29ebad9955d579ef6a4c7e`; -squash `77f67adbc0f700e88bc15554e02052eaa22f1033`) +### Objective and Owning Repository -### Objective - -Expose the reviewed Feature 0015 behavior through `rakestraw.dnd.pipeline` -while preserving the public-remote subtree and collection-artifact boundaries. +Deploy from the operational controller; record results in the consumer runbook. ### Required Policy Review -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/ansible.md` -- `docs/testing.md` -- `docs/planning.md` -- `docs/roadmap/features/0015-dnd-s3-storage-and-publishing.md` -- `ansible-collection-dnd/README.md` +Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, +`docs/ansible.md`, `docs/testing.md`, `docs/planning.md`, the Feature 0016 +roadmap, and `rakestraw-ansible/docs/pipeline-dnd.md` before this stage. ### Preconditions -- Stage 1's exact pipeline commit is publicly reachable from - `https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git`. -- Stage 2 is complete and committed in `ansible-collection-dnd`. -- The collection is clean at the Stage 2 commit and its bundled pipeline - subtree still corresponds to the authoritative pipeline history through - `c13f726a0a846180a1aa95d110b8bbc801edaae5`. +Stage 2 passed. The operational checkout contains its committed changes and +Vault is usable. Deliver changes through the established checkout workflow; +do not overwrite a dirty operational checkout. -### Owning Repository +### Required Changes and Validation -`ansible-collection-dnd` - -### Required Changes - -1. Set a shell variable to the full pushed Stage 1 commit hash and run the - documented remote-only subtree update from the collection repository: +1. Install root requirements at the confirmed controller paths. Explicitly + refresh only the D&D collection from its selected commit, even when `0.1.0` + is already installed: ```text - pipeline_revision= - git subtree pull --prefix=roles/pipeline \ - https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git \ - "$pipeline_revision" --squash -m "Import D&D storage and publishing" + ansible-galaxy collection install git+https://gitea.maximumdirect.net/eric/ansible-collection-dnd.git,46913446765e86ecfb29ebad9955d579ef6a4c7e --force --no-deps ``` -2. Do not edit role behavior directly beneath `roles/pipeline`. The import - must faithfully carry the reviewed defaults, argument specification, - dependency mappings, README, and detailed integration fixture. -3. Do not modify `galaxy.yml`, `requirements.yml`, release documentation, or - the published `v0.1.0` artifacts. Feature 0015 changes no standalone role or - native collection dependency and publishes no new release; the pipeline's - application-version variable carries the Narratio v2.1.1 selection. -4. Run the complete collection integration suite against the built and - installed artifact. Do not add collection-level assertions for the detailed - S3 configuration; native validation and clean convergence remain the - collection boundary. -5. If validation succeeds, push the Stage 2 fixture commit, the subtree merge - commit, and its Git-generated squash commit to `origin/main`. Record the - resulting commit hashes for Stage 4. - -### Validation - -Run from the workspace root: - -```text -(cd ansible-collection-dnd && tests/integration && git diff --check) -``` - -Expected result: the collection builds; its archive contains the updated -pipeline role while retaining development-file exclusions; isolated -dependency and artifact installation succeeds; the FQCN resolves; Narratio -loads its typed storage references from the synthetic credential files without -contacting S3; native representative application checks pass; and the -immediate repeat reports `changed=0` and `failed=0`. + Use the configured collection path; dependencies come from the manifest. + Do not force-update unrelated unpinned collections. Confirm role resolution + and playbook syntax on this operational controller as in Stage 2. +2. Run `ansible-playbook playbooks/pipeline/dnd.yml --limit pipeline-dnd` + using the recorded inventory, Vault, and any required sudo-password options. + Immediately repeat the identical command after success. Require + `changed=0`, `failed=0`, and no unreachable hosts on the repeat. +3. On the target, execute + `sudo -u narratio /usr/local/bin/narratio config validate`, then validate + with `--profile testing`. The managed default campaign should make an + explicit campaign selector unnecessary. +4. Start a fresh login as `eric` and execute the same default native validation + without switching user, demonstrating usable supplementary group access. +5. Record consumer commit, target, date, repeat recap, and native validation + results. Diagnose failures at the owning boundary; report required changes + to roles/applications separately rather than expanding this feature. ### Completion Criteria -- Git history records the exact public Stage 1 revision through the documented - squashed subtree workflow and stated merge message. -- No pipeline behavior was authored directly in the collection. -- The complete collection suite and `git diff --check` pass. -- The collection repository is clean and its Stage 2 and Stage 3 history is - present on public `origin/main`. +The actual host converges cleanly and both runtime identities validate the +configuration. Run `git diff --check` on the evidence/runbook changes. ### Commit -Commit intent: `Import D&D storage and publishing` +`Record successful D&D host deployment`. -The subtree command creates this stage's merge commit and its generated squash -commit; do not add an empty or redundant manual commit. +## Stage 4: Exercise One Real Session -## Stage 4: Record the Implementation Handoff +### Objective and Owning Repository -Completion: complete (`76c10f79f5f2ccdd3e906490b3e70620d78bd8dc`) - -### Objective - -Record the completed implementation evidence without marking Feature 0015 -done before independent review. +Demonstrate production processing and publication; record acceptance in +`rakestraw-ansible/docs/pipeline-dnd.md`. ### Required Policy Review -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/planning.md` -- `docs/roadmap/features/0015-dnd-s3-storage-and-publishing.md` +Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, +`docs/testing.md`, `docs/planning.md`, the Feature 0016 roadmap, the runbook, +and Narratio v2.1.1's `docs/config.md`, `docs/cli.md`, and +`docs/operations.md` before this stage. Follow the sibling application's +`AGENTS.md` and development reading guide when consulting its repository. ### Preconditions -- Stages 1 through 3 are complete, committed, pushed where required, and - validated. -- Their full commit hashes and validation results are available. -- The workspace repository is clean at the planning commit, is not behind or - diverged from `origin/main`, and contains no unrelated changes. +Stage 3 passed. Actual credentials, the operator-selected campaign/session, +session file, and audio are accessible. The exercise must demonstrate real +transcription and publication, not merely resume an already complete run. +Do not erase existing state to create a fixture. -### Owning Repository +### Required Changes and Validation -`ansible-workspace-dnd` +1. As `eric` in a fresh authorized login, run: -### Required Changes + ```text + narratio session validate SESSION_ID --campaign CAMPAIGN --session SESSION_FILE + narratio run SESSION_ID --campaign CAMPAIGN --session SESSION_FILE + narratio session artifacts SESSION_ID --remote --campaign CAMPAIGN --session SESSION_FILE + ``` -1. Change Feature 0015's roadmap status and status-table state to - `in_progress`, indicating implementation is complete but independent review - remains outstanding. -2. Update the workspace current focus and Feature 0015 evidence with the exact - pipeline commit, collection fixture commit, collection subtree merge and - squash commits, and validation completed. -3. Replace this plan's Progress Notes with a concise record of the four stage - states and their commits. Do not copy command logs into the repository. -4. Do not mark the feature `done`, remove this active plan, change Feature - 0016's state, or create `docs/roadmap/remediation.md`; those are later review - and closeout decisions. -5. Commit the workspace handoff record with the stated plain-English message. - -### Validation - -Run from the workspace root: - -```text -./scripts/status -git diff --check -``` - -Expected result: every repository is clean; the pipeline and collection are -not ahead of or behind their origins; only the workspace handoff commit may be -ahead of `origin/main`; and the dashboard points to exact implementation -evidence while retaining independent review as the next step. + Substitute the operator-recorded values and use the production profile. + The session document remains operational input; no session-management task + belongs in the playbook. Observe transcription, processing, and successful + publication. Do not force reprocessing or reduce the selected artifact set + merely to bypass a failure. +2. Observe a representative published transcript or recap at the configured + destination through the existing storage/operator interface. Successful + cleanup may remove local workspace content; local survival is not required. +3. Record identity, input location, runtime user, completion outcome, and + non-secret publication evidence. Avoid committing raw provider logs or + credential-bearing URLs. Do not repeat paid work just to duplicate evidence + or expand acceptance into a restore/locking test matrix. ### Completion Criteria -- Workspace status accurately identifies Feature 0015 as implemented and - awaiting independent review. -- The roadmap remains the durable target-state record and contains no command - log or transient execution notes. -- The active plan records concise implementation evidence and contains no - false completion claim. -- The workspace repository is clean after the handoff commit. +A real session completes and its published output is observable. Record any +provider/application blocker and leave acceptance incomplete if it cannot +finish. Run `git diff --check` on the runbook changes. ### Commit -Commit intent: `Record D&D storage and publishing implementation` +`Record the first published D&D session`. + +## Stage 5: Prepare the Independent Review Handoff + +### Objective and Owning Repository + +Record completed implementation evidence in the workspace. + +### Required Policy Review + +Read `AGENTS.md`, `docs/orientation.md`, `docs/conventions.md`, +`docs/testing.md`, `docs/planning.md`, and the Feature 0016 roadmap before +this stage. + +### Preconditions + +Stages 1–4 completed with committed changes and actual deployment/session +evidence. A blocked live exercise does not satisfy this stage. + +### Required Changes and Validation + +Update `docs/status.md` and this plan's progress notes with owning commits, +runbook link, validation outcomes, and deviations. Keep Feature 0016 +`in_progress` pending independent review. Report any additional complexity +and its authorizing requirement. Run `git diff --check` and confirm changed +repositories are clean after committing. Do not rerun role integration +matrices or paid sessions without a new change or failure requiring it. + +### Completion Criteria + +Evidence is recorded and implementation is ready for independent review. + +### Commit + +`Record the D&D deployment implementation`. ## Final Validation and Handoff -- Confirm Stage 1's complete standalone pipeline integration result and Stage - 3's complete collection integration result. -- Run `./scripts/status` and confirm every repository is clean, with no - unexpected branch divergence or untracked artifact. -- Report the full pipeline commit, collection fixture commit, collection - subtree merge and squash commits, and workspace handoff commit. -- Confirm that `ansible-role-narratio`, all standalone roles, applications, - assets, and `rakestraw-ansible` remained unchanged during the resumed sprint; - Narratio v2.1.1 was an already released prerequisite. -- Summarize any deviation from this plan, unresolved finding, or complexity - added beyond direct variable mapping and identify the acceptance criterion - that required it. -- Do not mark Feature 0015 `done`; implementation results require independent - review first. +Report dependency revision, consumer commits, controller/target, public +dependency and syntax results, immediate clean convergence, native validation +for both identities, and session publication evidence. Distinguish completed +work from operator-dependent blockers. Do not mark Feature 0016 `done` before +independent review. ## Progress Notes -- Stage 1 is complete in pipeline commit - `51566afcf69083cdbb5b5718f2544c86b079001c`; the complete standalone suite - passed and the commit is present on public `origin/main`. -- Stage 2 is complete in collection fixture commit - `cf3de016ee09edf91afc3bc1addfd926d4a172ad`; shell syntax and whitespace - validation passed. -- Stage 3 is complete in collection merge - `46913446765e86ecfb29ebad9955d579ef6a4c7e` with generated squash - `77f67adbc0f700e88bc15554e02052eaa22f1033`; the complete assembled-artifact - suite passed and the history is present on public `origin/main`. -- Stage 4 is complete in workspace handoff commit - `76c10f79f5f2ccdd3e906490b3e70620d78bd8dc`; implementation is awaiting - independent review. +Plan approved; no Feature 0016 implementation or deployment has begun. +Architecture is settled; the operational inputs below remain to be supplied. + +## Open Questions + +1. Which controller/checkout executes deployment and how do committed changes + reach it? Recommended: use the existing operational controller and its + established `/etc/ansible/` layout, keeping one operational inventory. + Alternative: a dedicated checkout with explicit inventory and dependency + paths, if the operator prefers isolation and records those paths consistently. +2. Which Vault identity/password mechanism is available, and can the operator + populate all four values? Recommended: reuse the controller's established + Vault workflow and populate the encrypted file directly. Alternative: an + interactive Vault password prompt for this file if no identity is established. + Both keep passwords outside Git; neither requires secrets in chat. +3. Which campaign/session/audio supplies acceptance? Recommended: an + operator-selected unprocessed `dilfs` session with accessible audio, matching + the retained default campaign and avoiding forced reprocessing. Alternative: + a selected session from another deployed campaign with an explicit selector. + Record the session file and audio location before execution; do not invent + sample production input. diff --git a/docs/status.md b/docs/status.md index 4165127..1e83396 100644 --- a/docs/status.md +++ b/docs/status.md @@ -4,7 +4,9 @@ Last updated: 2026-09-21 Current milestone: Operational D&D pipeline deployment -Current focus: Independently review the completed Feature 0015 implementation. +Current focus: Begin the approved Feature 0016 deployment plan after resolving +its controller, Vault, and acceptance-session inputs. Feature 0015 passed +independent review without findings; administrative closeout precedes the sprint. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -32,7 +34,7 @@ Current focus: Independently review the completed Feature 0015 implementation. | F0013 | Publish the first coordinated suite release | all Ansible repositories and workspace | done | Public [`rakestraw.dnd` 0.1.0 release](https://gitea.maximumdirect.net/eric/ansible-collection-dnd/releases/tag/v0.1.0); documentation remediation completed in pipeline `78afffe` and collection `5e695f3` | | F0014 | Enroll existing pipeline operators | ansible-role-dnd-pipeline, ansible-collection-dnd, and workspace | done | Pipeline `c13f726` and collection import `c0b0ebd` passed their complete integration suites and independent review with no remediation findings | | F0015 | Enable D&D S3 storage and publishing | ansible-role-dnd-pipeline, ansible-collection-dnd, and workspace | in_progress | Pipeline `51566afcf69083cdbb5b5718f2544c86b079001c`, collection fixture `cf3de016ee09edf91afc3bc1addfd926d4a172ad`, collection squash `77f67adbc0f700e88bc15554e02052eaa22f1033`, and collection merge `46913446765e86ecfb29ebad9955d579ef6a4c7e` passed the complete repository suites; independent review is next | -| F0016 | Deploy the D&D pipeline to `pipeline-dnd` | rakestraw-ansible and workspace | proposed | [Roadmap](roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md) drafted; Feature 0015 is a prerequisite | +| F0016 | Deploy the D&D pipeline to `pipeline-dnd` | rakestraw-ansible and workspace | ready | Approved [roadmap](roadmap/features/0016-deploy-dnd-pipeline-to-pipeline-dnd.md) and five-stage [implementation plan](roadmap/implementation.md); operational inputs listed under Open Questions remain prerequisites | | A0001 | Audit completed standalone-role test suites | workspace and standalone roles | done | Findings recorded in `docs/roadmap/test-suite-audit-findings.md` | | R0001 | Simplify completed standalone-role test suites | workspace and standalone roles | done | Role commits `e08c63c`, `d2d0b9d`, and `cfecf37` passed implementation and independent review |