diff --git a/docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md b/docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md index a2a1015..64f26e0 100644 --- a/docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md +++ b/docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md @@ -1,6 +1,6 @@ # Feature 0009: Shared Pipeline Filesystem and Execution -Status: proposed +Status: ready ## Summary diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index b5cd9af..6d3208c 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,13 +1,849 @@ -# Implementation Plan +# Implementation Plan 0009: Shared Pipeline Filesystem and Execution -Status: pending +Status: ready -No implementation plan is currently active. Feature 0008 was implemented, -independently reviewed, and completed through pipeline-role remediation commit -`3e253d7`. Its durable scope, decisions, and acceptance criteria remain in -[Feature 0008](features/0008-opinionated-dnd-processing-configuration.md), and -the completed review record remains in [the remediation -document](remediation.md). +Target executor: GPT-5.6-Terra -Select and approve the next feature roadmap before replacing this notice with -a new staged implementation plan. +Feature roadmap: +`docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` + +Active plan location: `docs/roadmap/implementation.md` + +## Objective + +Give each configuration-bearing standalone role a small, generic ownership +and mode interface, then have the D&D pipeline role select the suite's +`narratio:narratio` and world-readable configuration policy through those +interfaces. Establish setgid and default-ACL behavior on the three existing +Narratio writable roots so the service account and an existing human member of +the shared group can safely use the same state. + +The feature roadmap remains authoritative for scope, rationale, target end +state, and acceptance criteria. Decision 0002 remains authoritative for the +shared-readable filesystem boundary. + +## Execution Rules + +- Execute stages in numeric order. +- Before each stage, confirm its preconditions and the working-tree state of + its owning repository. +- Before each stage, reread every document listed in that stage's Required + Policy Review. Do not rely on policy recalled from an earlier stage. +- Preserve unrelated and pre-existing changes. Stop if an owning repository is + unexpectedly dirty at a stage boundary. +- Keep standalone roles independently useful. They expose generic owner, + group, directory-mode, and file-mode controls; only the pipeline role selects + `narratio:narratio`, `0755`, and `0644` as D&D suite policy. +- Change only the existing directory and template operations that own + configuration. Do not add corrective permission passes, preliminary + `stat` calls, handlers, validation tasks, checksums, manifests, or + role-private state. +- Trust `ansible.builtin.file`, `ansible.builtin.template`, + `ansible.builtin.apt`, and `ansible.posix.acl` to converge their documented + state. Apply `become: true` only to tasks that require it. +- Keep source checkouts, installed binaries, campaign assets, and prompt + assets outside the new configuration ownership interface. +- Do not create a `secrets/` directory, deliver credentials, select human + operators, alter an existing human account's group membership in production, + or recursively rewrite existing runtime descendants. +- Use `ansible.posix` version `2.2.0`, the current stable release selected for + this plan. Do not substitute another collection or version during execution. +- Test the public operating contract through native application use and actual + cross-identity read/write behavior. Do not assert task order, module results, + exact default values, or filesystem metadata merely to restate module + arguments. +- Run every stage's validation before committing it. Commit each completed + stage when it leaves the owning repository valid, using the plain-English + commit intent specified by that stage. +- Do not begin a dependent stage after an earlier stage fails validation. +- Do not push during implementation. Before Stage 5, the commits produced by + Stages 1 through 4 must nevertheless be reachable from their canonical Git + origins so the pipeline's isolated dependency installation can consume exact + immutable revisions. If they are not reachable, stop after Stage 4 and + report the four hashes for publication rather than weakening the dependency + test or using branch references. + +## Starting State and Preconditions + +- The workspace control repository contains the committed Feature 0009 + roadmap, Decision 0002, and settled MVP filesystem policy at `a7d7189` or a + reviewed descendant. +- Features 0001 through 0008 and the standalone-role test-suite simplification + are complete. +- The following implementation repositories are clean on `main` at these + reviewed starting commits: + + | Repository | Starting commit | + | --- | --- | + | `ansible-role-audita` | `d2d0b9d00b3b491ce7613ccfc8f686f3d1fa0896` | + | `ansible-role-notarius` | `cfecf37261f2595d45113235c591ee102d6f181f` | + | `ansible-role-scriptorium` | `8f47aa802a5e0c9dae9c0f43a1c70b3512b2c8b2` | + | `ansible-role-narratio` | `7feff4728a5968b6b1dd87e83add9fa1a9066b18` | + | `ansible-role-dnd-pipeline` | `3e253d714d0e242f2bcb25e1552d3f8511004d85` | + +- The four standalone-role starting commits match `origin/main`. The pipeline + starting commit is local and may be ahead of `origin/main`; this is expected + and must not be reset or replaced. +- The workspace `.venv` provides Ansible Core 2.21.3 and ansible-lint 26.8.0. +- The integration host is an accepted Ubuntu 26.04 proxy, supports task-level + privilege escalation, and provides ordinary POSIX ACL support. +- `ansible.posix` 2.2.0 supports Ansible Core 2.16 or newer and supplies the + `ansible.posix.acl` module used by this feature. +- Notarius remains at the Feature 0008-compatible release during this feature. + Its v0.7.0 upgrade, ConfigKit import interface, D&D pipeline, and cache root + belong to Feature 0010. + +## Repository Scope + +Repositories that change: + +- `ansible-role-audita`: generic Audita configuration ownership and mode + interface, argument specification, tasks, and consumer documentation. +- `ansible-role-notarius`: generic Notarius configuration ownership and mode + interface, argument specification, tasks, and consumer documentation. +- `ansible-role-scriptorium`: generic Scriptorium configuration ownership and + mode interface, argument specification, tasks, and consumer documentation. +- `ansible-role-narratio`: generic Narratio configuration ownership and mode + interface, argument specification, tasks, and consumer documentation. +- `ansible-role-dnd-pipeline`: dependency order and pins, suite identity and + configuration policy, ACL dependency and convergence, focused integration + coverage, and consumer documentation. + +Repositories that may be inspected but must remain unchanged: + +- `ansible-role-seriatim`, which owns no application configuration file. +- `ansible-collection-dnd`, whose assembly remains later work. +- `../{audita,notarius,scriptorium,narratio,seriatim}`, which remain the + read-only application authorities. +- `assets/campaigns`, `assets/narratio-prompts`, and `assets/configs`. +- `rakestraw-ansible` and every other repository in `workspace.yml`. +- The workspace control repository during implementation stages. It is updated + only before or after the sprint for planning and progress management. + +## Stage 1: Expose Audita Configuration Ownership + +### Objective + +Make Audita's managed configuration ownership and modes configurable while +preserving its current standalone installation as the default. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-audita/defaults/main.yml` +- `ansible-role-audita/meta/argument_specs.yml` +- `ansible-role-audita/tasks/main.yml` +- `ansible-role-audita/tests/integration` +- `ansible-role-audita/README.md` + +### Preconditions + +- `ansible-role-audita` is clean at the stated starting commit. +- Its existing integration suite passes before modification. + +### Owning Repository + +`ansible-role-audita` + +### Required Changes + +1. Add these required, defaulted public variables: + `audita_config_owner: root`, `audita_config_group: root`, + `audita_config_directory_mode: "0755"`, and + `audita_config_file_mode: "0644"`. +2. Add matching string entries to `meta/argument_specs.yml`, with descriptions + that distinguish the configuration directory mode from the managed file + mode. +3. Keep source and binary parent directories `root:root` mode `0755`. Manage + `audita_config_path | dirname` directly with the four configuration inputs, + either by giving it a distinct declarative file task or by using an equally + clear existing loop shape. +4. Replace the template task's hard-coded owner, group, and mode with the new + variables. Do not add a follow-up file task, state inspection, or other task + flow. +5. Document all four variables and their standalone defaults in the README. + Explain that composing roles may override them; do not introduce D&D policy + into this role. +6. Keep the existing focused integration suite and clean-repeat contract. Do + not add metadata assertions or a test whose only purpose is to prove that + `file` or `template` honored its arguments. + +### Validation + +Run from `ansible-role-audita`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: syntax and lint pass, Audita natively validates its managed +configuration, every existing representative behavior remains valid, the +immediate repeat reports `changed=0` and `failed=0`, and only intended Audita +role files are modified. + +### Completion Criteria + +- The four public inputs, argument specification, directory operation, + template operation, and README agree. +- The default standalone result remains `root:root`, `0755` for the directory, + and `0644` for the file. +- No new production task exists solely to inspect or repair module-managed + state. + +### Commit + +Commit intent: `Make Audita configuration ownership configurable` + +## Stage 2: Expose Notarius Configuration Ownership + +### Objective + +Make Notarius's managed configuration ownership and modes configurable while +leaving its application version and configuration schema unchanged for Feature +0010. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-notarius/defaults/main.yml` +- `ansible-role-notarius/meta/argument_specs.yml` +- `ansible-role-notarius/tasks/main.yml` +- `ansible-role-notarius/tests/integration` +- `ansible-role-notarius/README.md` + +### Preconditions + +- Stage 1 is committed and validated. +- `ansible-role-notarius` is clean at the stated starting commit. +- Its existing integration suite passes before modification. + +### Owning Repository + +`ansible-role-notarius` + +### Required Changes + +1. Add `notarius_config_owner: root`, `notarius_config_group: root`, + `notarius_config_directory_mode: "0755"`, and + `notarius_config_file_mode: "0644"` as required, defaulted public inputs. +2. Add matching string argument-specification entries. +3. Keep source and binary parents under the existing `root:root` mode `0755` + policy. Apply the new inputs directly when managing + `notarius_config_path | dirname`. +4. Use the same inputs directly in the existing configuration template task. + Do not add permission-repair tasks, inspection, handlers, or validation to + production convergence. +5. Document the interface and standalone defaults without mentioning the D&D + cache, ConfigKit imports, Notarius v0.7.0, or any other Feature 0010 work. +6. Retain the existing native and clean-repeat integration behavior without + adding filesystem metadata assertions or tests of trusted modules. + +### Validation + +Run from `ansible-role-notarius`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: syntax and lint pass, the current Notarius configuration and +explicit version-selection cases remain natively valid, all immediate repeats +remain clean, and only intended Notarius role files are modified. + +### Completion Criteria + +- The generic four-variable interface is complete and documented. +- Existing version, schema, cache, and pipeline behavior is unchanged. +- Standalone defaults remain `root:root`, `0755`, and `0644`. +- Production convergence contains no redundant permission machinery. + +### Commit + +Commit intent: `Make Notarius configuration ownership configurable` + +## Stage 3: Expose Scriptorium Configuration Ownership + +### Objective + +Make Scriptorium's managed configuration ownership and modes configurable while +preserving its current generic standalone behavior. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-scriptorium/defaults/main.yml` +- `ansible-role-scriptorium/meta/argument_specs.yml` +- `ansible-role-scriptorium/tasks/main.yml` +- `ansible-role-scriptorium/tests/integration` +- `ansible-role-scriptorium/README.md` + +### Preconditions + +- Stages 1 and 2 are committed and validated. +- `ansible-role-scriptorium` is clean at the stated starting commit. +- Its existing integration suite passes before modification. + +### Owning Repository + +`ansible-role-scriptorium` + +### Required Changes + +1. Add `scriptorium_config_owner: root`, `scriptorium_config_group: root`, + `scriptorium_config_directory_mode: "0755"`, and + `scriptorium_config_file_mode: "0644"` as required, defaulted public + variables. +2. Add the matching string argument-specification entries. +3. Leave source and binary parent policy unchanged. Apply the new variables + directly to the operation that creates + `scriptorium_config_path | dirname`. +4. Replace the template task's fixed configuration metadata with the new + variables. Do not add a second convergence pass or preliminary inspection. +5. Document the generic interface and standalone defaults. Do not add Narratio + or D&D assumptions to this reusable role. +6. Keep the existing native profile-inspection and clean-repeat suite focused; + do not add file metadata checks. + +### Validation + +Run from `ansible-role-scriptorium`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: syntax and lint pass, representative native Scriptorium +inspection remains successful, the immediate repeats report `changed=0` and +`failed=0`, and only intended Scriptorium role files are modified. + +### Completion Criteria + +- Defaults, argument specification, tasks, and README expose one coherent + generic ownership interface. +- Standalone configuration remains `root:root`, directory mode `0755`, and + file mode `0644` by default. +- No new task or test merely re-proves trusted module behavior. + +### Commit + +Commit intent: `Make Scriptorium configuration ownership configurable` + +## Stage 4: Expose Narratio Configuration Ownership + +### Objective + +Separate Narratio's generic configuration-file policy from its runtime identity +and writable-root policy, preserving the current standalone defaults while +allowing a composing role to make configuration service-owned. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-narratio/defaults/main.yml` +- `ansible-role-narratio/meta/argument_specs.yml` +- `ansible-role-narratio/tasks/main.yml` +- `ansible-role-narratio/tests/integration` +- `ansible-role-narratio/README.md` + +### Preconditions + +- Stages 1 through 3 are committed and validated. +- `ansible-role-narratio` is clean at the stated starting commit. +- Its existing integration suite passes before modification. + +### Owning Repository + +`ansible-role-narratio` + +### Required Changes + +1. Add `narratio_config_owner: root`, + `narratio_config_group: "{{ narratio_group }}"`, + `narratio_config_directory_mode: "0750"`, and + `narratio_config_file_mode: "0640"` as required, defaulted public inputs. + The group default deliberately follows the role's existing configurable + service group. +2. Add matching string argument-specification entries. +3. Use the four variables directly in the existing configuration-directory + and pipeline-template tasks. +4. Do not change creation of `narratio_user` or `narratio_group`, the three + mutable Narratio roots, the campaign registry root, source checkout, binary, + application fields, or task ordering. +5. Document the new interface and its standalone relationship to + `narratio_group`. Make clear that configuration ownership is independent of + writable runtime-root ownership. +6. Retain the existing native validation, representative configuration, and + immediate clean-repeat behavior. Do not add metadata assertions. + +### Validation + +Run from `ansible-role-narratio`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: syntax and lint pass, Narratio natively validates baseline and +representative configurations as its service account, all immediate repeats +are clean, and only intended Narratio role files are modified. + +### Completion Criteria + +- The configuration interface defaults to the prior standalone result: + `root:{{ narratio_group }}`, directory mode `0750`, and file mode `0640`. +- Runtime identity and mutable-root behavior remain unchanged. +- Configuration directory and template tasks are the sole production owners of + their respective metadata. + +### Commit + +Commit intent: `Make Narratio configuration ownership configurable` + +## Stage 5: Apply the Suite Configuration Ownership Policy + +### Objective + +Make Narratio establish the selected runtime identity first, then use the four +standalone interfaces to converge every application configuration and +pipeline-owned Narratio fragment under the D&D suite policy. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- the four standalone-role commits produced by Stages 1 through 4 +- `ansible-role-dnd-pipeline/defaults/main.yml` +- `ansible-role-dnd-pipeline/meta/argument_specs.yml` +- `ansible-role-dnd-pipeline/meta/main.yml` +- `ansible-role-dnd-pipeline/requirements.yml` +- `ansible-role-dnd-pipeline/tasks/main.yml` +- `ansible-role-dnd-pipeline/tests/integration` + +### Preconditions + +- Stages 1 through 4 are committed, validated, and otherwise clean. +- Each new standalone-role commit is reachable from its canonical origin. Stop + and report the hashes if a fresh Git or Galaxy fetch cannot resolve them. +- `ansible-role-dnd-pipeline` is clean at its stated starting commit or an + expected reviewed descendant. +- The existing pipeline integration suite passes before modification. + +### Owning Repository + +`ansible-role-dnd-pipeline` + +### Required Changes + +1. Add the required suite defaults and matching argument-specification entries: + `dnd_pipeline_runtime_user: narratio`, + `dnd_pipeline_runtime_group: narratio`, + `dnd_pipeline_config_directory_mode: "0755"`, and + `dnd_pipeline_config_file_mode: "0644"`. +2. Reorder `meta/main.yml` so `rakestraw.narratio` is the first dependency and + therefore creates the selected service account and group before any other + configuration-bearing role uses them. Preserve the remaining dependency + roles and all existing application wiring. +3. Pass the runtime user and group to `narratio_user` and `narratio_group`. + Pass the runtime user, runtime group, suite directory mode, and suite file + mode to the four new `narratio_config_*` variables. +4. Pass the same four suite values to the corresponding `audita_config_*`, + `notarius_config_*`, and `scriptorium_config_*` variables. Do not apply a + corrective ownership task after a dependency completes. +5. Update `requirements.yml` to pin the Audita, Notarius, Scriptorium, and + Narratio dependencies to the exact commits produced by Stages 1 through 4. + Keep canonical Git URLs and immutable commit hashes; do not use branches or + local-path substitutes. +6. Apply the selected runtime group to the pipeline-managed prompt-library + root. Apply the suite configuration owner, group, directory mode, and file + mode directly to the existing Narratio fragment directory and template + loops. Campaign and prompt Git content remains root-managed and + world-readable. +7. Do not add ACL or package tasks in this stage. Do not change application + versions, native configuration fields, assets, Notarius enablement, or the + Feature 0010 cache path. + +### Validation + +Run from `ansible-role-dnd-pipeline`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: a fresh isolated role installation resolves the four new +immutable commits; Narratio runs first without missing-identity failures; all +five applications and the assembled Narratio configuration remain natively +usable; the immediate baseline repeat reports `changed=0` and `failed=0`; and +only intended pipeline-role files are modified. + +### Completion Criteria + +- One suite-level identity and configuration-mode policy is passed through the + four generic role interfaces. +- All pipeline-owned Narratio configuration uses the same policy directly. +- Dependency order and immutable pins refer to the completed standalone stages. +- No follow-up task fights a dependency role's ownership or mode state. +- Existing pipeline behavior remains valid and immediately idempotent. + +### Commit + +Commit intent: `Apply shared configuration ownership to the D&D pipeline` + +## Stage 6: Establish Shared Writable-Root ACLs + +### Objective + +Apply the settled setgid and inherited-access policy to the three existing +Narratio writable roots using direct package and ACL convergence. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-narratio/tasks/main.yml` +- `ansible-role-dnd-pipeline/collections/requirements.yml` +- `ansible-role-dnd-pipeline/tasks/main.yml` +- the official `ansible.posix.acl` 2.2.0 module documentation + +### Preconditions + +- Stage 5 is committed and validated. +- The pipeline role creates the runtime identity and Narratio creates + `/var/lib/narratio`, `/var/spool/narratio`, and `/var/cache/narratio` as the + selected user and group with mode `2775` before pipeline tasks run. +- `ansible.posix` 2.2.0 and Ubuntu's `acl` package remain available. + +### Owning Repository + +`ansible-role-dnd-pipeline` + +### Required Changes + +1. Add `ansible.posix` version `2.2.0` to + `collections/requirements.yml`, retaining the existing + `community.general` pin. +2. Add one direct privileged `ansible.builtin.apt` task for package `acl` with + `state: present`, `update_cache: true`, and `cache_valid_time: 3600`. +3. Use the smallest clear `ansible.posix.acl` loop or loops to manage access + and default entries on exactly `/var/lib/narratio`, + `/var/spool/narratio`, and `/var/cache/narratio`. For each root, converge + entries equivalent to `u::rwx`, `g::rwx`, `o::r-x`, and `m::rwx` for both + access and default ACLs. +4. Apply `become: true` to the package and ACL tasks. Keep ACL convergence + non-recursive: manage the roots and inheritance for new descendants, not + pre-existing descendants. +5. Do not add `stat`, `getfacl`, shell commands, handlers, ACL facts, manual + change detection, wrapper umasks, or fallback permission repair to + production tasks. Do not create `/var/cache/notarius` or `secrets/`. + +### Validation + +Run from `ansible-role-dnd-pipeline`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: the private collection bootstrap installs both pinned +collections; syntax and production-profile lint pass; ACL convergence succeeds +on all three existing roots; all existing native checks pass; and the +immediate repeat reports `changed=0` and `failed=0`. + +### Completion Criteria + +- The collection and host-package requirements are explicit and pinned where + applicable. +- Each shared root retains mode `2775` from the Narratio role and has the + selected access and default ACL entries. +- Production logic uses only direct package and ACL state management and does + not recursively mutate existing content. +- Existing pipeline validation and clean convergence remain green. + +### Commit + +Commit intent: `Manage shared pipeline access with ACLs` + +## Stage 7: Exercise Cross-Identity Pipeline Access + +### Objective + +Prove the suite's user-visible read and shared-write contract with one isolated +human-operator fixture while retaining the existing focused integration suite. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- `ansible-role-dnd-pipeline/tests/integration` +- `ansible-role-dnd-pipeline/tests/converge.yml` +- `ansible-role-dnd-pipeline/tasks/main.yml` + +### Preconditions + +- Stages 1 through 6 are committed and validated. +- The integration driver can create and remove one uniquely named test-only + local account through privilege escalation without touching an existing + human account. +- The service account, selected group, managed configuration, and three shared + roots exist through ordinary baseline convergence. + +### Owning Repository + +`ansible-role-dnd-pipeline` + +### Required Changes + +1. Retain the driver's isolated role and collection installation, immutable + asset inputs, native application checks, explicit configurable-behavior + cases, cleanup boundary, and immediate clean repeats. +2. Create one uniquely named test-only operator account after baseline + convergence and add only that account to the selected runtime group. This + is integration fixture setup, not production role behavior. Ensure cleanup + removes only the fixture account and its explicitly named test content on + both success and failure; never modify a real operator account. +3. As the test operator, run one existing native Narratio configuration + validation or inspection command against the same managed configuration and + campaign used by the service account. This proves the supported human + invocation boundary without duplicating every application check. +4. Under one uniquely named child of a shared Narratio root, create ordinary + content as the service account with a restrictive ordinary umask and modify + or read it as the test operator. Then create representative content as the + operator and modify or read it as the service account. Use actual access as + the assertion; do not parse mode bits or `getfacl` output. +5. Use one existing unprivileged account outside the shared group to read a + representative non-secret configuration or test artifact, establishing the + deliberate world-readable boundary. Do not grant that account write access + or add it to the shared group. +6. Keep one immediate identical role repeat after the new policy is active and + require `changed=0` and `failed=0`. Test-created descendants must not cause + recursive role changes. +7. Do not test every root, every application configuration, every ACL entry, or + Ansible's file, user, group, package, template, or ACL implementation. Do + not create credentials or a secrets fixture. + +### Validation + +Run from `ansible-role-dnd-pipeline`: + +```text +tests/integration +git diff --check +git status --short +``` + +Expected result: all prior checks remain green; the service account and one +existing-group-member fixture use the same Narratio configuration; both +identities exchange representative shared-root content despite a restrictive +ordinary umask; an account outside the group can read but is never granted +write access; cleanup removes only test-owned state; and the immediate role +repeat reports `changed=0` and `failed=0`. + +### Completion Criteria + +- Tests observe the supported operating contract rather than filesystem + metadata or task implementation. +- The human-user fixture is isolated, uniquely named, and reliably cleaned up. +- One representative root and configuration path provide sufficient coverage; + no exhaustive access matrix is added. +- The complete integration entry point remains the sole supported test command + and is immediately idempotent. + +### Commit + +Commit intent: `Test shared pipeline access across users` + +## Stage 8: Document the Shared Execution Model + +### Objective + +Document the standalone ownership interfaces and the pipeline's opinionated +service identity, readable configuration, shared writable state, operator +prerequisites, and secret boundary. + +### Required Policy Review + +Before beginning this stage, read: + +- `AGENTS.md` +- `docs/orientation.md` +- `docs/conventions.md` +- `docs/ansible.md` +- `docs/testing.md` +- `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` +- `docs/decisions/0002-shared-readable-pipeline-filesystem-policy.md` +- the four standalone-role READMEs updated in Stages 1 through 4 +- `ansible-role-dnd-pipeline/README.md` + +### Preconditions + +- Stages 1 through 7 are committed and validated. +- All final variable names, dependency pins, task behavior, and integration + commands are stable and match the feature roadmap. + +### Owning Repository + +`ansible-role-dnd-pipeline` + +### Required Changes + +1. Add the four suite variables to the pipeline README and explain that they + are deliberate D&D policy passed to the standalone roles rather than + standalone defaults. +2. Document dependency order: Narratio establishes the runtime user and group + before the remaining configuration-bearing dependencies run. +3. Document `narratio:narratio`, directory mode `0755`, and file mode `0644` + for application configuration, including the pipeline-owned Narratio + fragments. Explain that this ordinary configuration is Ansible-managed and + intentionally world-readable, not operator-edited in place. +4. Document the three shared roots, their `2775` setgid mode, inherited ACL + policy, and supported invocation as either the service account or a human + account already belonging to the runtime group. Use the term **setgid**, not + sticky bit. +5. State clearly that the production role does not select human users or manage + their group membership. Provide a concise consumer-side inventory or + operational example without embedding a particular human username. +6. Explain that configuration, transcripts, caches, generated artifacts, + campaign data, prompts, and logs are treated as non-secret D&D content. API + keys and credentials are deferred to the future restricted `secrets/` + subtree; do not imply that this feature creates it. +7. Update validation documentation to describe the representative native + operator check, actual shared-write exchange, world-readable check, and + immediate clean repeat without promising exhaustive permission testing. + +### Validation + +Run from `ansible-role-dnd-pipeline`: + +```text +tests/integration +git diff --check HEAD +git status --short +``` + +Expected result: the complete suite remains syntax-clean, lint-clean, natively +valid, cross-identity usable, and immediately idempotent; documentation matches +the implemented interface and paths; and no whitespace errors are reported. + +### Completion Criteria + +- Consumers can distinguish standalone defaults from suite overrides. +- The service-user and existing-group-member invocation paths, setgid/ACL + behavior, world-readable boundary, and deferred secrets boundary are clear. +- Documentation does not promise group-membership management, recursive + migration, Notarius v0.7.0 integration, or secret delivery. +- All five changed repositories remain valid after the documentation commit. + +### Commit + +Commit intent: `Document the shared pipeline execution model` + +## Final Validation and Handoff + +After Stage 8, run each owning repository's complete integration entry point: + +```text +cd ansible-role-audita && tests/integration +cd ../ansible-role-notarius && tests/integration +cd ../ansible-role-scriptorium && tests/integration +cd ../ansible-role-narratio && tests/integration +cd ../ansible-role-dnd-pipeline && tests/integration +``` + +Then, from the workspace root, run: + +```text +git diff --check +./scripts/status +``` + +The final handoff must: + +- identify all eight implementation commit hashes and confirm every changed + repository has a clean working tree; +- confirm syntax and production-profile lint pass in all five changed roles; +- confirm every standalone role's native behavior and immediate clean repeat + pass; +- confirm the pipeline installs the exact immutable standalone commits, + applies the configuration and ACL policy, supports representative + cross-identity access, and immediately reports `changed=0` and `failed=0`; +- confirm no application source, asset, collection, Seriatim role, secret, + human operator account, or unrelated repository was modified; +- summarize any deviation, blocker, or deferred work, including whether + dependency publication required a coordination pause; +- report any production complexity beyond the planned public variables, + direct task substitutions, dependency wiring, one package task, and the + minimum clear ACL loop or loops, together with the acceptance criterion that + required it; and +- leave Feature 0009 `ready` or `in_progress` for independent review rather + than marking it `done`. + +## Progress Notes + +No implementation stages have begun. Record only concise stage commit hashes +and blockers here during execution; preserve detailed evidence in the stage +commits and final handoff. diff --git a/docs/status.md b/docs/status.md index af69f42..948a375 100644 --- a/docs/status.md +++ b/docs/status.md @@ -4,7 +4,7 @@ Last updated: 2026-09-14 Current milestone: M1-03 suite-level pipeline role -Current focus: Review Feature 0009 shared pipeline filesystem and execution. +Current focus: Begin the Feature 0009 implementation sprint. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -15,7 +15,7 @@ Current focus: Review Feature 0009 shared pipeline filesystem and execution. | M0-05 | Suite-level role repository | ansible-role-dnd-pipeline | done | Repository created and added to `workspace.yml` | | 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 | in_progress | Review the proposed Feature 0009 shared filesystem and execution roadmap | +| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | in_progress | Execute the approved Feature 0009 implementation plan | | M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism | | 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 | @@ -25,7 +25,7 @@ Current focus: Review Feature 0009 shared pipeline filesystem and execution. | F0006 | Establish pipeline-role composition | ansible-role-dnd-pipeline | done | Implemented and validated through remediation commit `4ea4358` | | F0007 | Deploy D&D campaigns and prompt assets | ansible-role-dnd-pipeline, campaigns, and narratio-prompts | done | Implemented and validated through remediation commit `7572fa3` | | F0008 | Define opinionated D&D processing configuration | ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `3e253d7` | -| F0009 | Establish shared pipeline filesystem and execution | configuration-bearing application roles and ansible-role-dnd-pipeline | proposed | Review `docs/roadmap/features/0009-shared-pipeline-filesystem-and-execution.md` | +| F0009 | Establish shared pipeline filesystem and execution | configuration-bearing application roles and ansible-role-dnd-pipeline | ready | Execute the stages in `docs/roadmap/implementation.md` | | F0010 | Integrate D&D Notarius extraction | ansible-role-notarius and ansible-role-dnd-pipeline | proposed | Depends on Feature 0009; review `docs/roadmap/features/0010-dnd-notarius-extraction-integration.md` | | 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 |