Record the remaining shared filesystem work

This commit is contained in:
2026-09-14 23:47:28 +00:00
parent 398562a2ca
commit 7d92867ba7

View File

@@ -1,140 +1,168 @@
# Feature 0008 Remediation Review # Feature 0009 Remediation Review
Status: resolved Status: open
Reviewed implementation commits: Reviewed implementation commits:
- `bc6df2a Add the D&D Audita configuration defaults` - `66ebea9 Make Audita configuration ownership configurable`
- `7ca812c Add the Narratio D&D processing configuration` - `e9ae2dc Make Notarius configuration ownership configurable`
- `c1fa8ba Test the D&D processing configuration` - `8b4c86e Make Scriptorium configuration ownership configurable`
- `e99983b Document D&D processing profiles and artifacts` - `eeb1105 Make Narratio configuration ownership configurable`
The implementation substantially matches Feature 0008. The pipeline role ## Review Summary
selects the complete D&D Audita policy, deploys a small explicit ConfigKit
layout, keeps each ordinary artifact and the character family in its own
fragment, and provides a testing overlay that changes only Scriptorium profile
selection. Production convergence adds only one directory loop and one
template loop. Native validation, artifact inspection, both campaigns, profile
selection, and repeated convergence all succeed.
Two narrow findings remain. The four completed standalone-role stages are concise, idiomatic, and aligned
with Feature 0009. Each role exposes owner, group, configuration-directory
mode, and configuration-file mode variables; applies them directly through the
ordinary `file` and `template` tasks; preserves its standalone defaults; and
documents the interface. No redundant inspection, corrective convergence,
private state, or unrelated application behavior was introduced. All four
repository-local integration suites passed independently during review.
## Finding 1: Pin the Narratio Configuration Boundary Used by the Pipeline Feature 0009 as a whole is not implemented. The active implementation plan and
workspace status correctly record a publication blocker after Stage 4. The
pipeline repository remains at pre-feature commit `3e253d7`; Stages 5 through
8 have not been executed. The following findings therefore describe missing
target architecture rather than defects in the completed standalone commits.
## Finding 1: The Pipeline Does Not Select the Shared Configuration Policy
Severity: high
`ansible-role-dnd-pipeline/defaults/main.yml` and
`meta/argument_specs.yml` do not define the four suite-level runtime identity
and configuration-mode variables. `meta/main.yml:19-98` still runs Narratio
last and does not pass the new configuration ownership interfaces to Audita,
Notarius, Scriptorium, or Narratio. `requirements.yml:7-22` still pins the four
pre-feature role commits.
Consequently, applying the current pipeline role retains standalone ownership:
Audita, Notarius, and Scriptorium configuration remains `root:root`, while
Narratio configuration remains `root:narratio` with its standalone restrictive
modes. The target `narratio:narratio`, `0755` directory, and `0644` file suite
policy is not selected. Narratio also does not establish the service identity
before the other configuration-bearing dependencies run.
### Required Remediation
- Publish the four reviewed standalone-role commits so immutable dependency
installation can resolve them; do not replace commit pins with branches.
- Execute Stage 5 of `docs/roadmap/implementation.md` in full.
- Add the four suite defaults and argument-spec entries, run Narratio first,
pass the selected identity and modes through every generic role interface,
update the four dependency pins, and apply the same values directly to the
pipeline-owned Narratio fragments.
- Retain direct module convergence without any post-dependency permission
repair.
## Finding 2: Shared Writable-Root ACL Convergence Is Absent
Severity: high
`ansible-role-dnd-pipeline/collections/requirements.yml:1-4` contains only
`community.general`. `tasks/main.yml:1-65` neither installs Ubuntu's `acl`
package nor uses `ansible.posix.acl`. The three Narratio writable roots still
receive mode `2775` from the standalone role, but the suite does not establish
the access and default ACLs required to preserve group write and world
read/traverse behavior across invocation identities with different umasks.
### Required Remediation
- Execute Stage 6 of the implementation plan in full.
- Pin `ansible.posix` 2.2.0 alongside the existing collection dependency.
- Install `acl` with one ordinary privileged `ansible.builtin.apt` task.
- Apply the selected access and default ACL entries to exactly
`/var/lib/narratio`, `/var/spool/narratio`, and `/var/cache/narratio` with
direct, non-recursive `ansible.posix.acl` convergence.
- Do not add filesystem probes, `getfacl` production commands, recursive
migration, handler flow, or supplemental permission repair.
## Finding 3: The Shared Execution Contract Has No Behavioral Coverage
Severity: medium Severity: medium
`ansible-role-dnd-pipeline/tasks/main.yml:29-65` writes suite-owned fragments `ansible-role-dnd-pipeline/tests/integration:64-133` exercises the established
under the fixed `/usr/local/etc/narratio` root and assigns them to the fixed pipeline only as root and the `narratio` service account. It does not use a
`narratio` group. `meta/main.yml:75-96` gives the standalone Narratio role representative existing member of the shared group, exchange writable-state
relative imports, but does not set `narratio_config_path` or `narratio_group`. content between invocation identities, exercise inheritance under a
restrictive ordinary umask, or observe the deliberate world-readable boundary.
The assembled role therefore relies on two standalone-role defaults for state The missing tests are important because the group-sharing outcome is suite
that the pipeline itself consumes. If inventory supplies either unmapped behavior authored by this feature, not a request to re-test an individual
standalone variable—or if the standalone defaults later change—the Narratio Ansible module. The tests should exercise actual access rather than assert
role can write its root document somewhere other than mode values or parse ACL metadata.
`/usr/local/etc/narratio/pipeline.yml` or create a differently named group,
while the pipeline role continues using its fixed path and group. The result is
either unresolved relative imports or a failed file task on a fresh host.
These are cross-role coordination values, not application-local defaults. The
roadmap explicitly fixes the root document, imported layout, and
`root:narratio` ownership boundary, so the suite role must establish the same
values on both sides.
### Required Remediation ### Required Remediation
- In the `rakestraw.narratio` dependency variables, explicitly set - Execute Stage 7 of the implementation plan after Findings 1 and 2 are
`narratio_config_path: /usr/local/etc/narratio/pipeline.yml` and resolved.
`narratio_group: narratio`. - Use one uniquely named, test-owned operator account as an integration
- Keep the fixed task paths and ownership unchanged. Do not add state probes, fixture and clean up only that account and its explicitly named content.
path-discovery facts, or new public variables merely to restate this fixed - Validate one representative Narratio operation as that group member and one
topology. bidirectional content exchange with the service account.
- Retain the exact relative import list and confirm native base/testing - Observe one representative world-readable configuration or artifact as an
validation and clean repeated convergence. account outside the group.
- Preserve immediate clean repeated convergence and avoid an exhaustive
identity, path, mode, or ACL matrix.
## Finding 2: Derive the Production Prompt Profile in the Integration Test ## Finding 4: Pipeline Consumer Documentation Is Stale
Severity: low Severity: medium
`ansible-role-dnd-pipeline/tests/integration:87-90` separately asks `ansible-role-dnd-pipeline/README.md:185` still lists operator access among
Scriptorium to inspect the hard-coded `claude-fable-latest` profile and then deferred concerns. It does not document the new suite variables,
inspects `dnd.session_recap` version `2.0.0`. The useful behavior is that the Narratio-first dependency order, service-owned and world-readable
explicitly inspected prompt's declared production profile resolves. The configuration, shared setgid roots, inherited ACL behavior,
literal profile name instead freezes a prompt-owned current value in the test. existing-group-member invocation, or the restricted future `secrets/`
boundary.
If the prompt deliberately selects a new default profile, this check can either
fail because the old profile is removed or continue passing without verifying
the new production profile. That is the change-detector pattern prohibited by
the testing policy.
### Required Remediation ### Required Remediation
- Capture the existing native JSON result for the explicitly selected - Execute Stage 8 of the implementation plan after the production behavior and
`dnd.session_recap` prompt once. tests are complete.
- Read its `default_profile_id` and pass that value to Scriptorium's native - Clearly distinguish generic standalone defaults from the pipeline's
`inspect profile` command. opinionated overrides.
- Preserve the explicit `endpoint-profile` override as the representative - Document setgid terminology, the three shared roots, supported invocation
caller-selected testing case. identities, the fact that production does not manage human membership, and
- Do not assert that `claude-fable-latest`, `gemini-flash-latest`, or any other the deliberate non-secret boundary.
prompt/profile value remains a current default, and do not snapshot the - Do not promise the deferred secrets implementation, recursive migration, or
complete prompt document. Feature 0010 Notarius behavior.
## Resolution ## Required Validation
Resolved in pipeline-role commit `3e253d7`. The Narratio dependency now pins After remediation, run the complete integration entry point in each changed
the fixed configuration path and group consumed by the pipeline role. The role:
integration driver now obtains the selected recap prompt's
`default_profile_id` from Scriptorium's native JSON inspection and validates
that profile without naming a prompt-owned default in the test. No public
variables, convergence tasks, or supplemental state were added.
## Validation
From `ansible-role-dnd-pipeline`, run:
```text ```text
bash -n tests/integration cd ansible-role-audita && tests/integration
tests/integration cd ../ansible-role-notarius && tests/integration
git diff --check cd ../ansible-role-scriptorium && tests/integration
git status --short --branch cd ../ansible-role-narratio && tests/integration
cd ../ansible-role-dnd-pipeline && tests/integration
``` ```
Expected result: syntax checking and production-profile lint pass; Audita and Then run from the workspace root:
Narratio validate natively; base/testing comparison, representative inferred
dependency, family expansion, derived production-profile resolution, and the
explicit testing-profile override all succeed without provider calls; every
immediate repeat reports `changed=0` and `failed=0`; and only intended
remediation changes remain before commit.
From the workspace root, run:
```text ```text
git diff --check
./scripts/status ./scripts/status
``` ```
Expected result: implementation and reference repositories remain clean except The expected result is that all five role suites pass syntax and lint checks,
for intended remediation work before it is committed. native application checks succeed, the shared cross-identity contract is
observed, every immediate repeat reports `changed=0` and `failed=0`, all eight
implementation-stage commits are identified, and every repository is clean.
## Review Validation Evidence ## Review Validation Evidence
During review, `ansible-role-dnd-pipeline/tests/integration` completed During this review, the complete `tests/integration` entry points passed in
successfully. It installed fresh pinned dependencies, passed Ansible syntax `ansible-role-audita`, `ansible-role-notarius`,
checking and production-profile lint, validated the managed Audita policy, `ansible-role-scriptorium`, and `ansible-role-narratio`. Each suite installed
validated base and testing Narratio configuration, observed the enabled recap, its pinned collection dependencies, passed syntax checking and
inferred recap-to-rumor dependency, and disabled party-expanded character production-profile lint, exercised its native application behavior, and
family, resolved production and explicitly selected testing Scriptorium reported clean immediate repeats. `git diff --check` passed and all
profiles, and reported `changed=0` and `failed=0` on every required immediate implementation repositories remained clean after testing.
repeat. Cleanup restored the baseline suite.
Direct review also validated the `dilfs` campaign, inspected ConfigKit source The pipeline suite was not presented as Feature 0009 validation evidence
ownership and the complete effective artifact catalog, confirmed that the because the pipeline repository contains no Feature 0009 implementation
default `gemini-flash-latest` testing profile currently resolves, and verified commits. Its current test suite exercises the prior Feature 0008 architecture.
that all profile differences are confined to `profile_id` leaves. All
repositories were clean before this remediation document was written.
After remediation, `bash -n tests/integration`, the complete integration
driver, and `git diff --check` passed again. The driver performed fresh
dependency bootstrap, syntax checking, production-profile lint, native Audita
and Narratio validation, artifact and profile inspection, the explicit
testing-profile scenario, the explicit Seriatim-version scenario, and clean
immediate repeats before restoring the baseline suite.