Compare commits

..

2 Commits

Author SHA1 Message Date
a5bc701f60 Plan pipeline operator enrollment 2026-09-18 12:44:26 +00:00
eda361fa5d Complete the first suite release 2026-09-17 23:52:46 +00:00
6 changed files with 592 additions and 837 deletions

View File

@@ -1,6 +1,6 @@
# Feature 0013: Publish the First Coordinated Suite Release
Status: in_progress
Status: done
## Summary

View File

@@ -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.

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -1,173 +1,147 @@
# Feature 0012 Remediation Review
# Feature 0013 Remediation Review
Status: resolved
Reviewed implementation commits:
Reviewed implementation and release state:
- `600eb21 Document standalone and collection pipeline usage`
- `3f7f82e Establish the D&D collection foundation`
- `c84aa0d Merge commit '5dbae8a' as 'roles/pipeline'`
- `10ad31c Test the assembled D&D collection`
- Application-role `v0.1.0` tags at the five roadmap-fixed commits
- Pipeline release commit and tag
`7c2bad827702fdcf78f8f77ece7d6270756bc3c5`
- Collection subtree import
`da348eb8bd9878a58404a37dbcf22ad6562ac5c9`
- Collection release commit and tag
`63e8f3fb090a583226c7435bd900e10d41a30b89`
- Public `rakestraw.dnd 0.1.0` Gitea release and
`rakestraw-dnd-0.1.0.tar.gz` attachment
- Workspace implementation record through
`06e1b35f25589a3a6ff3fd2884208c86c4fee9c4`
## Review Summary
Feature 0012 implements the principal target architecture. The standalone
pipeline repository remains authoritative, and collection history records its
exact `600eb21` snapshot as a squashed subtree at `roles/pipeline`. The
collection has valid Galaxy and runtime metadata, exact native collection
dependencies, one unified bootstrap manifest for the five Git-hosted roles,
focused build exclusions, and an isolated artifact-level integration entry
point. The collection builds as `rakestraw.dnd` 0.1.0 and exposes
`rakestraw.dnd.pipeline`.
Feature 0013 implements the release architecture and public consumer path.
The five application-role tags identify the exact reviewed commits selected by
the roadmap. The standalone pipeline and collection manifests use those
immutable tags, and the native collection dependencies remain pinned to
`ansible.posix` 2.2.0 and `community.general` 13.3.0. The collection subtree's
Git tree exactly matches public pipeline tag `v0.1.0`.
Two low-severity issues were found and are now resolved. The collection's
subtree maintenance examples derived a commit from the local sibling
repository but told Git to fetch that commit from a remote which did not
contain it at review time. Separately, the collection integration driver
repeated secret-redaction assertions already owned by the standalone pipeline
suite; those assertions did not validate collection assembly and strengthened
the collection test contract beyond the selected packaging boundary.
All seven repositories and tags are public and synchronized with their local
counterparts. The collection's non-draft, non-prerelease Gitea release carries
one correctly named archive. Its manifest declares `rakestraw.dnd` 0.1.0, the
expected Ansible baseline and collection dependencies, and its file payload
matches a fresh build from the tagged collection tree.
## Finding 1: Subtree Maintenance Commands Mix Local and Remote Sources
One low-severity documentation issue remains. The pipeline README now implies
that collection snapshots may be imported only from role releases. That
strengthens the settled maintenance contract beyond the requested release
feature and contradicts the documented development workflow, which also
permits a reviewed, pushed commit.
## Finding 1: Pipeline Documentation Narrows Subtree Imports to Releases
Severity: low
`ansible-collection-dnd/README.md:51-63` obtains `pipeline_commit` from
`../ansible-role-dnd-pipeline`, but passes the Gitea URL as the repository
argument to both `git subtree add` and `git subtree pull`. The reviewed
pipeline commit was seven commits ahead of `origin/main` at review time; the
remote advertised `b15fe8d`, not imported commit `600eb21`. The documented
command therefore could not reproduce the current import.
`ansible-role-dnd-pipeline/README.md:51-53` says that collection maintainers
“import a reviewed release as a snapshot.” The same sentence is present in the
faithfully imported collection copy at
`ansible-collection-dnd/roles/pipeline/README.md:51-53`.
The collection artifact already contains the imported role, so consumers do
not run these commands or need a sibling checkout. The commands are the
maintainer-facing assembly interface and should also be portable outside this
workspace. The durable contract should therefore use Gitea exclusively: first
push the reviewed pipeline commit or tag to the authoritative repository, then
identify that remote revision explicitly and import it from the same URL.
That wording accurately describes the particular snapshot used for collection
release 0.1.0, but it reads as the general maintenance rule. The durable
architecture deliberately permits the collection to import any reviewed
pipeline commit that has been pushed to Gitea during development. An immutable
pipeline tag is required only when preparing a released compatibility set.
The collection's own maintenance section correctly accepts a pushed commit or
immutable tag.
This is an inadvertent requirement strengthening: it could force an otherwise
unnecessary pipeline-role release merely to assemble and test a development
collection snapshot. It does not affect runtime behavior, the released
dependency pins, subtree fidelity, or consumer installation.
### Required Remediation
- Remove the sibling-repository `git rev-parse` commands from both subtree
examples.
- Define an explicit `pipeline_revision` placeholder representing a reviewed
commit or immutable tag that has already been pushed to Gitea, and pass that
revision with the authoritative Gitea URL to both `git subtree add` and
`git subtree pull`.
- State concisely that a pipeline revision must be committed, reviewed, and
pushed to the authoritative repository before collection assembly imports
it. Do not prescribe a branch name or require a release tag during active
development; a pushed full commit ID remains valid.
- Do not add a configured remote, sibling-path assumption, synchronization
script, lock file, or private provenance state.
- Do not rewrite subtree history or reimport the current role. This is a
collection-owned documentation correction only.
- Confirm that Gitea contains the selected pipeline revision, then validate
the corrected initial command in a disposable Git repository without using
the local sibling repository as the subtree source.
- In the authoritative pipeline README, replace the release-only wording with
concise language saying that collection maintainers import a reviewed,
pushed commit or immutable tag as a snapshot.
- Make no role, manifest, default, task, template, handler, or test change.
- Commit and push the pipeline documentation correction before importing it
into the collection.
- Refresh `roles/pipeline` through the documented squashed subtree command
using the pushed pipeline documentation commit as the remote revision. Do
not edit the collection's subtree copy directly.
- Confirm that the resulting collection subtree Git tree exactly matches the
selected pushed pipeline commit outside Git metadata.
- Do not move or replace any `v0.1.0` tag, modify the published Gitea release,
or replace its attachment. Those immutable artifacts correctly describe the
historical 0.1.0 source state.
- Do not create a new role or collection release solely for this
maintainer-facing wording correction.
## Finding 2: The Collection Test Duplicates Secret-Redaction Coverage
### Required Validation
Severity: low
`ansible-collection-dnd/tests/integration:19-20` defines two synthetic values
solely so lines 74-75 can search the first convergence log for them. Secret-safe
task output is pipeline behavior established by Feature 0011 and already
covered by `ansible-role-dnd-pipeline/tests/integration`. The collection owns
artifact construction, bootstrap installation, FQCN resolution, representative
assembled behavior, and clean repeated convergence; it does not own a second
credential-redaction contract.
The implementation plan required synthetic credentials so native
configuration could be exercised without real provider values, but it did not
require the collection to retest Feature 0011 redaction. These two assertions
are therefore an inadvertent strengthening by the implementing agent and
conflict with the roadmap's instruction to keep detailed pipeline feature
coverage in the standalone role.
The native Seriatim, Audita, Notarius, Scriptorium, and Narratio checks are not
part of this finding. They are state-based, inexpensive, and implement the
roadmap's express requirement for representative native validation of the
assembled suite.
### Required Remediation
- Retain distinctive synthetic credential contents in the collection
convergence variables; no real credential or live provider call may enter
the suite.
- Remove the two shell variables used only for log searching and remove the two
secret-content grep assertions.
- Retain isolated dependency installation, archive boundary checks, FQCN
syntax and lint validation, the selected native application checks, and the
immediate `changed=0 failed=0` repeat.
- Do not replace the removed assertions with another collection-level
credential, log, file-content, or implementation-trace test.
## Resolution
Resolved in collection commits `556b6ed` and `da67b34`.
The collection README now uses an explicit `PUSHED_COMMIT_OR_TAG` revision and
the authoritative Gitea URL for both initial and subsequent subtree imports.
It states that the selected revision must be committed, reviewed, and pushed
before collection assembly. The examples no longer inspect or depend on a
sibling checkout. A disposable repository successfully imported the exact
commit advertised by Gitea through the documented remote-only command shape.
The collection integration driver retains its distinctive synthetic
credential inputs but no longer defines separate values solely for log
searching or duplicates the standalone pipeline suite's two redaction
assertions. Its artifact, dependency, FQCN, native application, and clean
repeat coverage remain unchanged.
## Required Validation
After remediation, run:
Run:
```text
cd ansible-collection-dnd
bash -n tests/integration
tests/integration
cd ansible-role-dnd-pipeline
git diff --check
cd ../ansible-collection-dnd
../.venv/bin/ansible-galaxy collection build --output-path "$(mktemp -d)"
git diff --check
```
The result must demonstrate isolated dependency bootstrap, collection build
and artifact installation, FQCN resolution, the retained native application
checks, and immediate clean convergence. The built artifact must still include
`roles/pipeline/tasks/main.yml` and exclude the selected development-only
subtree content.
Also compare the imported `roles/pipeline` tree with a disposable clone of the
selected pushed pipeline commit. The full application, pipeline, and
collection integration suites do not need to be rerun because the remediation
changes documentation only and preserves all Ansible and dependency content.
Validate the corrected subtree example against Gitea in a disposable Git
repository without modifying the real collection history or relying on the
local sibling repository as the source. The standalone pipeline integration
suite does not need to be rerun for these collection-only documentation and
test-scope changes.
## Resolution
Resolved in pipeline commit `78afffe` and collection subtree import
`5e695f3`.
The authoritative pipeline README now states that collection maintainers may
import either a reviewed, pushed commit or an immutable tag. The pipeline
commit was pushed before the collection imported that exact Gitea revision
through the documented squashed subtree workflow. The imported subtree and
pipeline source have the same Git tree ID,
`37f619ac24d2303847c4b9ea60db1f9fc1bf9d0e`.
A fresh collection build succeeded, and `git diff --check` passed in both
repositories. No Ansible content or dependency selection changed, so the
integration suites were not rerun. The seven `v0.1.0` tags, published
collection release, and release attachment remain unchanged.
## Review Validation Evidence
The review compared the complete standalone pipeline repository with
`roles/pipeline`; the trees are byte-for-byte identical outside Git metadata.
The root bootstrap manifest's role and collection sections exactly match the
two imported pipeline manifests, and `galaxy.yml` declares the same native
collection versions.
- Every local and remote `v0.1.0` tag resolves to the commit recorded in the
Feature 0013 roadmap and implementation notes.
- All seven Gitea repositories report public visibility and `main` as their
default branch.
- The pipeline `v0.1.0` tree ID and the collection tag's
`roles/pipeline` tree ID are both
`44a9d2b010012d8a63720b3a4ed07e9f255a5dae`.
- The tagged raw collection manifest matches the repository manifest, and its
role and collection selections match the released pipeline manifests.
- The public release API reports tag `v0.1.0`, title
`rakestraw.dnd 0.1.0`, `draft: false`, `prerelease: false`, and one
`rakestraw-dnd-0.1.0.tar.gz` attachment.
- The published archive has the same file list, `MANIFEST.json`, `FILES.json`,
and file payload hashes as a fresh collection build from the tagged tree.
It contains the pipeline entry point and omits the selected development-only
subtree files.
- A fresh unauthenticated clone and release-attachment download installed the
five public role tags and the collection into isolated Ansible paths. The
installed `rakestraw.dnd.pipeline` role converged successfully and its
immediate repeat reported `changed=0` and `failed=0`.
- The complete repository-local collection integration suite independently
passed isolated bootstrap, collection build and installation, syntax check,
production-profile lint, native application validation, and immediate clean
convergence.
- `git diff --check` passes for the pipeline, collection, and workspace
implementation ranges. All workspace repositories are clean and synchronized
with their upstream branches before this review finding is recorded.
A fresh collection build produced
`rakestraw-dnd-0.1.0.tar.gz`. The archive contains the pipeline task entry
point and omits the selected nested tests, Ansible configuration, dependency
manifests, and Git ignore file. Installing that artifact into a temporary
collection path made `rakestraw.dnd.pipeline` discoverable. A separate
isolated bootstrap installed the unified requirements, after which syntax
checking and production-profile ansible-lint passed.
`bash -n ansible-collection-dnd/tests/integration`, manifest consistency
checks, `git diff --check`, and collection repository integrity checks also
passed during review.
After remediation, the remote-only subtree command successfully imported the
revision advertised by Gitea into a disposable repository, and a fresh
collection build succeeded. The complete collection integration entry point
then passed isolated dependency installation, artifact construction and
installation, syntax checking, production-profile lint, all retained native
application checks, and two recaps with `changed=0` and `failed=0`. The
standalone pipeline suite was not rerun because neither remediation changed
the authoritative pipeline role.
No runtime code-quality issue, release-architecture gap, test-policy violation,
or other inadvertent requirement strengthening was found.

View File

@@ -1,10 +1,10 @@
# Workspace Status
Last updated: 2026-09-17
Last updated: 2026-09-18
Current milestone: First coordinated suite release
Current milestone: First coordinated suite release complete
Current focus: Independently review the Feature 0013 implementation.
Current focus: Implement Feature 0014.
| ID | Deliverable | Owner | State | Evidence or next step |
| --- | --- | --- | --- | --- |
@@ -29,7 +29,8 @@ Current focus: Independently review the Feature 0013 implementation.
| F0010 | Integrate D&D Notarius extraction | ansible-role-notarius and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `bbf01e1` |
| 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 | in_progress | Public `v0.1.0` tags: Audita `66ebea9`, Narratio `292d866`, Notarius `14a38e0`, Seriatim `e08c63c`, Scriptorium `8b4c86e`, pipeline `7c2bad8`, collection `63e8f3f`; [collection release](https://gitea.maximumdirect.net/eric/ansible-collection-dnd/releases/tag/v0.1.0) |
| 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 |