diff --git a/docs/roadmap/features/0012-collection-assembly.md b/docs/roadmap/features/0012-collection-assembly.md index 2071fb4..cef0c5c 100644 --- a/docs/roadmap/features/0012-collection-assembly.md +++ b/docs/roadmap/features/0012-collection-assembly.md @@ -1,6 +1,6 @@ # Feature 0012: Assemble the D&D Collection -Status: in_progress +Status: done ## Summary diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index e9a6875..bb7bdee 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,577 +1,8 @@ -# Implementation Plan 0012: Assemble the D&D Collection +# Implementation Plan -Status: proposed +Status: pending -Target executor: GPT-5.6-Terra +Feature 0012 is complete. There is no active 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 - -- Stage 1 complete: `ansible-role-dnd-pipeline` - `600eb21cd967831607c087f1773063636ff2c31b` documents standalone and - collection consumption without changing role behavior. -- Stage 2 complete: `ansible-collection-dnd` - `3f7f82e40f63ee19e883052822c34dc806d8d51f` establishes buildable Galaxy - metadata, unified pinned dependencies, build exclusions, and source-use and - subtree-maintenance documentation. -- Stage 3 complete: `ansible-collection-dnd` - `c84aa0db8feda65ac66af07bc53976a23a016486` imports pipeline commit - `600eb21cd967831607c087f1773063636ff2c31b` as an exact squashed subtree - snapshot at `roles/pipeline`. -- Stage 4 complete: `ansible-collection-dnd` - `10ad31c176b50a64dc30e4aae81167b359359ffe` adds an isolated installed-artifact - integration path; both the collection test and standalone pipeline suite - pass. -- Stage 5 complete: `ansible-workspace-dnd` - `b359eee3216f6944e707a6c8c76c26d2ae99b65c` records the implementation - evidence and leaves Feature 0012 `in_progress` for independent review. -- Deviations: none. +Select the next unit of work and agree on its numbered feature roadmap before +replacing this notice with a staged implementation plan. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index e160298..bf7f896 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -1,149 +1,173 @@ -# Feature 0011 Remediation Review +# Feature 0012 Remediation Review Status: resolved Reviewed implementation commits: -- `292d866 Upgrade the Narratio role to version 2.1.0` -- `28a4d27 Add managed credentials to the D&D pipeline` -- `8ff0761 Document and test pipeline credential delivery` +- `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` ## Review Summary -Feature 0011 implements the principal target architecture. The standalone -Narratio role now installs v2.1.0 and generically exposes its three native -Notarius controls. The pipeline pins that role revision, manages a restricted -conventional secrets directory, coordinates the Audita and Notarius credential -references, and enables ordinary Notarius checkpoint reuse without duplicating -the root-owned chunk-cache policy. Both complete integration entry points pass, -including native application validation and immediate clean repeats. +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`. -Two issues remain. First, the feature roadmap and implementation plan -strengthened the requested credential-delivery interface with deletion and -empty-value policies that were not required. The implementation consequently -contains an extra production task and substantial test and documentation -machinery for those invented semantics. Second, the pipeline README does not -explain the Scriptorium credential flow that the feature roadmap expressly -requires it to document. +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. -## Finding 1: The Credential Mapping Adds Unrequested Lifecycle Semantics - -Severity: moderate - -The user requested an inventory-friendly way to deliver credential values to -Narratio's conventional secrets directory. The roadmap subsequently added two -stronger behaviors without an express requirement: null means delete an exact -file, and an empty string must be rejected by the role. Those choices were -then made mandatory by the implementation plan. - -The resulting production implementation appears in -`ansible-role-dnd-pipeline/tasks/main.yml:10-53`. It validates the stronger -value policy, conditionally copies non-null entries, and uses a separate file -loop to delete null entries. The public contract and example are repeated in -`ansible-role-dnd-pipeline/README.md:275-291`, while -`ansible-role-dnd-pipeline/tests/integration:167-194` adds an empty-value -failure case and a multi-convergence deletion lifecycle. - -The environment-variable-name validation is justified because caller input -becomes a destination path. The two value semantics are different: they add -credential lifecycle and application-validity guarantees that the role was -not asked to own. ConfigKit accepts an empty immediate credential file and -performs its own nonempty check only when a configured typed reference resolves -to that value. A simple delivery role should write the caller-supplied string -and trust the native application boundary. Credential deletion can be added -later if an operator-facing removal contract is expressly requested. - -### Required Remediation - -- Narrow `dnd_pipeline_secrets` to an empty-by-default mapping from valid - environment-variable names to string file contents. -- Retain complete key validation before path construction and retain - `no_log: true` for every task that evaluates or writes credential values. -- Validate that values are strings, but do not add a nonempty policy that is - stricter than the native bootstrap and typed-reference boundary. -- Converge every supplied entry directly with one `ansible.builtin.copy` loop. - Remove the null condition and the separate deletion task. -- Treat omitted keys as unmanaged. Do not invent a replacement deletion, - purge, directory-mirroring, or credential-validation mechanism. -- Remove the empty-value and explicit-null lifecycle cases from the integration - suite. Retain the valid-name boundary case, representative credential - delivery, redaction checks, authorized native loading, and immediate clean - repeat. -- Correct the Feature 0011 roadmap, the settled MVP text, and the pipeline - README so they describe the narrower interface and no longer present the - strengthened semantics as user decisions. - -## Finding 2: Scriptorium Credential Delivery Is Not Documented for Consumers +## Finding 1: Subtree Maintenance Commands Mix Local and Remote Sources Severity: low -The Feature 0011 roadmap requires documentation of all application credential -flows, including Scriptorium's existing profile-owned `api_key_env` selection. -`ansible-role-dnd-pipeline/README.md:275-291` explains the generic mapping and -the earlier Notarius section explains its typed reference, but the README never -tells an operator how a selected Scriptorium profile obtains its credential. +`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. -Production behavior is already correct: Narratio bootstraps the named file into -its environment and its existing Scriptorium adapter forwards the selected -profile credential. This is a documentation gap, not a request for another -variable, task, or integration test. +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. ### Required Remediation -- Add a concise consumer-facing explanation that a Scriptorium profile remains - the owner of its `api_key_env` name. -- Explain that an operator can add a matching filename/value entry to - `dnd_pipeline_secrets`; Narratio's bootstrap supplies it and the existing - adapter forwards only the profile-selected credential. -- Do not add a suite-specific Scriptorium credential variable, inspect profile - files in Ansible, duplicate the application adapter, or add tests of - Narratio/Scriptorium internals. +- 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. + +## Finding 2: The Collection Test Duplicates Secret-Redaction Coverage + +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 pipeline-role commit `de1b191`. The credential mapping now accepts -valid environment-variable names with string contents, validates the complete -mapping before path construction, and converges every supplied entry through -one secret-safe `ansible.builtin.copy` loop. The unrequested empty-value policy, -null deletion task, and associated lifecycle tests were removed. Omitted names -remain unmanaged. +Resolved in collection commits `556b6ed` and `da67b34`. -The pipeline README now explains how a Scriptorium profile's application-owned -`api_key_env` name selects a matching `dnd_pipeline_secrets` entry without -adding another suite variable or duplicating adapter behavior. The durable -Feature 0011 roadmap and MVP policy were corrected to record the narrower -operator-facing contract. +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 -Remediation validation: +After remediation, run: ```text -cd ansible-role-dnd-pipeline && tests/integration +cd ansible-collection-dnd +bash -n tests/integration +tests/integration git diff --check ``` -The result was successful syntax and lint validation; synthetic -credential delivery through the conventional directory; native Narratio -configuration loading for authorized identities; absence of synthetic values -from captured output; preservation of Notarius resume and root-owned `auto` -chunk caching; and immediate repeats with `changed=0` and `failed=0`. +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. + +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. ## Review Validation Evidence -The review inspected the exact implementation diffs and confirmed that the -Narratio dependency pin resolves to the reviewed `292d866` revision. The -standalone Narratio `tests/integration` entry point passed with v2.1.0 native -configuration validation and clean repeats. The complete pipeline -`tests/integration` entry point also passed, including isolated dependency -installation, syntax checking, production-profile lint, authorized and denied -native loading, redaction checks, profile and version selections, and clean -repeats. No live model, transcription, storage, or publishing endpoint was -contacted. +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. -After remediation, the complete pipeline integration entry point passed again. -It exercised isolated dependency installation, the invalid-name boundary, -synthetic credential delivery and redaction, authorized native loading, -Notarius resume and root-owned `auto` chunk caching, the retained profile and -version selections, and immediate clean repeats. `git diff --check` also -passed before the remediation commit. +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. diff --git a/docs/status.md b/docs/status.md index a75de1d..5e38c58 100644 --- a/docs/status.md +++ b/docs/status.md @@ -2,9 +2,9 @@ Last updated: 2026-09-17 -Current milestone: M1-04 collection assembly +Current milestone: Initial role and collection architecture complete -Current focus: Independently review the Feature 0012 implementation. +Current focus: Select the next unit of work. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -16,7 +16,7 @@ Current focus: Independently review the Feature 0012 implementation. | 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 | in_progress | Implementation is ready for independent review: pipeline `600eb21`, collection `10ad31c` | +| M1-04 | Collection assembly | ansible-collection-dnd | done | Implemented and independently reviewed through collection remediation commit `da67b34` | | 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,7 +28,7 @@ Current focus: Independently review the Feature 0012 implementation. | 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 | in_progress | Review pipeline `600eb21` and collection foundation, subtree, and test commits `3f7f82e`, `c84aa0d`, and `10ad31c` | +| 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` | | 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 |