diff --git a/docs/roadmap/features/0014-existing-pipeline-operator-enrollment.md b/docs/roadmap/features/0014-existing-pipeline-operator-enrollment.md new file mode 100644 index 0000000..ce0f7e8 --- /dev/null +++ b/docs/roadmap/features/0014-existing-pipeline-operator-enrollment.md @@ -0,0 +1,240 @@ +# Feature 0014: Enroll Existing Pipeline Operators + +Status: ready + +## Summary + +Let consumers name existing human accounts that the D&D pipeline role should +add to its shared runtime group. The interface is empty by default, manages +membership additively, and leaves account creation and removal outside the +role. + +## Problem or Opportunity + +The pipeline's shared filesystem and credential policy already supports +invocation by the dedicated `narratio` service account or by a human member of +the selected runtime group. The role does not yet select human operators or +manage their membership. Consumers must currently repeat a small +`ansible.builtin.user` task beside the role even though group enrollment is a +natural suite-level access choice. + +The role must not silently become a general account-management interface. +Human account identity, login policy, credentials, home directories, and +removal remain host or organization concerns. The pipeline needs only a +concise way to enroll explicitly selected existing accounts in the group that +already defines pipeline authorization. + +## Governing Policies + +- [The Ansible house style](../../ansible.md) requires the smallest direct + desired-state implementation and permits state inspection only when its + result is independently required. +- [The testing house style](../../testing.md) requires a representative + public-interface test of deployed behavior and immediate clean convergence, + without retesting `getent` or `user` module internals. +- [The MVP roadmap](../mvp.md) defines the runtime group as the shared + operator and credential-authorization boundary. +- [Feature 0009](0009-shared-pipeline-filesystem-and-execution.md) establishes + the service-user and human-group-member execution model. +- [Feature 0011](0011-managed-pipeline-credential-delivery.md) establishes + that runtime-group membership authorizes access to the suite's shared + credentials. +- [Feature 0012](0012-collection-assembly.md) makes the standalone pipeline + repository authoritative and requires reviewed changes to enter the + collection through its public Gitea subtree source. + +## Scope + +- Add `dnd_pipeline_operator_users`, a list of existing account names that + defaults to an empty list. +- Declare the variable as a list of strings in the pipeline role's argument + specification. +- Require every selected account to exist before changing any selected + account's group membership. +- Add each selected account to `dnd_pipeline_runtime_group` with additive + supplementary-group semantics. +- Preserve the existing account, its primary group, and all other + supplementary groups. +- Leave omitted accounts and memberships unmanaged. +- Document the existing-account contract, additive behavior, authorization + consequence, and need to begin a new login session before newly granted + supplementary membership is visible to a long-lived user session. +- Adapt the existing pipeline integration fixture to exercise enrollment + through the new public variable and retain its representative configuration, + secret-access, shared-cache, and clean-repeat behavior. +- Import the reviewed, pushed pipeline commit into the collection through the + established squashed subtree workflow and validate the assembled artifact. + +## Non-goals + +- Creating, deleting, locking, or otherwise managing human accounts. +- Managing UIDs, primary groups, passwords, SSH keys, shells, home + directories, sudo access, or login policy. +- Removing a user from the runtime group when the user is omitted from the + list or removed from a later inventory value. +- Managing external identity-provider or directory-service membership. +- Adding per-user access controls, separate credential sets, or a second + operator group. +- Changing the `narratio` service account, runtime group, filesystem modes, + ACL policy, credential policy, or application configuration. +- Adding handlers, sidecar state, membership snapshots, post-change + verification, or a custom account-management abstraction. +- Publishing a new pipeline-role or collection release as part of this + implementation. + +## Target End State + +The pipeline role exposes this optional interface: + +```yaml +dnd_pipeline_operator_users: + - eric + - alice +``` + +The default is `[]`, so existing consumers retain their current behavior. If +the list is nonempty, every named account must already exist on the managed +host. The role fails before its enrollment task when any selected account is +absent; it does not create a partially specified account as a side effect. + +Each existing selected account is an additive member of +`dnd_pipeline_runtime_group`. Existing primary and supplementary memberships +remain intact. Membership in that group grants the pipeline access already +defined by Features 0009 and 0011, including shared writable runtime roots and +group-readable suite credentials. Existing login sessions may need to be +restarted before the operating system exposes newly granted supplementary +membership. + +Removing a name from `dnd_pipeline_operator_users` does not revoke membership. +Account and access removal require an explicit lifecycle policy and remain +separate work. + +The collection's `rakestraw.dnd.pipeline` role contains the same reviewed +interface through a squashed import from the authoritative public pipeline +repository. The published `v0.1.0` release remains unchanged until a later +release feature selects and validates a new version. + +## Repository Ownership + +- `ansible-role-dnd-pipeline` owns the public variable, existing-account + prerequisite, additive enrollment, operator documentation, and detailed + behavioral integration coverage. +- `ansible-collection-dnd` owns the faithful subtree import and its existing + assembled-artifact validation boundary. It does not independently + reimplement or duplicate the pipeline behavior test. +- `ansible-workspace-dnd` owns this roadmap, the settled MVP decision, active + implementation plan, status, and review record. +- The standalone application roles, application sources, asset repositories, + and `rakestraw-ansible` remain unchanged. + +## Constraints and Settled Decisions + +- The public interface is a simple list of usernames, not a mapping of account + definitions. A richer structure would imply ownership of account creation + and login policy that this feature expressly excludes. +- All selected accounts must exist before enrollment begins. A single + `ansible.builtin.getent` loop over the `passwd` database is justified because + `ansible.builtin.user` with `state: present` would otherwise create a missing + account. No registered fact, separate assertion, or post-enrollment query is + required. +- The enrollment task uses `ansible.builtin.user` with the selected runtime + group and `append: true`. The module owns membership convergence; the role + does not inspect or reconstruct current group lists. +- The enrollment task uses `become: true`. The account-existence lookup does + not require elevation. +- The runtime group continues to be created by the existing Narratio role + dependency before the pipeline role's ordinary tasks execute. +- Empty input naturally skips both loops. No separate conditional, fact, or + branching task is needed. +- Omission is unmanaged, not absent. The feature adds access but does not + define revocation or exact-list reconciliation. +- No username grammar stricter than the managed host's account database is + introduced. The `getent` lookup and `user` module retain ownership of their + native input and error handling. + +## Simplest Viable Implementation + +Add the empty-list default and matching argument-spec entry. Add one +`ansible.builtin.getent` task that loops over the selected names with database +`passwd` and relies on its default missing-key failure, followed by one +privileged `ansible.builtin.user` task that loops over the same names, selects +`dnd_pipeline_runtime_group`, and uses `append: true`. + +Replace the README's consumer-owned membership example with the role variable +and its exact ownership boundary. In the existing integration driver, create +the temporary operator without `narratio` membership before the first role +application, pass that account through `dnd_pipeline_operator_users`, and +retain the existing native configuration and shared-access exercises. Do not +add a missing-user test, inspect `/etc/group`, assert module return data, or +create a second operator scenario. + +After the authoritative pipeline change is committed, validated, and pushed, +use the documented public Gitea `git subtree pull --squash` workflow to import +that exact commit into `ansible-collection-dnd`. Run the collection's existing +artifact-boundary integration suite without expanding its detailed feature +matrix. + +## Rationale and Alternatives + +Keeping membership entirely in each consumer play would avoid two role tasks, +but it leaves every deployment to reproduce access policy already owned by the +suite. An empty-by-default list adds the ergonomic path without affecting +consumers that prefer external membership management. + +Passing complete account definitions to the pipeline role would permit it to +create users, but it would also require defaults and policy for homes, shells, +authentication, IDs, and account removal. Those concerns are not pipeline +requirements and belong to host identity management. + +Calling `ansible.builtin.user` without first checking existence would be more +compact but would create missing accounts with implicit properties. The +`getent` lookup is therefore independently required to enforce the selected +ownership boundary; it is not defensive re-verification of state already +owned by another module. + +Exact-list reconciliation would make removal declarative, but omission has +not been selected as revocation and could remove access managed elsewhere. +Additive enrollment is the smaller and safer contract until lifecycle policy +is designed explicitly. + +## Acceptance Criteria + +- `dnd_pipeline_operator_users` defaults to an empty list and is declared as a + list of strings in the public argument specification. +- An empty list introduces no account or membership change. +- Every explicitly selected account must already exist, and a missing account + causes convergence to fail before the enrollment task can create or modify + any selected account. +- Each selected existing account is added to + `dnd_pipeline_runtime_group` additively without replacing its other groups. +- Omitted accounts and prior memberships remain unmanaged. +- The role uses only one account-existence task and one enrollment task; it + adds no handler, registered fact, assertion layer, command, private state, + or post-change verification. +- The pipeline documentation explains the variable, existing-account + prerequisite, additive non-removal behavior, group authorization boundary, + and login-session caveat. +- The existing temporary-operator integration scenario enrolls its fixture + through the public variable, demonstrates representative pipeline access, + and the immediate identical second role application reports `changed=0` + and `failed=0`. +- Syntax checking, production-profile lint, the complete standalone pipeline + integration suite, and `git diff --check` pass. +- The exact reviewed pipeline commit is pushed to public Gitea before the + collection imports it. +- The collection subtree contains the reviewed pipeline change through the + documented remote-only squashed import, and the existing collection + integration suite passes against the built and installed artifact. +- No application repository, asset repository, release tag, published + artifact, application configuration, filesystem policy, or credential value + changes. + +## Dependencies and Follow-up Work + +Features 0009, 0011, 0012, and 0013 are prerequisites. The completed Feature +0013 workspace and collection closeout commits should be pushed before the +implementation sprint begins so local and remote baselines agree. + +Upgrade, downgrade, account revocation, exact-membership reconciliation, +application removal, and publication of a release containing this feature +remain separate future work. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 30fedfa..fd1d328 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,8 +1,360 @@ -# Implementation Plan +# Implementation Plan 0014: Enroll Existing Pipeline Operators -Status: pending +Status: ready -Feature 0013 is complete. There is no active implementation plan. +Target executor: GPT-5.6-Terra -Select the next unit of work and agree on its numbered feature roadmap before -replacing this notice with a staged implementation plan. +Feature roadmap: +`docs/roadmap/features/0014-existing-pipeline-operator-enrollment.md` + +Active plan location: `docs/roadmap/implementation.md` + +## Objective + +Add one empty-by-default pipeline interface that enrolls explicitly selected +existing human accounts in the suite's runtime group. Implement the behavior +with one account-existence lookup and one additive membership task, adapt the +existing operator integration scenario, and import the reviewed result into +the collection from public Gitea. + +The Feature 0014 roadmap remains authoritative for scope, rationale, target +state, and acceptance criteria. This plan does not authorize human-account +creation or removal, exact-list reconciliation, filesystem-policy changes, or +a new release. + +## 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. +- Keep the production behavior to the roadmap's exact direct task flow: one + `ansible.builtin.getent` loop followed by one `ansible.builtin.user` loop. +- Do not add an assertion, registered fact, handler, command, shell operation, + explicit empty-list condition, membership comparison, post-change query, + sidecar state, or account abstraction. +- Trust `getent` to fail for a missing key and `user` to converge additive + membership. Do not reproduce either module's checks. +- Test the public behavior by adapting the existing temporary-operator + scenario. Do not add a missing-user test, inspect `/etc/passwd` or + `/etc/group`, assert task results, or duplicate the detailed test in the + collection. +- Run each stage's validation before committing it. 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. + +## Starting State and Preconditions + +- Features 0009, 0011, 0012, and 0013 are complete. +- This roadmap and implementation plan have been reviewed and committed in the + workspace repository before execution begins. +- The completed Feature 0013 closeout commits `eda361f` in the workspace and + `5e695f3` in the collection are pushed to their respective `origin/main` + branches before implementation begins. Preserve the Git-generated subtree + squash commit that accompanies `5e695f3`. +- `ansible-role-dnd-pipeline` starts clean on `main` at `78afffe`, equal to + `origin/main`. +- `ansible-collection-dnd` starts clean on `main` at `5e695f3`, equal to + `origin/main` after the prerequisite push. +- 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. + +## Repository Scope + +- `ansible-role-dnd-pipeline` owns the variable, argument specification, + account lookup, additive enrollment task, README, and detailed integration + behavior. +- `ansible-collection-dnd` receives the reviewed pipeline commit only through + its established squashed subtree and validates the assembled artifact. +- `ansible-workspace-dnd` records implementation progress and the review + handoff after the two implementation repositories are complete. +- All standalone application-role repositories, application source + repositories, asset repositories, and `rakestraw-ansible` are out of scope + and must remain unchanged. + +## Stage 1: Implement Existing-Operator Enrollment + +### Objective + +Give the standalone pipeline role its minimal public interface for enrolling +existing human accounts and prove the behavior through the existing operator +integration scenario. + +### 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/0014-existing-pipeline-operator-enrollment.md` + +### Preconditions + +- The workspace planning commit is present. +- `ansible-role-dnd-pipeline` is clean at `78afffe` on `main`, is not behind + or diverged from `origin/main`, and contains no unrelated changes. +- Its Narratio dependency still creates the selected runtime group before the + pipeline role's ordinary tasks execute. +- The existing integration driver still contains the temporary operator and + representative group-access scenario described by the roadmap. + +### Owning Repository + +`ansible-role-dnd-pipeline` + +### Required Changes + +1. Add `dnd_pipeline_operator_users: []` beside the existing runtime identity + defaults in `defaults/main.yml`. +2. Add the matching `meta/argument_specs.yml` entry with `type: list`, + `elements: str`, and the same required/default-backed convention used by + the role's other public variables. +3. Add one unprivileged `ansible.builtin.getent` task near the beginning of + `tasks/main.yml`. Loop directly over `dnd_pipeline_operator_users`, use the + `passwd` database and each username as `key`, and rely on the module's + default missing-key failure. Do not register its result or add a separate + assertion. +4. Immediately follow it with one `become: true` `ansible.builtin.user` task + over the same list. Set `name` to the selected account, + `groups` to `dnd_pipeline_runtime_group`, `append: true`, and + `state: present`. Do not set or manage any other account property. +5. Revise the README variable reference and shared-execution section. Replace + the consumer-owned membership example and deferred wording with the new + interface, existing-account prerequisite, additive non-removal behavior, + authorization consequence, and new-login-session caveat. +6. Adapt `tests/integration` rather than adding another scenario. Create its + temporary operator before the initial role application without membership + in the runtime group, pass that username through + `dnd_pipeline_operator_users` for the baseline and repeated applications, + and retain the existing native configuration, secret-boundary, and shared + cache exercises under that identity. Reorder cleanup as necessary so any + final baseline convergence occurs while the selected fixture account still + exists, then remove the fixture account. +7. Retain the existing clean-repeat assertion. Do not add a negative + missing-user case or assertions about module internals, task traces, the + current default value, or raw account database entries. +8. Run the complete existing repository validation, commit the result, push + `main` to the public pipeline origin, and record the full pushed commit for + Stage 2. + +### Validation + +Run from the workspace root: + +```text +(cd ansible-role-dnd-pipeline && tests/integration && git diff --check) +``` + +Expected result: syntax and production-profile lint pass; the temporary +existing account is enrolled through the public role variable and completes +the existing representative operator-access scenario; native application +checks pass; the immediate identical role application reports `changed=0` +and `failed=0`; and no credential value appears in test output. + +### Completion Criteria + +- The public interface, argument specification, two direct tasks, and README + implement exactly the roadmap contract. +- The existing operator scenario uses the role interface rather than fixture + group enrollment. +- The full standalone integration suite and `git diff --check` pass. +- The role repository is clean after a plain-English commit. +- The exact commit is present on public `origin/main` and its full hash is + available for the collection import. + +### Commit + +Commit intent: `Add optional pipeline operator enrollment` + +## Stage 2: Import the Reviewed Pipeline Change + +### Objective + +Expose the reviewed operator interface through `rakestraw.dnd.pipeline` while +preserving the authoritative-standalone-repository and collection-artifact +boundaries. + +### 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/0014-existing-pipeline-operator-enrollment.md` +- `ansible-collection-dnd/README.md` + +### Preconditions + +- Stage 1 is complete and its exact commit is publicly reachable from + `https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git`. +- `ansible-collection-dnd` is clean at `5e695f3` on `main`, is not behind or + diverged from `origin/main`, and contains no unrelated changes. +- The collection's current `roles/pipeline` subtree still corresponds to the + authoritative pipeline history through `78afffe`. + +### Owning Repository + +`ansible-collection-dnd` + +### Required Changes + +1. Set a shell variable to the full pushed Stage 1 commit hash and run the + documented remote-only update from the collection repository: + + ```text + pipeline_revision= + git subtree pull --prefix=roles/pipeline \ + https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git \ + "$pipeline_revision" --squash -m "Import pipeline operator enrollment" + ``` + +2. Do not edit role behavior directly beneath `roles/pipeline`. The subtree + import should carry the new default, argument specification, tasks, README, + and standalone tests faithfully. +3. Do not change `galaxy.yml`, dependency manifests, collection-level tests, + or release documentation. No dependency or published version changes in + this feature, and the detailed behavior remains covered by Stage 1. +4. Run the existing collection integration suite against the built and + installed artifact. Commit no additional files after the subtree command + unless validation exposes a genuine collection-boundary issue within this + feature's scope. +5. Push the resulting collection history to `origin/main` and record the + resulting merge commit and Git-generated squashed subtree commit. + +### Validation + +Run from the workspace root: + +```text +(cd ansible-collection-dnd && tests/integration && git diff --check) +``` + +Expected result: the collection builds; the archive contains the updated +pipeline role while retaining its development-file exclusions; isolated +dependency and artifact installation succeeds; the FQCN resolves; native +representative application checks pass; and the immediate repeat reports +`changed=0` and `failed=0`. + +### Completion Criteria + +- Git history records a squashed subtree import from the exact public Stage 1 + commit with the stated plain-English merge message. +- No pipeline behavior was authored directly in the collection. +- The existing collection suite and `git diff --check` pass without an + unnecessary duplicate operator test. +- The collection is clean and its new history is present on `origin/main`. + +### Commit + +Commit intent: `Import pipeline operator enrollment` + +The subtree command creates the stage's merge commit and its generated squash +commit; do not add an empty or redundant manual commit. + +## Stage 3: Record the Implementation Handoff + +### Objective + +Record the completed implementation evidence without marking Feature 0014 +done before independent review. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/planning.md` +- `docs/roadmap/features/0014-existing-pipeline-operator-enrollment.md` + +### Preconditions + +- Stages 1 and 2 are complete, committed, pushed, and validated. +- Their full commit hashes and validation results are available. +- The workspace repository is clean apart from the expected progress-record + edits for this stage and is not behind or diverged from `origin/main`. + +### Owning Repository + +`ansible-workspace-dnd` + +### Required Changes + +1. Change Feature 0014'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 0014 evidence with the exact + pipeline and collection commit hashes and the validation completed. +3. Replace this plan's Progress Notes with a concise record of the three stage + states and their commits. Do not copy command logs into the repository. +4. Do not mark the feature `done`, remove the active plan, or create + `docs/roadmap/remediation.md`; those are 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 the exact implementation +evidence while retaining independent review as the next step. + +### Completion Criteria + +- Workspace status accurately identifies Feature 0014 as implemented and + awaiting review. +- The roadmap remains the durable target-state record and is not polluted with + execution logs. +- The active plan records concise implementation evidence and contains no + false completion claim. +- The workspace repository is clean after the handoff commit. + +### Commit + +Commit intent: `Record pipeline operator enrollment implementation` + +## Final Validation and Handoff + +- Confirm Stage 1's complete standalone integration result and Stage 2'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, collection merge, collection subtree-squash, and + workspace handoff commit hashes. +- Summarize any deviation from this plan, unresolved finding, or added + implementation complexity and identify the acceptance criterion that + required it. +- Do not mark Feature 0014 `done`; implementation results require independent + review first. + +## Progress Notes + +- Planning complete; implementation has not started. diff --git a/docs/roadmap/mvp.md b/docs/roadmap/mvp.md index 637054c..87d49be 100644 --- a/docs/roadmap/mvp.md +++ b/docs/roadmap/mvp.md @@ -16,9 +16,9 @@ The `rakestraw.dnd` collection exposes that role as `rakestraw.dnd.pipeline`. The suite-level role installs and configures the complete D&D transcript processing pipeline on a single supported host. Operators or unattended automation invoke Narratio commands either under the dedicated `narratio` -runtime identity or under a human account that belongs to the `narratio` -group, processing D&D session recordings into transcripts and related -artifacts. +runtime identity or under an explicitly selected existing human account that +belongs to the `narratio` group, processing D&D session recordings into +transcripts and related artifacts. ## Locked Decisions @@ -253,9 +253,18 @@ application-role releases in one source repository. - Application source trees and installed binaries are owned by `root` and are not writable by operators or the runtime account. - The supported operational model runs `narratio run` and other processing - commands either as the dedicated `narratio` account or as a human account - that is already a member of the `narratio` group. The suite does not yet - select those human accounts or manage their membership. + commands either as the dedicated `narratio` account or as an existing human + account selected through the pipeline role's + `dnd_pipeline_operator_users` list. The list defaults to empty. +- Every selected human account must exist before pipeline convergence. The + role adds selected accounts to the runtime group with additive supplementary + membership and does not create accounts, replace other group memberships, + or manage omitted accounts. +- Removing a name from `dnd_pipeline_operator_users` does not revoke existing + membership. Account and access removal remain outside the MVP until an + explicit lifecycle policy is selected. +- Newly granted supplementary membership may require the operator to begin a + new login session before it becomes visible to that session. - Application configuration directories and files are owned by `narratio:narratio`, use modes `0755` and `0644`, respectively, and are world-readable. Configuration remains under Ansible control rather than @@ -416,7 +425,6 @@ managed host. The prompt-library checkout retains its upstream `prompts/` and ## Design Work Still Open -The following areas require investigation and decisions before implementation: +The following area requires investigation and decisions before implementation: -- Optional suite-level operator-selection and group-membership management - Upgrade, downgrade, and removal behavior diff --git a/docs/status.md b/docs/status.md index df34036..9429568 100644 --- a/docs/status.md +++ b/docs/status.md @@ -1,10 +1,10 @@ # Workspace Status -Last updated: 2026-09-17 +Last updated: 2026-09-18 Current milestone: First coordinated suite release complete -Current focus: Select the next unit of work. +Current focus: Implement Feature 0014. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -30,6 +30,7 @@ Current focus: Select the next unit of work. | F0011 | Deliver pipeline credentials and Notarius reuse | ansible-role-narratio and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `de1b191` | | F0012 | Assemble the D&D collection | ansible-collection-dnd and ansible-role-dnd-pipeline | done | Pipeline `600eb21` assembled and validated through collection remediation commit `da67b34` | | 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 | ready | Execute `docs/roadmap/implementation.md` in stage order | | 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 |