Plan the D&D collection assembly

This commit is contained in:
2026-09-17 03:26:04 +00:00
parent 54a2362c02
commit 9a86cdb57e
4 changed files with 880 additions and 12 deletions

View File

@@ -0,0 +1,304 @@
# Feature 0012: Assemble the D&D Collection
Status: ready
## Summary
Turn the existing `ansible-collection-dnd` repository into a valid, buildable
`rakestraw.dnd` Ansible collection that exposes the independently developed
pipeline role as `rakestraw.dnd.pipeline`. The collection will carry a
self-contained snapshot of the pipeline role, publish the collection
dependencies Ansible can resolve natively, and provide one consumer bootstrap
manifest for the five Git-hosted application roles.
## Problem or Opportunity
The standalone application roles and the opinionated pipeline role are now
implemented and independently tested, but the collection repository still
contains only a placeholder README and repository metadata. A consumer cannot
build or install `rakestraw.dnd`, invoke the intended fully qualified role
name, or reproduce the reviewed combination of application-role dependencies
from that repository.
The pipeline role must remain independently developed, versioned, and usable.
At the same time, the collection artifact must contain the role it advertises;
it cannot depend on a sibling checkout, a symbolic link, or workspace-only
tooling at runtime. The assembly boundary therefore needs an explicit,
repeatable source-import convention and focused integration coverage of the
packaged result.
## Governing Policies
- [The Ansible house style](../../ansible.md) governs collection metadata,
dependency declarations, documentation, and the preference for native
Ansible packaging behavior.
- [The testing house style](../../testing.md) governs behavior-oriented,
state-based validation and the avoidance of tests that merely restate file
layout or implementation details.
- [The MVP roadmap](../mvp.md) establishes the collection name, independently
released role repositories, Git-hosted application-role dependencies, and
the collection as the compatibility record for an assembled release.
- Features [0006](0006-pipeline-role-composition-foundation.md) through
[0011](0011-managed-pipeline-credential-delivery.md) define the pipeline
role behavior being assembled; this feature does not reopen those contracts.
## Scope
- Add valid Ansible Galaxy metadata for collection namespace `rakestraw`, name
`dnd`, development version `0.1.0`, the repository's existing license and
README, and its supported Ansible version.
- Declare the exact `ansible.posix` and `community.general` versions already
selected by the pipeline role as collection dependencies.
- Import the complete standalone pipeline-role repository into
`roles/pipeline` as a squashed Git subtree at an explicitly reviewed commit.
- Treat `ansible-role-dnd-pipeline` as authoritative: changes are made and
reviewed there first, then deliberately imported into the collection. Do
not edit role behavior directly beneath the collection's subtree prefix.
- Document the initial subtree import and subsequent update commands so the
source relationship is reproducible without custom tooling or private
knowledge.
- Ensure the standalone pipeline role's collection-facing documentation
distinguishes its standalone role name and invocation from
`rakestraw.dnd.pipeline` use without changing its public behavior.
- Add `meta/runtime.yml` with `requires_ansible: ">=2.18.0"`, matching the
implemented roles' supported baseline.
- Add one root `requirements.yml` that combines the five Git-hosted
application-role dependencies with the two collection dependencies needed
to bootstrap the assembled suite.
- Pin application roles to the exact reviewed commits already selected by the
standalone pipeline role during development. Keep the root bootstrap
manifest and the imported role's dependency manifests consistent.
- Configure collection builds to omit development-only content embedded in the
role subtree, including its integration suite, local Ansible configuration,
and nested dependency manifests. Retain operator-facing role documentation
and licensing in the source collection unless Ansible packaging requires
otherwise.
- Replace the collection's placeholder README with concise instructions for
dependency bootstrap, collection build and installation, FQCN invocation,
subtree provenance and updates, supported platform, and the distinction
between development commit pins and future released role tags.
- Add a focused collection integration suite that starts with isolated role
and collection paths, installs the root bootstrap manifest and the locally
built collection artifact, invokes `rakestraw.dnd.pipeline`, validates the
assembled pipeline through the applications' native configuration
interfaces, and verifies an immediate second application converges with no
reported changes.
## Non-goals
- Publishing the collection to Ansible Galaxy, Automation Hub, Gitea, or any
other registry.
- Creating the first collection release tag or application-role release tags.
- Replacing development commit pins with immutable role tags before those tags
exist.
- Vendoring any of the five standalone application roles into the collection.
- Moving authoritative pipeline-role development into the collection
repository or permitting collection-local role forks.
- Changing pipeline defaults, host convergence, application versions,
application configuration, asset deployment, credentials, or runtime
behavior.
- Adding collection plugins, modules, filters, playbooks, execution
environments, CI workflows, release automation, or a general-purpose sync
framework.
- Repeating every standalone pipeline integration scenario inside the
collection suite or asserting the exact contents of metadata and manifests
as an implementation snapshot.
- Supporting installation without network access. The collection artifact is
self-contained for the pipeline role, but its declared external role and
collection dependencies must still be made available to Ansible.
## Target End State
The collection repository has this durable shape:
```text
ansible-collection-dnd/
├── galaxy.yml
├── meta/
│ └── runtime.yml
├── requirements.yml
├── roles/
│ └── pipeline/ imported pipeline-role subtree
├── tests/
│ ├── converge.yml
│ ├── integration assembled-artifact behavior test
│ └── inventory
├── LICENSE
└── README.md
```
`ansible-galaxy collection build` produces a valid
`rakestraw-dnd-0.1.0.tar.gz` artifact. After the documented bootstrap installs
the root dependency manifest and the built artifact into clean Ansible paths,
a consumer can invoke:
```yaml
- name: Install and configure the D&D transcript pipeline
hosts: pipeline_hosts
roles:
- role: rakestraw.dnd.pipeline
```
The collection contains ordinary role files at `roles/pipeline`; it has no
runtime link to the standalone repository. Git history records that directory
as a squashed subtree import from `ansible-role-dnd-pipeline`. Maintainers make
pipeline changes in the standalone repository, validate and commit them there,
then update the collection subtree from the desired reviewed commit.
The root bootstrap manifest is the consumer-facing compatibility manifest for
development. It contains the same five application-role sources and reviewed
commit pins as the imported pipeline role, plus exact versions of
`ansible.posix` and `community.general`. The collection's Galaxy metadata also
declares those two collection dependencies because Ansible can resolve them as
native collection dependencies. This intentional duplication serves two
different installation boundaries and must remain consistent.
Development-only files may remain in the subtree source for faithful
provenance, but they are excluded from the built artifact. The collection's
own integration suite exercises the artifact rather than the repository role
directory, with role and collection paths isolated from ordinary user
installations.
## Repository Ownership
- `ansible-collection-dnd` owns collection metadata, the consumer bootstrap
manifest, the imported pipeline snapshot, collection-facing documentation,
build exclusions, and assembled-artifact integration coverage.
- `ansible-role-dnd-pipeline` remains authoritative for all pipeline-role code,
defaults, templates, dependency metadata, standalone documentation, and its
comprehensive integration suite. This feature changes only the wording
needed to document both standalone and collection use.
- The five standalone application-role repositories remain authoritative for
their roles and are read-only inputs to this feature.
- `campaigns` and `narratio-prompts` remain independently managed asset
repositories and are read-only integration inputs.
- `ansible-workspace-dnd` owns this feature roadmap, progress tracking, and the
later independent review record.
- Application source repositories and `rakestraw-ansible` remain unchanged.
## Constraints and Settled Decisions
- The collection is `rakestraw.dnd`; the bundled role's FQCN is
`rakestraw.dnd.pipeline`.
- A squashed Git subtree is the selected incorporation mechanism. It yields a
normal, self-contained collection artifact while preserving an auditable
upstream relationship and avoiding submodule checkout requirements,
symbolic links, manual copying, or custom synchronization state.
- The subtree prefix is `roles/pipeline`, and the standalone pipeline
repository remains the only place where role behavior is authored.
- The first development build uses collection version `0.1.0`. This version
enables ordinary Galaxy build and install validation but does not itself
authorize publication or establish a release tag.
- Development dependencies use exact reviewed commits. A later release pass
must replace all application-role commit pins with immutable role release
tags and revalidate the assembled artifact before publishing.
- Collection dependencies remain exactly `ansible.posix` 2.2.0 and
`community.general` 13.3.0, matching the existing reviewed pipeline
manifests.
- Galaxy metadata cannot install arbitrary standalone Git roles. The root
unified requirements manifest and documented bootstrap are therefore part
of the collection's public installation contract.
- The collection integration suite must not receive dependencies from the
developer's normal Ansible paths. Its success must demonstrate that the
documented manifest and built artifact are sufficient.
- The collection suite owns only the packaging boundary: buildability,
dependency bootstrap, FQCN resolution, representative assembled behavior,
native configuration acceptance, and convergence. Detailed pipeline feature
matrices remain in the standalone role's tests.
- The collection does not add probes, manifests, checksums, copied-file
comparisons, or private state to police the subtree. Git and the documented
subtree workflow are the provenance mechanism.
## Simplest Viable Implementation
Use Ansible's conventional collection layout and metadata directly. Import the
reviewed pipeline repository with ordinary `git subtree add --squash`, then
exclude only the subtree's development fixtures and nested bootstrap files
from Galaxy builds. No wrapper role, generated role, symbolic link, submodule,
or synchronization script is required.
Derive the root unified dependency manifest directly from the pipeline role's
two existing manifests. The only deliberate duplication is the collection
dependency declaration in `galaxy.yml`, because the artifact and the source
bootstrap have distinct native Ansible dependency interfaces.
Use one representative integration path: build into a temporary directory,
install dependencies and the artifact into isolated temporary Ansible paths,
apply `rakestraw.dnd.pipeline` using the same offline synthetic inputs already
proven by the standalone suite, run native application configuration
validation, and apply the play a second time to assert `changed=0` and
`failed=0`. This tests the behavior unique to collection assembly without
duplicating the standalone role's full test matrix.
## Rationale and Alternatives
A squashed subtree is preferable to a Git submodule because Ansible collection
archives require real role content and should build correctly from an ordinary
checkout without a second initialization step. It is preferable to a symbolic
link because archive behavior and installed collection paths would be fragile.
It is preferable to an unrecorded copy because subtree history retains the
source relationship and provides a standard update command. Squashing avoids
injecting the pipeline repository's entire development history into the
collection while still recording each reviewed import.
Moving the role permanently into the collection would simplify assembly, but
would discard the settled requirement that the suite role remain independently
developed, tested, versioned, and usable. A thin collection wrapper that
depends on `rakestraw.dnd_pipeline` would avoid source import but would not
actually bundle the role or satisfy the desired FQCN without adding another
runtime dependency layer.
Keeping one unified root requirements file gives consumers one bootstrap
command for both dependency kinds. Retaining the imported role's own
requirements files in source preserves standalone repository fidelity; build
exclusion prevents those nested development interfaces from confusing users
of the installed artifact.
## Acceptance Criteria
- The collection repository is recognized by `ansible-galaxy` as
`rakestraw.dnd` version `0.1.0` and builds successfully from a clean checkout.
- The built archive contains `roles/pipeline` and excludes the imported role's
development-only integration suite, local Ansible configuration, and nested
dependency manifests.
- The role content at `roles/pipeline` is traceable to a documented reviewed
commit of `ansible-role-dnd-pipeline` through the repository's squashed
subtree history.
- The standalone pipeline README accurately documents both
`rakestraw.dnd_pipeline` and `rakestraw.dnd.pipeline` consumption without
changing role behavior.
- `meta/runtime.yml` selects Ansible 2.18 or newer, and Galaxy metadata declares
the exact two collection dependencies used by the pipeline.
- The root bootstrap manifest contains all five standalone application roles
at the same reviewed commits used by the imported pipeline role and the
exact two required collections.
- Collection documentation provides sufficient commands to install the
bootstrap dependencies, build and install the artifact, invoke the pipeline
FQCN, and update the subtree from a future reviewed pipeline commit.
- The integration suite starts with isolated Ansible role and collection
paths, installs only the declared bootstrap inputs and built artifact, and
resolves `rakestraw.dnd.pipeline` without access to a sibling role checkout.
- The representative assembled deployment passes the applications' native
configuration validation and an immediate identical second run reports
`changed=0` and `failed=0`.
- Existing standalone pipeline-role validation continues to pass after its
documentation-only change.
- No application role, application source, asset behavior, or pipeline host
convergence behavior changes as part of this feature.
## Dependencies and Follow-up Work
- Features 0001 through 0011 and their reviewed role commits are prerequisites.
- A subsequent release feature must create immutable role tags, replace
development commit pins, select the release collection version, validate the
tagged combination, create release notes and tags, and publish or distribute
the artifact.
- CI automation may later run the collection integration suite after a local,
repeatable workflow exists.
## Potential Future Hardening
- Sign collection artifacts or publish checksums and software bills of
materials when a distribution threat model requires them.
- Automate subtree provenance checks and dependency-pin synchronization if
manual collection updates become frequent enough to justify that machinery.

View File

@@ -1,8 +1,559 @@
# Implementation Plan
# Implementation Plan 0012: Assemble the D&D Collection
Status: pending
Status: proposed
Feature 0011 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/0012-collection-assembly.md`
Active plan location: `docs/roadmap/implementation.md`
## Objective
Build the initial `rakestraw.dnd` collection around the independently
maintained pipeline role. The completed source repository must build and
install as collection version `0.1.0`, expose the imported role as
`rakestraw.dnd.pipeline`, bootstrap the exact reviewed standalone role and
collection dependencies, and prove the packaged boundary through one focused
isolated integration path. The feature roadmap remains authoritative for
scope, rationale, target state, and acceptance criteria.
## Execution Rules
- Execute stages in numeric order.
- Number stages with consecutive integers beginning with `Stage 1`. Do not use
zero-based, decimal, nested, or nonsequential stage identifiers.
- Before each stage, confirm its preconditions and the working-tree state of
its owning repository.
- Before each stage, read 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.
- Do not make unresolved product or architecture decisions during execution;
stop and report the decision required.
- Start from the feature roadmap's simplest viable implementation. Use native
Galaxy metadata, dependency manifests, collection layout, and Git subtree
behavior rather than adding wrappers, generators, synchronization scripts,
or private state.
- Do not alter pipeline behavior in the standalone repository or beneath the
imported `roles/pipeline` prefix. Any discovered behavioral defect belongs
in the standalone pipeline repository and requires a separately reviewed
change before a new subtree import.
- Do not add integrity, drift, release, publishing, signing, rollback, or
offline-installation guarantees beyond the feature roadmap.
- Keep collection tests focused on the packaging boundary. Do not copy the
standalone pipeline role's full integration matrix.
- Run every stage's validation before committing it. Stage 3 is the sole
mechanical exception: `git subtree add` necessarily creates its provenance
commit as part of the import, so run its validation immediately afterward
and do not proceed if it fails.
- Commit each completed stage when it leaves the repository in a valid state,
using the commit intent specified by that stage. Do not push any repository.
- Do not begin a dependent stage after an earlier stage fails validation.
## Starting State and Preconditions
- The workspace planning changes for Feature 0012, including this plan, have
been reviewed and committed before execution begins.
- `ansible-workspace-dnd`, `ansible-role-dnd-pipeline`, and
`ansible-collection-dnd` begin on `main` with clean working trees.
- The standalone pipeline role begins at `de1b191cd2b6895895d3915e7b453596994127cf`.
Stage 1 will create the new reviewed commit that Stage 3 imports.
- The collection begins at `976277b03374`. It contains no role or Galaxy
metadata yet; Feature 0012 planning files belong to the independent parent
workspace repository.
- The pipeline dependency manifests select these exact application-role
commits, which the collection bootstrap manifest must preserve:
- `rakestraw.seriatim` at
`e08c63c0b078658bdfa2d10a2e6e1e4f9372a075`
- `rakestraw.audita` at
`66ebea9a47ce82bfdbdc5e2855f3dfaaff8e2a16`
- `rakestraw.notarius` at
`14a38e04e35ef524d6a97fa7fb5a04981a0a2161`
- `rakestraw.scriptorium` at
`8b4c86e48e7d8655e479b26dc510bf01683a0c8f`
- `rakestraw.narratio` at
`292d8669e7aad5cfe80b0c469d22b6177e8cf0f1`
- Collection dependencies remain `ansible.posix` 2.2.0 and
`community.general` 13.3.0.
- The workspace `.venv` provides Ansible Core 2.21.3 and ansible-lint 26.8.0.
Invoke them through `.venv/bin` rather than assuming they are on `PATH`.
- Git includes the `git subtree` command.
- The local Ubuntu 26.04 proxy host supports passwordless noninteractive
`sudo`, as required by the existing role integration suites.
- Network access is available for Galaxy dependencies and the pinned Git role
sources. Local immutable `file://` inputs from `assets/campaigns` and
`assets/narratio-prompts` remain available for integration testing.
## Repository Scope
- `ansible-role-dnd-pipeline` may change only its README to document the two
supported consumption forms. It remains authoritative for the role.
- `ansible-collection-dnd` owns Galaxy and runtime metadata, the unified
bootstrap manifest, collection documentation, build exclusions, the
squashed pipeline-role subtree, and focused collection integration tests.
- `ansible-workspace-dnd` may change only planning and status documents during
the final handoff stage.
- The five standalone application roles, both asset repositories, all
application repositories, and `rakestraw-ansible` may be inspected but must
remain unchanged.
## Stage 1: Document Standalone and Collection Consumption
### Objective
Make the authoritative pipeline role's README accurately describe both its
standalone role name and its collection FQCN before taking the collection
snapshot.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
### Preconditions
- `ansible-role-dnd-pipeline` is clean at
`de1b191cd2b6895895d3915e7b453596994127cf`.
- Feature 0012 is committed and records the standalone repository as the
authoritative role source.
### Owning Repository
`ansible-role-dnd-pipeline`
### Required Changes
1. Revise `README.md` so it no longer describes collection exposure only as a
future possibility.
2. Retain the existing standalone installation and
`rakestraw.dnd_pipeline` invocation instructions.
3. Add a concise collection-use path that names `rakestraw.dnd.pipeline` and
directs collection consumers to the collection repository's unified
bootstrap instructions. Do not duplicate the collection's complete build,
dependency, or subtree maintenance documentation here.
4. Explain that this repository remains authoritative and the collection
carries a reviewed snapshot. Do not claim that a collection release has
been published or tagged.
5. Make no changes to defaults, tasks, templates, metadata, dependency pins,
tests, or role behavior.
### Validation
Run from `ansible-role-dnd-pipeline`:
```text
git diff --check
git diff -- README.md
git status --short
```
Expected result: the diff is limited to accurate README wording, contains no
whitespace errors, preserves the standalone instructions, and introduces no
claim of an already published collection release.
### Completion Criteria
- Both role names and their distinct consumption contexts are documented.
- No executable or dependency file changed.
- The repository is ready to supply the exact commit for the subtree import.
### Commit
Commit intent: `Document standalone and collection pipeline usage`
## Stage 2: Establish the Collection Foundation
### Objective
Create the valid, buildable collection metadata, reproducible dependency
bootstrap, build policy, and operator documentation that will own the imported
role.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
### Preconditions
- Stage 1 is committed and its full pipeline-role commit hash is recorded.
- `ansible-collection-dnd` is clean at its current `main` HEAD.
- The exact application-role and collection dependency pins still match the
values in Starting State and Preconditions. Stop if a pin has changed.
### Owning Repository
`ansible-collection-dnd`
### Required Changes
1. Add `galaxy.yml` with:
- namespace `rakestraw`, name `dnd`, and development version `0.1.0`;
- `README.md`, Eric Rakestraw as author, `license: [CC0-1.0]`, a concise D&D
pipeline description, the tags `dnd`, `pipeline`, `transcript`, and
`processing`, repository URL
`https://gitea.maximumdirect.net/eric/ansible-collection-dnd.git`, and
issue URL
`https://gitea.maximumdirect.net/eric/ansible-collection-dnd/issues`;
- exact collection dependencies `ansible.posix: 2.2.0` and
`community.general: 13.3.0`; and
- `build_ignore` entries for the collection's `tests`, root `.gitignore`,
and the imported role's `.gitignore`, `ansible.cfg`, `collections`,
`requirements.yml`, and `tests` paths.
2. Add `meta/runtime.yml` with only the native runtime requirement
`requires_ansible: ">=2.18.0"` and the normal YAML document marker.
3. Add one root `requirements.yml` using Ansible's unified `roles:` and
`collections:` format. Copy the five Git sources, canonical installed role
names, and exact reviewed commit pins from the pipeline manifests. Include
the same exact two collection versions declared in `galaxy.yml`.
4. Replace the placeholder README with concise documentation covering:
- purpose, Ubuntu 26.04 support, and the `rakestraw.dnd.pipeline` FQCN;
- the unified `ansible-galaxy install -r requirements.yml` bootstrap;
- collection build and local artifact installation with `--no-deps` after
bootstrap;
- a minimal FQCN play example;
- the distinction between development commit pins and future released role
tags; and
- exact `git subtree add` and `git subtree pull --squash` maintenance
examples using `roles/pipeline` and
`https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git`.
5. Make the subtree documentation explicit that role changes originate in
`ansible-role-dnd-pipeline`; collection maintainers import a reviewed commit
and do not edit the snapshot directly.
6. Extend `.gitignore` only as needed to keep locally built `*.tar.gz`
collection artifacts untracked. The documented/tested workflow should
still build into a temporary output directory.
7. Do not create a wrapper role, placeholder role, sync script, lock file,
generated manifest, release automation, or publication configuration.
### Validation
Run from `ansible-collection-dnd`:
```text
build_dir=$(mktemp -d)
trap 'rm -rf -- "$build_dir"' EXIT
../.venv/bin/ansible-galaxy collection build --output-path "$build_dir"
test -f "$build_dir/rakestraw-dnd-0.1.0.tar.gz"
git diff --check
git status --short
```
Expected result: Ansible recognizes and builds collection version `0.1.0`
without metadata errors, the expected archive is created outside the
repository, and only the planned collection foundation files have changed.
The artifact does not yet need to contain the pipeline role.
### Completion Criteria
- The collection has valid Galaxy and runtime metadata.
- The root requirements file exactly reproduces both existing dependency
manifests in unified form.
- The README gives a complete source-consumer and maintainer workflow without
claiming a published release.
- No role code exists in or has been copied into the collection yet.
### Commit
Commit intent: `Establish the D&D collection foundation`
## Stage 3: Import the Authoritative Pipeline Role
### Objective
Create the self-contained `roles/pipeline` collection role through one
provenance-bearing squashed subtree import of the Stage 1 commit.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
### Preconditions
- Stages 1 and 2 are committed and validated.
- Both `ansible-role-dnd-pipeline` and `ansible-collection-dnd` are clean.
- `roles/pipeline` does not exist.
- The exact Stage 1 pipeline commit is available from the sibling repository.
### Owning Repository
`ansible-collection-dnd`
### Required Changes
1. From the collection repository, capture and inspect the full Stage 1
pipeline HEAD, then import exactly that commit with:
```text
pipeline_commit=$(git -C ../ansible-role-dnd-pipeline rev-parse HEAD)
git subtree add --prefix=roles/pipeline ../ansible-role-dnd-pipeline "$pipeline_commit" --squash
```
2. Retain the standard subtree-generated provenance commit and trailers. Do
not replace the import with a manual copy, submodule, symbolic link, wrapper
role, or custom synchronization record.
3. Do not edit, remove, or reformat any file beneath `roles/pipeline`. Files
excluded from the built artifact remain in source so the imported snapshot
stays faithful to the authoritative repository.
4. Do not change collection-owned metadata merely to hide an unexpected import
result. Stop and report a mismatch between the roadmap, Stage 2 build policy,
and the actual role source.
### Validation
Run from `ansible-collection-dnd` immediately after the subtree command:
```text
diff -ru --exclude=.git ../ansible-role-dnd-pipeline roles/pipeline
../.venv/bin/python -c 'import pathlib, yaml; root = yaml.safe_load(pathlib.Path("requirements.yml").read_text()); role = yaml.safe_load(pathlib.Path("roles/pipeline/requirements.yml").read_text()); collections = yaml.safe_load(pathlib.Path("roles/pipeline/collections/requirements.yml").read_text()); assert root["roles"] == role["roles"]; assert root["collections"] == collections["collections"]'
build_dir=$(mktemp -d)
trap 'rm -rf -- "$build_dir"' EXIT
../.venv/bin/ansible-galaxy collection build --output-path "$build_dir"
tar -tf "$build_dir/rakestraw-dnd-0.1.0.tar.gz" > "$build_dir/files.txt"
grep -Fx 'roles/pipeline/tasks/main.yml' "$build_dir/files.txt"
! grep -Eq '^roles/pipeline/(tests/|ansible.cfg$|collections/|requirements.yml$|\.gitignore$)' "$build_dir/files.txt"
git status --short
git log -2 --format=fuller
```
Expected result: source and imported role trees are byte-for-byte equivalent
apart from Git metadata; both dependency sections match their authoritative
pipeline manifests; the archive contains the pipeline task entry point but no
imported development fixtures or nested manifests; and Git records the
standard squashed subtree provenance. The collection working tree is clean
because the subtree command created the import commit.
### Completion Criteria
- `roles/pipeline` is an exact snapshot of the Stage 1 pipeline commit.
- The collection artifact is self-contained for the pipeline role.
- Build exclusions affect only the artifact and have not mutated the source
snapshot.
- The dependency bootstrap remains consistent with the imported role.
### Commit
Commit intent: retain the standard commit created by `git subtree add`; do not
create a second manual import commit.
## Stage 4: Validate the Installed Collection Boundary
### Objective
Add one lean integration path that proves the built artifact, unified
dependency bootstrap, FQCN resolution, representative native configuration,
and clean repeated convergence.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
- `docs/testing.md`
### Preconditions
- Stage 3 is committed and validated.
- `ansible-collection-dnd` is clean.
- The workspace `.venv`, passwordless `sudo`, and both local asset
repositories are available.
- No developer-global Ansible installation may satisfy the test's role or
collection dependencies.
### Owning Repository
`ansible-collection-dnd`
### Required Changes
1. Add `tests/inventory` for local connection and `tests/converge.yml` whose
only role invocation is `rakestraw.dnd.pipeline`.
2. Add an executable `tests/integration` shell driver consistent with the
standalone role repositories. It must:
- use `set -euo pipefail`, locate the repository and workspace `.venv`
without assuming the caller's working directory, and create one private
`mktemp -d` root with cleanup on exit;
- set `ANSIBLE_ROLES_PATH` and `ANSIBLE_COLLECTIONS_PATH` exclusively to
directories beneath that temporary root, without appending the workspace,
sibling repositories, or user-global paths;
- run the unified `ansible-galaxy install -r requirements.yml` with those
environment paths so both dependency sections are exercised;
- build `rakestraw-dnd-0.1.0.tar.gz` into the temporary root and install that
artifact into the isolated collection path with `--no-deps` because the
unified bootstrap has already installed its exact dependencies;
- confirm the archive includes the pipeline task entry point and excludes
the development-only subtree paths selected in `build_ignore`;
- run syntax checking and production-profile ansible-lint against
`tests/converge.yml` only after the isolated dependencies and artifact are
installed;
- derive immutable local asset revisions from `assets/campaigns` and
`assets/narratio-prompts`, pass their `file://` URLs and revisions through
the pipeline's public variables, and use the same syntactically valid
local WhisperX URL and distinctive synthetic credential values as the
standalone suite;
- apply the collection role without contacting WhisperX or any model
provider;
- use the installed applications' native interfaces for one representative
assembled validation: Seriatim reports a version, Audita validates its
configuration, Notarius validates `dnd-session`, Scriptorium resolves a
deployed prompt or profile through its configured roots, and Narratio
validates one deployed campaign;
- immediately apply the identical play and variables a second time, capture
its play recap, and require `changed=0` and `failed=0`; and
- remove only its temporary root during cleanup.
3. Keep the test at this packaging boundary. Do not add alternate-version,
mapping-composition, invalid-secret, human-operator, ACL, profile-matrix,
or exhaustive artifact tests already owned by the standalone suite.
4. Do not assert current default values, task names or order, individual task
results, module behavior, complete rendered files, or exact manifest
contents. The small archive inclusion/exclusion check is permitted because
packaged content is behavior owned specifically by this feature.
5. Do not place real credentials in the test, logs, inventory, or repository.
Native configuration checks must remain offline.
### Validation
Run from the workspace root:
```text
bash -n ansible-collection-dnd/tests/integration
ansible-collection-dnd/tests/integration
ansible-role-dnd-pipeline/tests/integration
git -C ansible-collection-dnd diff --check
git -C ansible-role-dnd-pipeline status --short
```
Expected result: the collection driver builds and installs only the declared
artifact and dependencies into isolated paths, resolves the FQCN, passes every
native application check, and reports a clean immediate repeat. The existing
standalone suite also passes, and the authoritative pipeline repository
remains clean after testing.
### Completion Criteria
- The source collection cannot accidentally satisfy its own FQCN or
dependencies through workspace or user-global Ansible paths.
- One representative installed-artifact deployment and every selected native
check pass without external service calls.
- The repeat application reports `changed=0` and `failed=0`.
- The standalone pipeline integration suite remains green.
- The test suite contains no implementation snapshots or duplicated feature
matrix.
### Commit
Commit intent: `Test the assembled D&D collection`
## Stage 5: Record the Implementation Handoff
### Objective
Record the completed implementation stages and leave every changed repository
clean for independent review without marking the feature complete.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/planning.md`
### Preconditions
- Stages 1 through 4 are committed and all validation has passed.
- `ansible-role-dnd-pipeline` and `ansible-collection-dnd` are clean.
- Full commit hashes for every implementation commit, including the subtree
provenance commit, have been recorded.
### Owning Repository
`ansible-workspace-dnd`
### Required Changes
1. Change Feature 0012's roadmap status from `ready` to `in_progress`; do not
mark it `done` before independent review.
2. Update `docs/status.md` so M1-04 and F0012 remain `in_progress`, the current
focus is independent implementation review, and the evidence names the
resulting pipeline and collection commit hashes.
3. Replace this document's Progress Notes placeholder with one concise entry
per completed stage, including repository and commit hash. Record any
deviation from the plan; write `none` if there were no deviations.
4. Do not create or modify `docs/roadmap/remediation.md`; independent review
owns remediation findings.
### Validation
Run from the workspace root:
```text
git diff --check
./scripts/status
git status --short
git -C ansible-role-dnd-pipeline status --short
git -C ansible-collection-dnd status --short
```
Expected result: only the intended workspace progress documents are pending in
the parent repository; both implementation repositories are clean; status
points reviewers to concrete commits; and the feature remains `in_progress`.
### Completion Criteria
- Every stage and deviation is recorded concisely.
- Workspace status requests independent review and does not claim completion.
- No remediation document was preemptively created.
- The workspace change is ready for its own commit.
### Commit
Commit intent: `Record the Feature 0012 implementation`
## Final Validation and Handoff
- Confirm the successful Stage 4 logs include collection build and isolated
installation, FQCN syntax resolution, every selected native application
check, and the clean repeat recap.
- Run `./scripts/status` and confirm the workspace,
`ansible-role-dnd-pipeline`, and `ansible-collection-dnd` are clean after the
Stage 5 commit. All repositories outside those three must remain unchanged.
- Report the Stage 1 pipeline commit, the Stage 2 collection foundation commit,
the Stage 3 subtree import commit, the Stage 4 collection test commit, and
the Stage 5 workspace handoff commit.
- Summarize any deviations, unresolved findings, and deferred release work.
- Report any implementation complexity beyond native collection metadata, one
unified requirements manifest, the standard subtree import, and the focused
integration driver, together with the acceptance criterion that required it.
- Do not push commits and do not mark Feature 0012 `done`; implementation
results require independent review first.
## Progress Notes
No stages have been executed.

View File

@@ -106,6 +106,13 @@ role will manage the native configuration needed to connect to it.
- The collection bundles and exposes the independently developed suite-level
role as `rakestraw.dnd.pipeline`, providing one opinionated interface for
consumers.
- The collection incorporates the pipeline role at `roles/pipeline` as a
squashed Git subtree. The standalone pipeline repository remains
authoritative; maintainers change and validate the role there, then import
a reviewed commit into the collection rather than editing the subtree copy.
- The subtree makes the collection artifact self-contained for its bundled
role without requiring submodule initialization, symbolic links, sibling
repositories, or custom synchronization tooling.
- The pipeline role owns compatible application-version selection,
cross-application configuration, D&D campaign deployment, prompt-library
deployment, operator access, the pipeline-wide secret-delivery policy, and
@@ -135,6 +142,10 @@ role will manage the native configuration needed to connect to it.
collection dependencies. During active development, the Git roles are
pinned to reviewed commits; released manifests replace those commits with
immutable role release tags.
- The collection supplies one consumer-facing root `requirements.yml` that
combines those same Git-hosted role pins with the shared collection
dependencies. Its Galaxy metadata separately declares the native collection
dependencies that Ansible can resolve while installing a collection.
- The pipeline role composes the five roles through ordinary Ansible role
dependency metadata. It exposes suite-prefixed variables for the small set
of values the suite must coordinate, and does not duplicate every downstream
@@ -179,6 +190,11 @@ application-role releases in one source repository.
- Collection integration tests must install and exercise the same pinned role
combination delivered to consumers, starting from an environment in which
the dependencies are not already installed.
- Collection integration tests build and install the collection artifact into
isolated Ansible paths, resolve `rakestraw.dnd.pipeline`, validate one
representative assembled deployment through native application interfaces,
and confirm immediate convergence. Detailed pipeline feature matrices remain
the standalone pipeline role's testing responsibility.
- Updating one application role in the suite requires updating its pinned
version in the collection, validating the assembled suite, and releasing a
new collection version. Unrelated application-role repositories remain
@@ -396,9 +412,5 @@ managed host. The prompt-library checkout retains its upstream `prompts/` and
The following areas require investigation and decisions before implementation:
- The mechanism used to incorporate the independently developed pipeline role
into collection releases
- Optional suite-level operator-selection and group-membership management
- Upgrade, downgrade, and removal behavior
- Collection bootstrap and end-to-end validation details beyond the locked
dependency and testing policies above

View File

@@ -1,10 +1,10 @@
# Workspace Status
Last updated: 2026-09-16
Last updated: 2026-09-17
Current milestone: M1-04 collection assembly
Current focus: Select the next unit of work; collection assembly is proposed.
Current focus: Review the Feature 0012 staged implementation plan.
| ID | Deliverable | Owner | State | Evidence or next step |
| --- | --- | --- | --- | --- |
@@ -16,7 +16,7 @@ Current focus: Select the next unit of work; collection assembly is proposed.
| M1-01 | Remaining MVP design decisions | workspace | done | Feature 0003 roadmap fixes the Notarius configuration interface |
| M1-02 | Standalone application roles | role repositories | done | All five standalone roles implemented and independently reviewed |
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | done | Features 0006 through 0011 completed through remediation commit `de1b191` |
| M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism |
| M1-04 | Collection assembly | ansible-collection-dnd | in_progress | Review Feature 0012 and prepare its implementation plan |
| F0001 | Install Seriatim from pinned source | ansible-role-seriatim | done | Implementation, integration coverage, and final remediation completed through `fb8dc41` |
| F0002 | Install and configure Audita | ansible-role-audita | done | Field-specific configuration completed in `e61f02f` and `847c4c3`; full suite passed |
| F0003 | Install and configure Notarius | ansible-role-notarius | done | Implemented and validated through remediation commit `eb4f511` |
@@ -28,6 +28,7 @@ Current focus: Select the next unit of work; collection assembly is proposed.
| F0009 | Establish shared pipeline filesystem and execution | configuration-bearing application roles and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `b15fe8d` |
| 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 | ready | Review `docs/roadmap/implementation.md`, then begin the implementation sprint |
| 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 |