Document shared pipeline filesystem policy
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
# Decision 0002: Shared, Readable Pipeline Filesystem Policy
|
||||||
|
|
||||||
|
Status: accepted
|
||||||
|
|
||||||
|
Date: 2026-09-14
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The D&D pipeline may be invoked either by its dedicated `narratio` service
|
||||||
|
account or by a human operator who is already a member of the `narratio`
|
||||||
|
group. Both identities need a consistent view of application configuration and
|
||||||
|
shared writable state. Notarius versions before v0.7.0 imposed private cache
|
||||||
|
modes that prevented this deployment model, but v0.7.0 delegates cache access
|
||||||
|
policy to deployment provisioning.
|
||||||
|
|
||||||
|
The pipeline processes D&D campaign material. This deployment does not treat
|
||||||
|
configuration, transcripts, caches, generated artifacts, logs, or other
|
||||||
|
pipeline content as secret. API keys and similar credentials are the sole
|
||||||
|
confidential category and must remain isolated from ordinary content.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
The suite uses `narratio` as both its service identity and shared operator
|
||||||
|
group. A human account that is already a member of that group is a supported
|
||||||
|
pipeline invocation identity. Selecting operators and managing their group
|
||||||
|
membership remain separate deployment concerns.
|
||||||
|
|
||||||
|
Application configuration directories and files are owned by
|
||||||
|
`narratio:narratio` and are world-readable. Directories normally use `0755`
|
||||||
|
and files use `0644`. They remain Ansible-managed even though the service
|
||||||
|
account owns them; operators do not edit managed configuration in place.
|
||||||
|
Standalone application roles expose generic owner, group, and mode variables
|
||||||
|
and retain independently useful defaults. The opinionated pipeline role
|
||||||
|
selects the suite ownership policy through those interfaces.
|
||||||
|
|
||||||
|
Shared writable roots use `narratio:narratio` ownership and mode `2775`.
|
||||||
|
Setgid preserves the shared group, while managed default ACLs preserve owner
|
||||||
|
and group write access and world read/traverse access for newly created
|
||||||
|
content regardless of an invoking account's ordinary umask. Ordinary files
|
||||||
|
are expected to converge to the corresponding non-executable mode `0664`.
|
||||||
|
Application source trees and installed binaries remain root-owned and
|
||||||
|
world-readable or executable as appropriate.
|
||||||
|
|
||||||
|
Credential material belongs only beneath the suite's eventual `secrets/`
|
||||||
|
directory. That directory is not world-accessible; its expected directory and
|
||||||
|
file modes are `0750` and `0640`, respectively, with
|
||||||
|
`narratio:narratio` ownership so both supported invocation identities can read
|
||||||
|
shared credentials. Configuration may contain credential reference names but
|
||||||
|
never raw credential values.
|
||||||
|
|
||||||
|
Version-controlled campaign and prompt assets may remain root-managed because
|
||||||
|
Git is authoritative, but they are world-readable. The suite does not add
|
||||||
|
confidentiality controls to non-secret D&D content.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
The pipeline can run under the service account or an existing human member of
|
||||||
|
the shared group without maintaining separate configuration or cache trees.
|
||||||
|
The deployment must provision setgid and default ACL behavior on shared
|
||||||
|
writable roots; directory modes alone do not guarantee group write access for
|
||||||
|
content created under an arbitrary user umask.
|
||||||
|
|
||||||
|
The broad readability of transcript-derived content is intentional. Hosts
|
||||||
|
requiring confidential campaign data need a different deployment policy and
|
||||||
|
are outside this MVP contract. Secret delivery remains future work and must
|
||||||
|
honor the separate restricted subtree rather than tightening unrelated files.
|
||||||
|
|
||||||
|
Existing content with incompatible ownership or ACLs is not recursively
|
||||||
|
migrated unless a feature expressly selects that behavior. Fresh convergence
|
||||||
|
and newly created content follow this policy.
|
||||||
@@ -6,3 +6,8 @@ change. Number records sequentially, for example
|
|||||||
`0001-application-and-suite-role-boundaries.md`.
|
`0001-application-and-suite-role-boundaries.md`.
|
||||||
|
|
||||||
Do not create a decision record for routine implementation choices.
|
Do not create a decision record for routine implementation choices.
|
||||||
|
|
||||||
|
## Records
|
||||||
|
|
||||||
|
- [0001: Minimal, Module-Driven Ansible](0001-minimal-module-driven-ansible.md)
|
||||||
|
- [0002: Shared, Readable Pipeline Filesystem Policy](0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
|
|||||||
@@ -458,12 +458,14 @@ are complete. Feature 0008 depends on the current Narratio 2.0 ConfigKit
|
|||||||
contract, the canonical party files deployed by Feature 0007, and prompt
|
contract, the canonical party files deployed by Feature 0007, and prompt
|
||||||
definitions whose production default profiles are available from Promptkit.
|
definitions whose production default profiles are available from Promptkit.
|
||||||
|
|
||||||
Feature 0009 should adapt the validated D&D Notarius pipeline, remove its
|
Feature 0010 should adapt the validated D&D Notarius pipeline, remove its
|
||||||
hard-coded campaign references in favor of Narratio invocation bindings,
|
hard-coded campaign references in favor of Narratio invocation bindings,
|
||||||
declare its runtime-directory policy, map its accepted outputs into Narratio,
|
declare its runtime-directory policy, map its accepted outputs into Narratio,
|
||||||
and enable extraction. Later features should address storage/publishing and
|
and enable extraction after Feature 0009 establishes shared filesystem and
|
||||||
secret delivery together, operator access, collection assembly, and an
|
execution policy. Later features should address storage/publishing and secret
|
||||||
end-to-end workflow that can use actual external services.
|
delivery together, optional operator selection and membership management,
|
||||||
|
collection assembly, and an end-to-end workflow that can use actual external
|
||||||
|
services.
|
||||||
|
|
||||||
## Potential Future Hardening
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,266 @@
|
|||||||
|
# Feature 0009: Shared Pipeline Filesystem and Execution
|
||||||
|
|
||||||
|
Status: proposed
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Establish one coherent filesystem and invocation policy for the D&D suite.
|
||||||
|
Standalone application roles will expose sensible generic configuration
|
||||||
|
ownership and mode controls, while the pipeline role will use those controls
|
||||||
|
to make configuration service-owned and world-readable and to make writable
|
||||||
|
state safely shareable by the service account and existing human members of
|
||||||
|
its group.
|
||||||
|
|
||||||
|
## Problem or Opportunity
|
||||||
|
|
||||||
|
The current standalone roles hard-code their configuration ownership and
|
||||||
|
modes. Those defaults are reasonable in isolation, but the pipeline cannot
|
||||||
|
select its intended `narratio:narratio` ownership without adding a second
|
||||||
|
convergence pass that would fight the dependency roles and report changes on
|
||||||
|
every run.
|
||||||
|
|
||||||
|
Narratio's writable roots already use setgid mode `2775`, but directory mode
|
||||||
|
alone does not preserve group write access when different invocation identities
|
||||||
|
have different umasks. Notarius v0.7.0 has removed its application-enforced
|
||||||
|
private cache modes, so deployment provisioning can now establish a consistent
|
||||||
|
shared policy before Notarius integration begins.
|
||||||
|
|
||||||
|
## Governing Policies
|
||||||
|
|
||||||
|
- [The Ansible house style](../../ansible.md) governs the generic role
|
||||||
|
interfaces, direct module-driven convergence, and suite overrides.
|
||||||
|
- [The testing house style](../../testing.md) governs behavioral access tests
|
||||||
|
and clean repeated convergence.
|
||||||
|
- [The MVP roadmap](../mvp.md) assigns operator access and cross-application
|
||||||
|
policy to the pipeline role while keeping standalone roles independently
|
||||||
|
useful.
|
||||||
|
- [Decision 0001](../../decisions/0001-minimal-module-driven-ansible.md)
|
||||||
|
requires direct idempotent modules without preliminary state inspection.
|
||||||
|
- [Decision 0002](../../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
|
defines the service ownership, shared writable state, world-readable content,
|
||||||
|
and restricted credential boundary implemented by this feature.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add configuration owner, group, directory-mode, and file-mode variables to
|
||||||
|
the Audita, Notarius, Narratio, and Scriptorium roles.
|
||||||
|
- Preserve standalone defaults appropriate to each application rather than
|
||||||
|
embedding D&D suite policy in those roles.
|
||||||
|
- Add suite-level runtime identity and configuration-mode variables to the
|
||||||
|
pipeline role and pass them explicitly to all four configuration-bearing
|
||||||
|
dependencies.
|
||||||
|
- Run the Narratio dependency before the other application dependencies so it
|
||||||
|
creates the selected service account and group before they write
|
||||||
|
service-owned configuration.
|
||||||
|
- Converge suite application configuration as `narratio:narratio`, with
|
||||||
|
directory mode `0755` and file mode `0644` by default.
|
||||||
|
- Keep `/var/lib/narratio`, `/var/spool/narratio`, and
|
||||||
|
`/var/cache/narratio` as `narratio:narratio` mode `2775` shared writable
|
||||||
|
roots.
|
||||||
|
- Install the Ubuntu `acl` package, declare a pinned `ansible.posix`
|
||||||
|
collection dependency, and manage access and default ACL entries that retain
|
||||||
|
owner/group write and world read/traverse access beneath shared roots.
|
||||||
|
- Support invocation as either the service account or an existing human
|
||||||
|
member of the selected runtime group.
|
||||||
|
- Document the standalone defaults, pipeline overrides, expected group
|
||||||
|
membership, world-readable non-secret boundary, and reserved restricted
|
||||||
|
`secrets/` policy.
|
||||||
|
- Add focused integration coverage for public configuration-mode overrides,
|
||||||
|
cross-identity access, and immediate clean repeated convergence.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Upgrading Notarius, adding its ConfigKit import interface, deploying its
|
||||||
|
D&D pipeline, creating `/var/cache/notarius`, or enabling Narratio's
|
||||||
|
extraction stage; those belong to Feature 0010.
|
||||||
|
- Changing any application's native configuration fields or runtime behavior.
|
||||||
|
- Selecting human operators or changing their group membership.
|
||||||
|
- Creating or populating a `secrets/` directory, delivering credentials, or
|
||||||
|
defining secret injection.
|
||||||
|
- Making application configuration group-writable or supporting manual edits
|
||||||
|
to Ansible-managed configuration.
|
||||||
|
- Changing ownership of root-managed source checkouts, installed binaries,
|
||||||
|
campaign assets, or prompt assets.
|
||||||
|
- Recursively migrating pre-existing runtime content with incompatible modes
|
||||||
|
or ACLs.
|
||||||
|
- Running transcript processing, calling external services, or adding
|
||||||
|
scheduling and service management.
|
||||||
|
|
||||||
|
## Target End State
|
||||||
|
|
||||||
|
Each standalone role exposes the same four concepts using its application
|
||||||
|
prefix. Its defaults remain appropriate for an independent installation:
|
||||||
|
|
||||||
|
| Role | Configuration owner | Configuration group | Directory mode | File mode |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| Audita | `root` | `root` | `0755` | `0644` |
|
||||||
|
| Notarius | `root` | `root` | `0755` | `0644` |
|
||||||
|
| Scriptorium | `root` | `root` | `0755` | `0644` |
|
||||||
|
| Narratio | `root` | `narratio` | `0750` | `0640` |
|
||||||
|
|
||||||
|
For example, the Notarius variables are
|
||||||
|
`notarius_config_owner`, `notarius_config_group`,
|
||||||
|
`notarius_config_directory_mode`, and `notarius_config_file_mode`; the other
|
||||||
|
roles use their corresponding prefixes. Each role uses these variables in the
|
||||||
|
ordinary directory and template tasks that already own its configuration. No
|
||||||
|
role adds a follow-up permission-repair task or preliminary inspection.
|
||||||
|
|
||||||
|
The pipeline role defines `dnd_pipeline_runtime_user` and
|
||||||
|
`dnd_pipeline_runtime_group`, both defaulting to `narratio`, plus
|
||||||
|
`dnd_pipeline_config_directory_mode: "0755"` and
|
||||||
|
`dnd_pipeline_config_file_mode: "0644"`. It passes those values as the four
|
||||||
|
roles' configuration owner, group, and mode inputs. Narratio executes first in
|
||||||
|
dependency order and creates the selected identity before another dependency
|
||||||
|
references it.
|
||||||
|
|
||||||
|
The resulting application configuration beneath
|
||||||
|
`/usr/local/etc/{audita,notarius,narratio,scriptorium}` is owned by
|
||||||
|
`narratio:narratio` and is world-readable. It remains under Ansible control;
|
||||||
|
neither the service account nor human operators are expected to edit managed
|
||||||
|
files in place.
|
||||||
|
|
||||||
|
The three existing Narratio writable roots are `narratio:narratio` mode
|
||||||
|
`2775`. Their access and default ACLs are equivalent to `u::rwx`, `g::rwx`,
|
||||||
|
`o::r-x`, and `m::rwx`. Inherited permissions remain subject to the mode
|
||||||
|
requested for each new file type, so ordinary files are non-executable while
|
||||||
|
remaining group-writable and world-readable. A later feature applies the same
|
||||||
|
policy when it introduces another shared root such as
|
||||||
|
`/var/cache/notarius`.
|
||||||
|
|
||||||
|
A human account already belonging to `narratio` can use the same configuration
|
||||||
|
and writable roots as the service account. This feature does not choose that
|
||||||
|
account. Credential files are absent; the reserved future
|
||||||
|
`/usr/local/etc/narratio/secrets` subtree uses the distinct `0750` directory
|
||||||
|
and `0640` file policy when a credential-delivery feature creates it.
|
||||||
|
|
||||||
|
## Repository Ownership
|
||||||
|
|
||||||
|
- `ansible-role-audita`, `ansible-role-notarius`, and
|
||||||
|
`ansible-role-scriptorium` own their generic configuration ownership and
|
||||||
|
mode variables, standalone defaults, documentation, and focused integration
|
||||||
|
coverage.
|
||||||
|
- `ansible-role-narratio` owns the equivalent generic controls while retaining
|
||||||
|
its existing standalone relationship to the service group it creates.
|
||||||
|
- `ansible-role-dnd-pipeline` owns dependency ordering, the suite runtime
|
||||||
|
identity and configuration-mode defaults, explicit dependency overrides,
|
||||||
|
the `acl` package and `ansible.posix` dependency, shared-root ACL
|
||||||
|
convergence, consumer documentation, and cross-identity integration
|
||||||
|
coverage.
|
||||||
|
- `ansible-workspace-dnd` owns this roadmap, Decision 0002, the later staged
|
||||||
|
implementation plan, and aggregate status.
|
||||||
|
- The five application source repositories are unchanged; their runtime
|
||||||
|
contracts are not needed to implement configuration-file ownership.
|
||||||
|
|
||||||
|
## Constraints and Settled Decisions
|
||||||
|
|
||||||
|
- Standalone application roles remain independently usable. Their defaults do
|
||||||
|
not assume that a `narratio` account exists unless the role itself creates
|
||||||
|
it.
|
||||||
|
- The pipeline role selects suite policy by passing public role variables; it
|
||||||
|
does not reapply ownership after dependencies have completed.
|
||||||
|
- Configuration owner and group variables are strings, while mode variables
|
||||||
|
use the quoted four-digit strings expected by Ansible file-management
|
||||||
|
modules.
|
||||||
|
- The pipeline's selected runtime user and group are the configuration owner
|
||||||
|
and group. Supporting different configuration and runtime identities would
|
||||||
|
require a concrete later use case.
|
||||||
|
- Application configuration is world-readable but not group-writable. Shared
|
||||||
|
writable roots and their ordinary content are group-writable and
|
||||||
|
world-readable.
|
||||||
|
- The role uses `ansible.builtin.apt` for the `acl` package and
|
||||||
|
`ansible.posix.acl` for access/default ACL state. The collection dependency
|
||||||
|
is pinned in the pipeline role's manifest and installed by its integration
|
||||||
|
driver.
|
||||||
|
- ACL management covers only the three existing writable roots and their
|
||||||
|
inheritance policy. It does not recursively rewrite existing descendants.
|
||||||
|
- A `secrets/` subtree is a documented future boundary, not state created by
|
||||||
|
this feature.
|
||||||
|
- Tests exercise the public operating contract and one representative
|
||||||
|
cross-identity workflow. They do not enumerate every path or restate every
|
||||||
|
module argument.
|
||||||
|
|
||||||
|
## Simplest Viable Implementation
|
||||||
|
|
||||||
|
1. Add four defaults, four argument-specification entries, and direct task
|
||||||
|
substitutions to each configuration-bearing standalone role; update its
|
||||||
|
README and focused integration inputs without adding new task flow.
|
||||||
|
2. Reorder the pipeline dependencies so Narratio creates the service identity
|
||||||
|
first, add four suite policy variables, and pass them directly to each
|
||||||
|
configuration-bearing role.
|
||||||
|
3. Add the pinned `ansible.posix` requirement, install `acl`, and apply the
|
||||||
|
selected access/default ACL entries to the three existing writable roots
|
||||||
|
with ordinary state-management modules.
|
||||||
|
4. Update pipeline consumer documentation and extend its integration driver
|
||||||
|
with one representative human group member, native configuration
|
||||||
|
inspection, shared-write behavior, and a clean repeat.
|
||||||
|
|
||||||
|
No task gathers preliminary filesystem or account state. Existing `file`,
|
||||||
|
`template`, `apt`, and `acl` modules own convergence and change reporting.
|
||||||
|
|
||||||
|
## Rationale and Alternatives
|
||||||
|
|
||||||
|
Public ownership and mode variables let each standalone role express its own
|
||||||
|
sensible installation while allowing a composing role to select different
|
||||||
|
policy through normal Ansible precedence. A corrective pipeline task would
|
||||||
|
fight the dependency templates and make every otherwise unchanged run report
|
||||||
|
changes.
|
||||||
|
|
||||||
|
Setgid alone preserves group identity but does not guarantee group-write bits
|
||||||
|
for files created under an arbitrary human user's umask. A managed default ACL
|
||||||
|
expresses the required inherited state directly. A wrapper command that sets a
|
||||||
|
umask would add another invocation path and would not protect direct use of the
|
||||||
|
installed applications.
|
||||||
|
|
||||||
|
Mode `2775`, rather than `2770`, is deliberate: D&D transcript content is not
|
||||||
|
treated as secret in this deployment. Only API keys and similar credentials
|
||||||
|
belong in the separately restricted future subtree.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Each configuration-bearing standalone role exposes and documents owner,
|
||||||
|
group, directory-mode, and file-mode variables with the standalone defaults
|
||||||
|
listed above.
|
||||||
|
- Each role applies those inputs through the tasks that already create its
|
||||||
|
configuration directory and file, without a second convergence pass.
|
||||||
|
- The pipeline role runs Narratio first and explicitly selects
|
||||||
|
`narratio:narratio`, `0755` directories, and `0644` files for all application
|
||||||
|
configuration.
|
||||||
|
- The deployed configuration for Audita, Notarius, Narratio, and Scriptorium
|
||||||
|
is owned by `narratio:narratio`, is readable by other local users, and
|
||||||
|
contains no credential values.
|
||||||
|
- The three existing Narratio writable roots are `narratio:narratio` mode
|
||||||
|
`2775` and have access/default ACLs that preserve group write and world
|
||||||
|
read/traverse access for new content.
|
||||||
|
- The pipeline role declares a pinned `ansible.posix` dependency and installs
|
||||||
|
the required Ubuntu `acl` package.
|
||||||
|
- The service account and a representative existing human member of the
|
||||||
|
`narratio` group can use the same configuration and exchange ordinary
|
||||||
|
writable-state content.
|
||||||
|
- The role does not create users other than the established service account,
|
||||||
|
alter human group membership, create a secrets directory, or migrate
|
||||||
|
existing descendants recursively.
|
||||||
|
- Syntax checking and production-profile lint pass in every changed role.
|
||||||
|
- Focused standalone-role integration checks and the complete pipeline
|
||||||
|
integration entry point pass.
|
||||||
|
- An immediate repeated application in every changed role reports no changes.
|
||||||
|
- Tests observe the shared operating contract without snapshotting defaults,
|
||||||
|
enumerating implementation steps, or testing trusted module behavior.
|
||||||
|
|
||||||
|
## Dependencies and Follow-up Work
|
||||||
|
|
||||||
|
Features 0001 through 0008 and the standalone-role test-suite simplification
|
||||||
|
are complete. Notarius v0.7.0's deployment-owned cache permissions remove the
|
||||||
|
application blocker that previously prevented this policy, but Feature 0009
|
||||||
|
does not otherwise depend on or modify the Notarius application.
|
||||||
|
|
||||||
|
Feature 0010 applies this policy to `/var/cache/notarius` while adding the D&D
|
||||||
|
extraction integration. Later work may add optional operator-selection and
|
||||||
|
group-membership variables or deliver credentials beneath the restricted
|
||||||
|
`secrets/` subtree.
|
||||||
|
|
||||||
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
- Offer a non-world-readable deployment profile if a concrete environment
|
||||||
|
later treats campaign material as confidential.
|
||||||
|
- Select a recursive migration policy if supported upgrades must normalize
|
||||||
|
pre-existing descendants rather than only managed roots and new content.
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
# Feature 0010: D&D Notarius Extraction Integration
|
||||||
|
|
||||||
|
Status: proposed
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Enable Narratio's Notarius stage with the maintained ten-lane D&D extraction
|
||||||
|
pipeline. The pipeline role will supply the opinionated Notarius pipeline,
|
||||||
|
bind campaign-owned inputs through Narratio's invocation boundary, and declare
|
||||||
|
the exact lane contracts Narratio may accept as extraction sources. It uses
|
||||||
|
the service ownership and shared-access foundation established by Feature
|
||||||
|
0009.
|
||||||
|
|
||||||
|
## Problem or Opportunity
|
||||||
|
|
||||||
|
Features 0006 through 0008 install and configure the five applications,
|
||||||
|
deploy the D&D content, and define the transcript-processing and Scriptorium
|
||||||
|
workflow. Narratio still leaves its Notarius stage disabled, and Notarius's
|
||||||
|
managed configuration contains no pipeline. A run can therefore produce a
|
||||||
|
cleaned and trimmed transcript but cannot yet extract the structured D&D
|
||||||
|
registries and events implemented by Notarius.
|
||||||
|
|
||||||
|
The uploaded test-machine configuration demonstrates the intended multi-step
|
||||||
|
pipeline, but it embeds campaign-specific filesystem paths and explicit
|
||||||
|
runtime roots. The current Notarius v0.7.0 complete example and Narratio 2.0
|
||||||
|
integration contract supersede those details. In particular, Narratio must
|
||||||
|
prepare invocation-local campaign references and own the run-specific output
|
||||||
|
staging directory; generated registry and event handoffs remain internal to
|
||||||
|
Notarius. Notarius v0.7.0 also replaces configuration version 4 with a strict,
|
||||||
|
ConfigKit-backed version 5 contract and makes cache access policy a deployment
|
||||||
|
responsibility.
|
||||||
|
|
||||||
|
## Governing Policies
|
||||||
|
|
||||||
|
- [The Ansible house style](../../ansible.md) governs the suite-owned public
|
||||||
|
interface, direct desired-state configuration, and reliance on the
|
||||||
|
standalone roles' native templates.
|
||||||
|
- [The testing house style](../../testing.md) governs focused native contract
|
||||||
|
validation and immediate clean repeated convergence.
|
||||||
|
- [The MVP roadmap](../mvp.md) assigns opinionated D&D policy and
|
||||||
|
cross-application coordination to the pipeline role while keeping the
|
||||||
|
standalone application roles generic.
|
||||||
|
- [Decision 0001](../../decisions/0001-minimal-module-driven-ansible.md)
|
||||||
|
requires module-owned convergence without redundant inspection or
|
||||||
|
supplemental state.
|
||||||
|
- [Decision 0002](../../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
|
defines the service ownership, shared operator access, world-readable
|
||||||
|
content, and restricted credential boundary.
|
||||||
|
- [Feature 0008](0008-opinionated-dnd-processing-configuration.md) establishes
|
||||||
|
the trimmed transcript, ConfigKit layout, and `testing` overlay into which
|
||||||
|
this feature integrates.
|
||||||
|
- [Feature 0009](0009-shared-pipeline-filesystem-and-execution.md) establishes
|
||||||
|
the runtime identity, configuration ownership interfaces, and inherited
|
||||||
|
shared-access policy extended by this feature.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Update the standalone Notarius role for Notarius v0.7.0 and configuration
|
||||||
|
version 5 while preserving its generic, independently usable interface.
|
||||||
|
- Expose Notarius's native `configkit.imports` field through one optional
|
||||||
|
`notarius_configkit_imports` role variable; the role continues to own only
|
||||||
|
its root configuration and does not manage caller-selected fragments.
|
||||||
|
- Supply one complete `dnd-session` Notarius pipeline as deliberate D&D suite
|
||||||
|
policy in a suite-managed imported fragment at
|
||||||
|
`/usr/local/etc/notarius/pipelines/dnd-session.yml`.
|
||||||
|
- Adapt the maintained Notarius v0.7.0 complete D&D pipeline using canonical
|
||||||
|
version 5 module-binding objects, including:
|
||||||
|
- the embedded `dnd-extraction` PromptKit workload profile;
|
||||||
|
- Seriatim input and scene-based chunking;
|
||||||
|
- the ordered `describe-session`, `extract-events`, and `track-enemies`
|
||||||
|
steps;
|
||||||
|
- all ten maintained D&D artifact lanes and their generated handoffs; and
|
||||||
|
- JSON output with the chunk map and selected evidence context.
|
||||||
|
- Remove every campaign-specific filesystem reference from the Notarius
|
||||||
|
pipeline definition.
|
||||||
|
- Enable Narratio's Notarius stage and select `dnd-session`.
|
||||||
|
- Bind `party`, `players`, and `glossary` to Narratio's prepared campaign
|
||||||
|
sources at invocation time.
|
||||||
|
- Define Narratio acceptance descriptors for all ten maintained lane outputs.
|
||||||
|
- Make the pipeline map, Narratio reference map, and Narratio output map
|
||||||
|
ordinary suite variables so callers can compose or replace native mappings
|
||||||
|
through inventory precedence.
|
||||||
|
- Make the selected pipeline ID an ordinary suite variable and keep it
|
||||||
|
coordinated with the default pipeline map.
|
||||||
|
- Enable Notarius caching to the maximum currently available extent: use
|
||||||
|
`auto` chunk-plan caching and enable checkpoint recording. Narratio does not
|
||||||
|
yet request checkpoint reuse with Notarius's `--resume` flag.
|
||||||
|
- Provision `/var/cache/notarius` as a shared FHS cache root owned by
|
||||||
|
`narratio:narratio` with mode `2775`, with chunk-plan and checkpoint stores
|
||||||
|
beneath it.
|
||||||
|
- Apply Feature 0009's established access and default ACL policy to the new
|
||||||
|
cache root so content created by either supported invocation identity remains
|
||||||
|
group-writable and world-readable.
|
||||||
|
- Keep Notarius enabled under the existing `testing` overlay. Testing and
|
||||||
|
production select the same Notarius pipeline and workload profile until the
|
||||||
|
suite chooses a distinct testing profile strategy.
|
||||||
|
- Document the reference boundary, lane-to-source mapping, runtime-state
|
||||||
|
policy, production/testing behavior, and supported caller customization.
|
||||||
|
- Extend focused integration coverage for native Notarius validation,
|
||||||
|
Narratio base/testing resolution, representative reference and output
|
||||||
|
wiring, and immediate clean repeated convergence.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Changing any application's native configuration fields or duplicating a
|
||||||
|
standalone role's root configuration template in the pipeline role.
|
||||||
|
- Making the standalone Notarius role manage imported fragments; fragment
|
||||||
|
deployment remains the responsibility of the caller that selects an
|
||||||
|
import.
|
||||||
|
- Copying the uploaded test-machine configuration verbatim.
|
||||||
|
- Installing a filesystem PromptKit profile for Notarius. Notarius v0.7.0
|
||||||
|
already embeds the selected production `dnd-extraction` fallback profile.
|
||||||
|
- Defining a second Notarius pipeline solely to select an inexpensive testing
|
||||||
|
model, or otherwise adding profile inheritance that Notarius does not
|
||||||
|
natively provide.
|
||||||
|
- Binding a spell catalog before the campaign registry declares one.
|
||||||
|
- Publishing, rendering, or otherwise consuming the new extraction sources in
|
||||||
|
Scriptorium artifacts.
|
||||||
|
- Selecting a default campaign.
|
||||||
|
- Delivering API keys, provider credentials, environment files, or a general
|
||||||
|
secret-management mechanism.
|
||||||
|
- Running Notarius extraction, making model calls, or processing a complete
|
||||||
|
transcript during integration tests.
|
||||||
|
- Managing output retention, cache cleanup, or debug retention.
|
||||||
|
- Adding checkpoint-resume control to Narratio or changing Narratio's
|
||||||
|
subprocess invocation to pass `--resume` or `--config-profile`.
|
||||||
|
- Installing a systemd service, timer, scheduler, or other unattended
|
||||||
|
invocation mechanism.
|
||||||
|
- Selecting human operator accounts or changing their membership in the
|
||||||
|
`narratio` group.
|
||||||
|
- Revising the general configuration ownership, dependency ordering, ACL
|
||||||
|
dependency, or existing shared roots established by Feature 0009.
|
||||||
|
- Delivering or populating the future restricted `secrets/` directory.
|
||||||
|
- Modifying upstream application source, embedded Notarius prompts, schemas,
|
||||||
|
modules, codecs, or validators.
|
||||||
|
- Collection assembly, role releases, storage/publishing, upgrade/removal
|
||||||
|
behavior, or end-to-end production validation.
|
||||||
|
|
||||||
|
## Target End State
|
||||||
|
|
||||||
|
The standalone Notarius role continues to own the version 5 root document at
|
||||||
|
`/usr/local/etc/notarius/config.yml`. Its public interface exposes the native
|
||||||
|
`configkit.imports` list, and the pipeline role selects the explicit relative
|
||||||
|
import `pipelines/dnd-session.yml`. The pipeline role owns that fragment and
|
||||||
|
renders the complete `dnd_pipeline_notarius_pipelines` map into it, producing
|
||||||
|
one native `dnd-session` definition by default. The definition follows the
|
||||||
|
Notarius v0.7.0 maintained complete D&D topology:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Seriatim transcript
|
||||||
|
-> dnd/scenes chunking
|
||||||
|
-> describe-session
|
||||||
|
item-registry
|
||||||
|
npc-registry
|
||||||
|
location-registry
|
||||||
|
scene-descriptions
|
||||||
|
-> extract-events
|
||||||
|
item-occurrences
|
||||||
|
spells
|
||||||
|
combat-turns
|
||||||
|
npc-occurrences
|
||||||
|
location-occurrences
|
||||||
|
-> track-enemies
|
||||||
|
enemy-events
|
||||||
|
-> JSON bundle, chunk map, and evidence context
|
||||||
|
```
|
||||||
|
|
||||||
|
Feature 0009 already makes application configuration service-owned and
|
||||||
|
world-readable. The Notarius root document and new suite fragment retain that
|
||||||
|
`narratio:narratio`, `0755` directory, and `0644` file policy through the
|
||||||
|
standalone role's established ownership and mode interface.
|
||||||
|
|
||||||
|
The `extract-events` step consumes the four generated outputs from
|
||||||
|
`describe-session` under their declared internal reference slots. The
|
||||||
|
`track-enemies` step consumes the generated NPC registry and scene
|
||||||
|
descriptions from `describe-session` and the generated combat turns and NPC
|
||||||
|
occurrences from `extract-events`. Those handoffs are part of the Notarius
|
||||||
|
pipeline and never appear in Narratio's CLI reference map.
|
||||||
|
|
||||||
|
Narratio's effective base configuration enables Notarius, selects the managed
|
||||||
|
configuration and `dnd-session`, and supplies three campaign-owned references:
|
||||||
|
|
||||||
|
| Notarius selector | Prepared Narratio source |
|
||||||
|
| --- | --- |
|
||||||
|
| `party` | `narratio.input.party` |
|
||||||
|
| `players` | `narratio.input.players` |
|
||||||
|
| `glossary` | `narratio.input.glossary` |
|
||||||
|
|
||||||
|
Narratio snapshots those inputs for each invocation and passes their absolute
|
||||||
|
paths with `--reference`. No campaign path appears in Notarius configuration.
|
||||||
|
The optional `spell_catalog` binding is absent because neither deployed
|
||||||
|
campaign currently declares `inputs.spell_catalog_file`. A caller that adds
|
||||||
|
that campaign input can extend the suite reference map with
|
||||||
|
`spell_catalog: narratio.input.spell_catalog` without changing either
|
||||||
|
application role.
|
||||||
|
|
||||||
|
Narratio accepts all ten configured lanes using these exact v1 contracts and
|
||||||
|
registers each accepted payload as `narratio.extraction.<output-key>`:
|
||||||
|
|
||||||
|
| Narratio output key | Lane ID | Schema ID | Module key |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `item_registry` | `item-registry` | `notarius.dnd.item_registry` | `dnd/item-registry` |
|
||||||
|
| `npc_registry` | `npc-registry` | `notarius.dnd.npc_registry` | `dnd/npc-registry` |
|
||||||
|
| `location_registry` | `location-registry` | `notarius.dnd.location_registry` | `dnd/location-registry` |
|
||||||
|
| `scene_descriptions` | `scene-descriptions` | `notarius.dnd.scene_descriptions` | `dnd/scene-descriptions` |
|
||||||
|
| `item_occurrences` | `item-occurrences` | `notarius.dnd.item_occurrences` | `dnd/item-occurrences` |
|
||||||
|
| `spells` | `spells` | `notarius.dnd.spells` | `dnd/spells` |
|
||||||
|
| `combat_turns` | `combat-turns` | `notarius.dnd.combat_turns` | `dnd/combat-turns` |
|
||||||
|
| `npc_occurrences` | `npc-occurrences` | `notarius.dnd.npc_occurrences` | `dnd/npc-occurrences` |
|
||||||
|
| `location_occurrences` | `location-occurrences` | `notarius.dnd.location_occurrences` | `dnd/location-occurrences` |
|
||||||
|
| `enemy_events` | `enemy-events` | `notarius.dnd.enemy_events` | `dnd/enemy-events` |
|
||||||
|
|
||||||
|
Every entry requires `media_type: application/json` and
|
||||||
|
`schema_version: v1`. Narratio validates the received descriptor before
|
||||||
|
registering the source; it does not infer contracts from filenames.
|
||||||
|
|
||||||
|
Narratio supplies its run-specific staging root through Notarius's
|
||||||
|
`--output-dir` override, so the suite does not set Notarius's global
|
||||||
|
`output.directory`. Reconstructible Notarius state uses the FHS cache layout:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/cache/notarius/
|
||||||
|
├── chunk-plans/
|
||||||
|
└── checkpoints/
|
||||||
|
```
|
||||||
|
|
||||||
|
The pipeline role creates the root as `narratio:narratio` mode `2775`, sets
|
||||||
|
chunk-plan mode to `auto`, enables checkpoint recording, and configures both
|
||||||
|
child paths. Notarius creates cache entries with conventional maximum creation
|
||||||
|
modes and leaves their effective modes to deployment provisioning, process
|
||||||
|
umask, setgid inheritance, and default ACLs. The suite applies a default ACL
|
||||||
|
that retains owner and group write access and world read/traverse access for
|
||||||
|
new cache content. Narratio and its Notarius subprocess may run as the
|
||||||
|
dedicated `narratio` account or as a human member of the `narratio` group.
|
||||||
|
Chunk plans are reused automatically; checkpoints are recorded but are not
|
||||||
|
reused because Narratio does not pass `--resume`. The debug root remains
|
||||||
|
unset. The selected Notarius process working directory is
|
||||||
|
`/usr/local/etc/notarius`, matching the managed configuration location; no
|
||||||
|
relative profile or reference paths depend on it.
|
||||||
|
|
||||||
|
The cache root receives the same setgid and default-ACL policy that Feature
|
||||||
|
0009 applies to Narratio's existing shared roots. Non-secret content created
|
||||||
|
beneath it remains writable by the shared group and readable by other local
|
||||||
|
users. The suite does not create or populate a `secrets/` directory.
|
||||||
|
|
||||||
|
The base Narratio configuration and the `testing` ConfigKit overlay both run
|
||||||
|
the extraction stage using Notarius's embedded `dnd-extraction` profile. The
|
||||||
|
testing overlay continues to override only the Scriptorium profile selections;
|
||||||
|
it does not disable or restate Notarius. A later feature may select a distinct
|
||||||
|
inexpensive Notarius testing profile without changing the pipeline topology.
|
||||||
|
|
||||||
|
## Repository Ownership
|
||||||
|
|
||||||
|
- `ansible-role-dnd-pipeline` owns the D&D pipeline map and imported fragment,
|
||||||
|
Narratio integration mappings, Notarius dependency-variable wiring, the new
|
||||||
|
cache root and its inherited shared-access policy, testing-overlay choice,
|
||||||
|
consumer documentation, and suite integration coverage.
|
||||||
|
- `ansible-role-notarius` owns the generic Notarius v0.7.0 installation,
|
||||||
|
version 5 root configuration, optional ConfigKit import interface, focused
|
||||||
|
role documentation, and role-local integration coverage. It does not own or
|
||||||
|
render the suite's imported D&D fragment.
|
||||||
|
- `ansible-role-audita`, `ansible-role-narratio`, and
|
||||||
|
`ansible-role-scriptorium` remain unchanged. The Narratio role owns its generic
|
||||||
|
Notarius adapter fields and ConfigKit-aware root configuration.
|
||||||
|
- `../notarius` is the read-only authority for configuration version 5, the
|
||||||
|
maintained D&D pipeline, embedded profile, module handoffs, and lane
|
||||||
|
contracts.
|
||||||
|
- `../narratio` is the read-only authority for prepared campaign sources,
|
||||||
|
subprocess invocation, output acceptance, and profile overlay behavior.
|
||||||
|
- `assets/configs/notarius/config.yml` is an operational reference only. Its
|
||||||
|
useful topology is adapted, while its campaign paths and runtime roots are
|
||||||
|
not copied.
|
||||||
|
- `assets/campaigns` remains unchanged and continues to own the campaign
|
||||||
|
registry inputs that Narratio prepares.
|
||||||
|
- `ansible-workspace-dnd` owns this roadmap, the later implementation plan,
|
||||||
|
settled MVP decisions, and aggregate status.
|
||||||
|
|
||||||
|
## Constraints and Settled Decisions
|
||||||
|
|
||||||
|
- The selected application contracts are Notarius v0.7.0 and Narratio v2.0.0,
|
||||||
|
matching the pipeline role's pinned application versions.
|
||||||
|
- Feature 0009 has already established the runtime identity, dependency order,
|
||||||
|
standalone ownership interfaces, configuration modes, `acl` package, and
|
||||||
|
pinned `ansible.posix` dependency used here.
|
||||||
|
- The pipeline role relies on the standalone roles for application
|
||||||
|
installation and both root configuration documents. It manages only the
|
||||||
|
suite-owned Notarius and Narratio fragments selected through those public
|
||||||
|
interfaces.
|
||||||
|
- The standalone Notarius role defaults to configuration version 5 and exposes
|
||||||
|
`notarius_configkit_imports` as the complete native import list. A null value
|
||||||
|
omits the `configkit` section and leaves composition with Notarius.
|
||||||
|
- The pipeline role passes the fixed import
|
||||||
|
`pipelines/dnd-session.yml` to the standalone role and manages that imported
|
||||||
|
file as suite-owned configuration. It does not pass the pipeline map into
|
||||||
|
the standalone role's root-level `notarius_pipelines` field.
|
||||||
|
- `/var/cache/notarius` uses the Feature 0009 runtime identity, mode `2775`,
|
||||||
|
and access/default ACL entries equivalent to `u::rwx`, `g::rwx`, `o::r-x`,
|
||||||
|
and `m::rwx`.
|
||||||
|
- `dnd_pipeline_notarius_pipelines` is a complete native map whose default
|
||||||
|
contains `dnd-session`. Callers may replace it or compose additional
|
||||||
|
pipeline definitions with Jinja's `combine` filter in inventory.
|
||||||
|
- `dnd_pipeline_narratio_notarius_pipeline_id` defaults to `dnd-session`.
|
||||||
|
Callers that replace that key are responsible for selecting a matching ID.
|
||||||
|
- `dnd_pipeline_narratio_notarius_references` is the complete native Narratio
|
||||||
|
reference map. It defaults to `party`, `players`, and `glossary`; its values
|
||||||
|
are prepared source IDs, never filesystem paths.
|
||||||
|
- `dnd_pipeline_narratio_notarius_outputs` is the complete native Narratio
|
||||||
|
output map. It defaults to all ten lanes because the suite claims to consume
|
||||||
|
the complete maintained D&D extraction workflow.
|
||||||
|
- `dnd_pipeline_notarius_cache_root` defaults to `/var/cache/notarius`,
|
||||||
|
`dnd_pipeline_notarius_cache_chunk_plans_mode` defaults to `auto`, and
|
||||||
|
`dnd_pipeline_notarius_cache_checkpoints_enabled` defaults to `true`. They
|
||||||
|
are intentional, inventory-overridable suite policy. The two application
|
||||||
|
cache directories derive from that root rather than becoming independent
|
||||||
|
suite variables.
|
||||||
|
- The pipeline defaults to `llm_profile: dnd-extraction` and relies on
|
||||||
|
Notarius's embedded fallback. It does not set `promptkit.profile_file`,
|
||||||
|
`promptkit.profile_dir`, a local backend, or credentials.
|
||||||
|
- The pipeline uses the version 5 `input: {module: seriatim}` binding,
|
||||||
|
`dnd/scenes` chunking with two retries, and the three ordered steps documented
|
||||||
|
above. Extract, merge, and normalize bindings use canonical objects with
|
||||||
|
`module:`; retries and generated reference handoffs match the maintained
|
||||||
|
Notarius complete example.
|
||||||
|
- JSON output enables `include_chunk_map` and evidence context with a
|
||||||
|
three-unit window. Evidence context includes item occurrences, item
|
||||||
|
registry, location registry, location occurrences, NPC registry, spells,
|
||||||
|
combat turns, NPC occurrences, and enemy events, matching the maintained
|
||||||
|
example.
|
||||||
|
- Notarius pipeline YAML contains no external file references. Narratio owns
|
||||||
|
all campaign input materialization for the orchestrated path.
|
||||||
|
- Narratio's Notarius binary and configuration paths remain the established
|
||||||
|
`/usr/local/bin/notarius` and `/usr/local/etc/notarius/config.yml`.
|
||||||
|
- The suite uses the runtime user and group selected by Feature 0009 for the
|
||||||
|
Notarius cache and configuration fragment.
|
||||||
|
- Narratio's Notarius working directory is explicitly
|
||||||
|
`/usr/local/etc/notarius`; the timeout inherits Narratio's native three-hour
|
||||||
|
default because the suite has selected no different policy.
|
||||||
|
- Narratio owns per-run Notarius output staging. The suite provisions
|
||||||
|
`/var/cache/notarius` for the shared `narratio` identity, and Notarius owns
|
||||||
|
its child cache stores. The role does not create `/var/lib/notarius`, set a
|
||||||
|
global output root, or provision a debug root.
|
||||||
|
- Checkpoint enablement records reusable state but does not cause Narratio to
|
||||||
|
reuse it. Resume remains an explicit Notarius invocation action and requires
|
||||||
|
a later Narratio integration decision.
|
||||||
|
- The production configuration enables Notarius. The existing `testing`
|
||||||
|
overlay inherits that enabled stage and the same `dnd-extraction` profile;
|
||||||
|
it does not override Notarius merely to avoid model calls.
|
||||||
|
- All maps use native application shapes and remain replaceable through normal
|
||||||
|
inventory precedence. The suite does not create field-by-field aliases for
|
||||||
|
every nested lane or module option.
|
||||||
|
- Directory and ACL tasks declare only the shared roots required by the
|
||||||
|
applications, using ordinary state-management modules with task-level
|
||||||
|
privilege escalation. No `stat`, command, handler, checksum, manifest, or
|
||||||
|
production validation task accompanies them.
|
||||||
|
|
||||||
|
## Simplest Viable Implementation
|
||||||
|
|
||||||
|
The production changes remain direct configuration management:
|
||||||
|
|
||||||
|
1. Update the standalone Notarius role's version and configuration-version
|
||||||
|
defaults and add the nullable native ConfigKit import field to defaults,
|
||||||
|
argument specification, root template, and documentation. Cover that public
|
||||||
|
behavior with focused native validation and a clean repeat.
|
||||||
|
2. Add the selected Notarius pipeline map, shared FHS cache policy, and three
|
||||||
|
suite-level Narratio integration mappings to pipeline-role defaults and the
|
||||||
|
argument specification.
|
||||||
|
3. Pass the fixed import and cache choices to `rakestraw.notarius`, and pass
|
||||||
|
Notarius enablement, selected ID, working directory, references, and outputs
|
||||||
|
to `rakestraw.narratio`.
|
||||||
|
4. Create the Notarius pipeline-fragment directory and cache root with ordinary
|
||||||
|
`ansible.builtin.file` tasks, render the suite-owned pipeline map into one
|
||||||
|
imported fragment, and extend Feature 0009's access/default ACL task to the
|
||||||
|
new root.
|
||||||
|
5. Update both role READMEs and extend focused integration coverage with native
|
||||||
|
configuration validation, effective-configuration inspection, inspection
|
||||||
|
as a supported group member, and clean repeats.
|
||||||
|
|
||||||
|
The standalone roles' template operations continue to own both root
|
||||||
|
configuration files. The pipeline role adds one Notarius pipeline-fragment
|
||||||
|
template but does not duplicate the root document or change the existing
|
||||||
|
Narratio testing-overlay template for this feature.
|
||||||
|
|
||||||
|
## Rationale and Alternatives
|
||||||
|
|
||||||
|
Using Notarius's maintained complete example preserves the upstream module
|
||||||
|
topology and contract while keeping suite policy explicit. Maintaining a
|
||||||
|
smaller custom pipeline would make the role responsible for deciding which
|
||||||
|
D&D artifacts no longer matter. Copying the uploaded file would instead
|
||||||
|
preserve obsolete host paths and bypass Narratio's verified reference
|
||||||
|
boundary.
|
||||||
|
|
||||||
|
Rendering one native map into a ConfigKit-imported fragment keeps configuration
|
||||||
|
ownership clear and preserves the inventory-composition workflow already
|
||||||
|
selected for Notarius. It also follows Notarius v0.7.0's maintained composition
|
||||||
|
shape without making the generic role own D&D content. Field-specific variables
|
||||||
|
for every lane, step, and retry would create a large parallel schema with little
|
||||||
|
consumer value. One complete map is easier to replace, combine, validate, and
|
||||||
|
compare with Notarius documentation.
|
||||||
|
|
||||||
|
`/var/cache/notarius` follows the filesystem hierarchy's intended location for
|
||||||
|
reconstructible application state and is preferable to the uploaded
|
||||||
|
`/var/lib/notarius/cache` layout. Assigning the root to the dedicated
|
||||||
|
`narratio` account and group gives unattended and human-initiated runs one
|
||||||
|
reusable cache. Mode `2775` preserves the shared group, and the default ACL
|
||||||
|
prevents an invoking account's umask from accidentally removing group write or
|
||||||
|
world read access from new content. Notarius v0.7.0 respects this deployment
|
||||||
|
policy rather than replacing it with application-owned private modes.
|
||||||
|
Narratio's staging root remains separate because output bundles are run
|
||||||
|
results, not cache data.
|
||||||
|
|
||||||
|
The `testing` overlay cannot natively replace a nested Notarius pipeline's
|
||||||
|
`llm_profile`; that configuration lives in a separate application file.
|
||||||
|
Duplicating the full pipeline or managing a second Notarius root configuration
|
||||||
|
would add substantial configuration drift for one model choice. Testing
|
||||||
|
therefore inherits production extraction for now; a distinct testing strategy
|
||||||
|
can be selected later if it becomes a concrete need.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
### Required Configuration Behavior
|
||||||
|
|
||||||
|
- The pipeline role installs a Notarius configuration that natively validates
|
||||||
|
the `dnd-session` pipeline without provider credentials or a model call.
|
||||||
|
- The standalone Notarius role supports an explicitly selected v0.7.0,
|
||||||
|
emits configuration version 5 with its compatible defaults, and can render
|
||||||
|
a caller-supplied native ConfigKit import list.
|
||||||
|
- The root Notarius configuration imports the suite-owned
|
||||||
|
`pipelines/dnd-session.yml` fragment, and that fragment contains the complete
|
||||||
|
pipeline map selected through inventory.
|
||||||
|
- The pipeline contains the maintained Seriatim input, D&D scene chunker,
|
||||||
|
three ordered steps, ten lanes, generated handoffs, JSON chunk map, and
|
||||||
|
selected evidence-context policy.
|
||||||
|
- The Notarius configuration contains no campaign-specific reference paths,
|
||||||
|
PromptKit operator-profile path, fixed output root, or debug root.
|
||||||
|
- The Notarius configuration selects `auto` chunk-plan caching, enables
|
||||||
|
checkpoints, and uses `/var/cache/notarius/chunk-plans` and
|
||||||
|
`/var/cache/notarius/checkpoints` respectively.
|
||||||
|
- The deployed cache root is `narratio:narratio` mode `2775`; its access and
|
||||||
|
default ACLs preserve group write and world read/traverse access without
|
||||||
|
depending on Notarius to enforce entry modes. Checkpoints are recorded; the
|
||||||
|
roadmap does not claim Narratio reuses them.
|
||||||
|
- The Notarius root configuration and suite-owned imported fragment retain
|
||||||
|
Feature 0009's `narratio:narratio`, `0755` directory, and `0644` file policy.
|
||||||
|
No secret value appears in either file.
|
||||||
|
- Narratio's effective base configuration enables Notarius, selects
|
||||||
|
`dnd-session`, and uses the installed binary, configuration, and working
|
||||||
|
directory.
|
||||||
|
- Narratio maps `party`, `players`, and `glossary` to the three documented
|
||||||
|
prepared campaign sources and contains no default `spell_catalog` binding.
|
||||||
|
- Narratio declares all ten documented output entries with exact lane, media,
|
||||||
|
schema, version, and module identities.
|
||||||
|
- Narratio natively validates the effective base configuration for either
|
||||||
|
deployed campaign without a model call.
|
||||||
|
- `narratio config show` or the equivalent native inspection surface exposes
|
||||||
|
the enabled stage, selected pipeline, representative reference, and
|
||||||
|
representative output contract.
|
||||||
|
- The effective `testing` profile keeps Notarius enabled with the same pipeline
|
||||||
|
and profile while retaining the existing Scriptorium testing overrides.
|
||||||
|
- A caller can compose an additional Notarius pipeline into
|
||||||
|
`dnd_pipeline_notarius_pipelines` and select it through the corresponding
|
||||||
|
Narratio pipeline-ID variable without changing the role.
|
||||||
|
- A caller can add the optional spell-catalog source by extending the native
|
||||||
|
Narratio reference map after providing that campaign input.
|
||||||
|
- An immediate repeated role application with unchanged inputs reports no
|
||||||
|
changes.
|
||||||
|
- The production role contains no new configuration probes, validation
|
||||||
|
commands, runtime state beyond the required cache root, state bookkeeping,
|
||||||
|
duplicated root templates, secrets, extraction invocation, storage, or
|
||||||
|
publishing behavior.
|
||||||
|
|
||||||
|
### Required Validation
|
||||||
|
|
||||||
|
- YAML syntax checking and production-profile ansible-lint pass for the role
|
||||||
|
and test playbooks.
|
||||||
|
- The standalone-role integration suite explicitly selects Notarius v0.7.0,
|
||||||
|
validates a representative imported version 5 configuration through the
|
||||||
|
native CLI, and retains immediate clean repeated convergence without
|
||||||
|
asserting that v0.7.0 remains the default forever.
|
||||||
|
- The complete existing pipeline integration entry point continues to install
|
||||||
|
the pinned role combination and validate both deployed campaigns.
|
||||||
|
- A representative human account in the `narratio` group can execute native
|
||||||
|
Notarius configuration inspection through the same files used by the service
|
||||||
|
account.
|
||||||
|
- Notarius natively validates the role-managed `dnd-session` configuration.
|
||||||
|
- Notarius `config effective` exposes the composed imported pipeline and a
|
||||||
|
representative cache override without parsing managed YAML directly.
|
||||||
|
- Narratio natively validates both base and `testing` configurations with an
|
||||||
|
explicitly selected deployed campaign.
|
||||||
|
- Focused native inspection observes a representative generated Notarius
|
||||||
|
handoff and representative Narratio reference and output mappings rather
|
||||||
|
than reproducing the full application validators in shell assertions.
|
||||||
|
- A test explicitly supplies a small additional or replacement Notarius
|
||||||
|
pipeline mapping and observes that selected behavior; it does not assert
|
||||||
|
that `dnd-session` remains the role's current default forever.
|
||||||
|
- A representative test explicitly overrides one cache choice and observes
|
||||||
|
the effective Notarius configuration; it does not freeze all current cache
|
||||||
|
defaults or test Notarius's cache implementation.
|
||||||
|
- The immediate repeat reports `changed=0` and `failed=0`.
|
||||||
|
- Tests do not execute extraction, call an LLM, snapshot complete rendered
|
||||||
|
files, enumerate every nested option as an implementation lock, inspect
|
||||||
|
template task results, test filesystem metadata, or reproduce Ansible,
|
||||||
|
Notarius, Narratio, ConfigKit, or PromptKit behavior.
|
||||||
|
|
||||||
|
## Dependencies and Follow-up Work
|
||||||
|
|
||||||
|
Features 0001 through 0008 and the standalone-role test-suite simplification
|
||||||
|
are complete. Implementation of this feature depends on completing Feature
|
||||||
|
0009's shared filesystem and execution policy. It also depends on the current
|
||||||
|
Notarius v0.7.0 maintained D&D configuration and ConfigKit contract, Narratio
|
||||||
|
v2.0.0 subprocess contract, campaign sources deployed by Feature 0007, and
|
||||||
|
trimmed transcript policy defined by Feature 0008.
|
||||||
|
|
||||||
|
The next suite feature should select which extraction sources feed new or
|
||||||
|
existing Scriptorium artifacts, or address pipeline-wide credential delivery
|
||||||
|
if real end-to-end execution requires it first. Later work should cover
|
||||||
|
storage and publishing, optional operator selection and membership management,
|
||||||
|
collection assembly, release pinning, and an end-to-end workflow using actual
|
||||||
|
external services. A separate feature may add inexpensive Notarius testing
|
||||||
|
extraction if a concrete workflow justifies a second operator profile or
|
||||||
|
application configuration.
|
||||||
|
|
||||||
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
- Add explicit cache and debug retention policy once operational use provides
|
||||||
|
concrete retention requirements.
|
||||||
|
- Define credential delivery beneath the restricted `secrets/` subtree. No
|
||||||
|
further Notarius cache-permission feature is required for shared invocation.
|
||||||
|
- Pin content repositories to immutable releases when their upstream projects
|
||||||
|
begin publishing them.
|
||||||
@@ -14,9 +14,11 @@ Build independently usable Ansible roles for the five Narratio applications
|
|||||||
and compose them through a suite-level role developed in its own repository.
|
and compose them through a suite-level role developed in its own repository.
|
||||||
The `rakestraw.dnd` collection exposes that role as `rakestraw.dnd.pipeline`.
|
The `rakestraw.dnd` collection exposes that role as `rakestraw.dnd.pipeline`.
|
||||||
The suite-level role installs and configures the complete D&D transcript
|
The suite-level role installs and configures the complete D&D transcript
|
||||||
processing pipeline on a single supported host. Human operators invoke
|
processing pipeline on a single supported host. Operators or unattended
|
||||||
Narratio commands directly to process D&D session recordings and produce
|
automation invoke Narratio commands either under the dedicated `narratio`
|
||||||
transcripts and related artifacts.
|
runtime identity or under a human account that belongs to the `narratio`
|
||||||
|
group, processing D&D session recordings into transcripts and related
|
||||||
|
artifacts.
|
||||||
|
|
||||||
## Locked Decisions
|
## Locked Decisions
|
||||||
|
|
||||||
@@ -224,24 +226,40 @@ application-role releases in one source repository.
|
|||||||
- The standalone Narratio role creates a dedicated system `narratio` user and
|
- The standalone Narratio role creates a dedicated system `narratio` user and
|
||||||
`narratio` group. The account uses `/var/lib/narratio` as its default home
|
`narratio` group. The account uses `/var/lib/narratio` as its default home
|
||||||
and has a non-login shell.
|
and has a non-login shell.
|
||||||
- The `narratio` account owns Narratio's writable runtime directories.
|
- The `narratio` account owns the suite's application configuration and
|
||||||
|
writable runtime directories; `narratio` is also the shared operator group.
|
||||||
- Application source trees and installed binaries are owned by `root` and are
|
- Application source trees and installed binaries are owned by `root` and are
|
||||||
not writable by operators or the runtime account.
|
not writable by operators or the runtime account.
|
||||||
- Ordinary human users run `narratio run` and other Narratio commands directly.
|
- The supported operational model runs `narratio run` and other processing
|
||||||
- Those operators receive the required access by membership in the `narratio`
|
commands either as the dedicated `narratio` account or as a human account
|
||||||
group.
|
that is already a member of the `narratio` group. The suite does not yet
|
||||||
- Narratio's configuration directory is owned by `root:narratio` with mode
|
select those human accounts or manage their membership.
|
||||||
`0750`, and its pipeline file is owned by `root:narratio` with mode `0640`.
|
- Application configuration directories and files are owned by
|
||||||
Configuration remains under Ansible control rather than being routinely
|
`narratio:narratio`, use modes `0755` and `0644`, respectively, and are
|
||||||
edited by operators on the host.
|
world-readable. Configuration remains under Ansible control rather than
|
||||||
- The Narratio workspace, spool, and cache roots are owned by
|
being routinely edited by operators on the host.
|
||||||
`narratio:narratio` with mode `2775`, preserving the group on created content
|
- Workspace, spool, and cache roots are owned by `narratio:narratio` with mode
|
||||||
and granting the shared write access needed for direct operator invocations.
|
`2775`. Setgid and managed default ACLs preserve shared group write access
|
||||||
|
and world read/traverse access for newly created directories and files even
|
||||||
|
when invocation identities have different ordinary umasks.
|
||||||
|
- The pipeline role installs the host `acl` package and uses the declared,
|
||||||
|
pinned `ansible.posix` collection to manage access and default ACL entries on
|
||||||
|
those shared writable roots.
|
||||||
- The campaign registry root is owned by `root:narratio` with mode `0755`.
|
- The campaign registry root is owned by `root:narratio` with mode `0755`.
|
||||||
Its content is readable by operators but is populated by the suite role and
|
Its content is world-readable but is populated by the suite role and is not
|
||||||
is not edited directly on the managed host.
|
edited directly on the managed host.
|
||||||
- The standalone role does not select human operators. The suite role owns the
|
- Configuration, transcripts, caches, generated artifacts, logs, campaign
|
||||||
operator list and adds those accounts to the `narratio` group.
|
data, and prompt assets are deliberately non-secret D&D content and remain
|
||||||
|
world-readable. API keys and similar credentials are the sole confidential
|
||||||
|
category.
|
||||||
|
- Debug output is not enabled by the MVP. Any later debug feature must either
|
||||||
|
produce world-readable non-secret D&D diagnostics or identify and justify a
|
||||||
|
narrower application contract before deployment.
|
||||||
|
- Credential material will live beneath a restricted `secrets/` subdirectory
|
||||||
|
owned by `narratio:narratio`, with directories mode `0750` and files mode
|
||||||
|
`0640`. Ordinary configuration contains only credential reference names.
|
||||||
|
- [Decision 0002](../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
|
records the complete rationale and boundary for this policy.
|
||||||
|
|
||||||
### Narratio configuration
|
### Narratio configuration
|
||||||
|
|
||||||
@@ -287,6 +305,20 @@ application-role releases in one source repository.
|
|||||||
Scriptorium artifacts and families. Audita initially uses the same endpoint
|
Scriptorium artifacts and families. Audita initially uses the same endpoint
|
||||||
and models in production and testing; identical values are inherited rather
|
and models in production and testing; identical values are inherited rather
|
||||||
than duplicated in the overlay.
|
than duplicated in the overlay.
|
||||||
|
- The D&D suite enables Notarius's `auto` chunk-plan cache and checkpoint
|
||||||
|
cache beneath `/var/cache/notarius`. That FHS cache root is owned by the
|
||||||
|
`narratio` account and group with mode `2775` and the suite's shared default
|
||||||
|
ACL policy. Notarius v0.7.0 leaves cache-entry access to that deployment
|
||||||
|
policy. Chunk plans are reused automatically; checkpoints are recorded but
|
||||||
|
Narratio does not yet request their reuse.
|
||||||
|
- The standalone Notarius role exposes Notarius v0.7.0's native ConfigKit
|
||||||
|
import list while remaining independent of D&D content. The pipeline role
|
||||||
|
owns an imported `pipelines/dnd-session.yml` fragment containing its
|
||||||
|
opinionated, inventory-composable D&D pipeline map; the standalone role
|
||||||
|
continues to own only the version 5 root document.
|
||||||
|
- The Narratio `testing` profile keeps the Notarius stage enabled and inherits
|
||||||
|
the same D&D pipeline and extraction profile as production until a distinct
|
||||||
|
testing extraction policy is selected.
|
||||||
|
|
||||||
### Execution model
|
### Execution model
|
||||||
|
|
||||||
@@ -303,7 +335,10 @@ later design decision changes them:
|
|||||||
- `/usr/local/etc/narratio` for Narratio configuration
|
- `/usr/local/etc/narratio` for Narratio configuration
|
||||||
- `/usr/local/etc/audita/config.yml` for Audita configuration
|
- `/usr/local/etc/audita/config.yml` for Audita configuration
|
||||||
- `/usr/local/etc/notarius/config.yml` for Notarius configuration
|
- `/usr/local/etc/notarius/config.yml` for Notarius configuration
|
||||||
|
- `/usr/local/etc/notarius/pipelines` for suite-owned imported Notarius
|
||||||
|
pipeline definitions
|
||||||
- `/usr/local/etc/scriptorium/config.yml` for Scriptorium configuration
|
- `/usr/local/etc/scriptorium/config.yml` for Scriptorium configuration
|
||||||
|
- `/usr/local/etc/narratio/secrets` for future restricted credential material
|
||||||
- `/usr/local/share/narratio/campaigns` for version-controlled campaign data
|
- `/usr/local/share/narratio/campaigns` for version-controlled campaign data
|
||||||
- `/usr/local/share/narratio/prompt-library` for version-controlled prompts
|
- `/usr/local/share/narratio/prompt-library` for version-controlled prompts
|
||||||
and schemas
|
and schemas
|
||||||
@@ -312,6 +347,8 @@ later design decision changes them:
|
|||||||
- `/var/lib/narratio` for durable workspace and session state
|
- `/var/lib/narratio` for durable workspace and session state
|
||||||
- `/var/spool/narratio` for spool data
|
- `/var/spool/narratio` for spool data
|
||||||
- `/var/cache/narratio` for cached data
|
- `/var/cache/narratio` for cached data
|
||||||
|
- `/var/cache/notarius` for suite-provisioned Notarius chunk-plan and
|
||||||
|
checkpoint caches
|
||||||
|
|
||||||
The Narratio role creates and configures the campaign root; the pipeline role
|
The Narratio role creates and configures the campaign root; the pipeline role
|
||||||
populates it from the selected campaign source. `/usr/local/share` assumes Git
|
populates it from the selected campaign source. `/usr/local/share` assumes Git
|
||||||
@@ -342,7 +379,7 @@ The following areas require investigation and decisions before implementation:
|
|||||||
- The mechanism used to incorporate the independently developed pipeline role
|
- The mechanism used to incorporate the independently developed pipeline role
|
||||||
into collection releases
|
into collection releases
|
||||||
- Secret injection and storage
|
- Secret injection and storage
|
||||||
- Suite-level operator-selection variables
|
- Optional suite-level operator-selection and group-membership management
|
||||||
- Upgrade, downgrade, and removal behavior
|
- Upgrade, downgrade, and removal behavior
|
||||||
- Collection bootstrap and end-to-end validation details beyond the locked
|
- Collection bootstrap and end-to-end validation details beyond the locked
|
||||||
dependency and testing policies above
|
dependency and testing policies above
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Workspace Status
|
# Workspace Status
|
||||||
|
|
||||||
Last updated: 2026-09-11
|
Last updated: 2026-09-14
|
||||||
|
|
||||||
Current milestone: M1-03 suite-level pipeline role
|
Current milestone: M1-03 suite-level pipeline role
|
||||||
|
|
||||||
Current focus: Select the next unit of work.
|
Current focus: Review Feature 0009 shared pipeline filesystem and execution.
|
||||||
|
|
||||||
| ID | Deliverable | Owner | State | Evidence or next step |
|
| ID | Deliverable | Owner | State | Evidence or next step |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
@@ -15,7 +15,7 @@ Current focus: Select the next unit of work.
|
|||||||
| M0-05 | Suite-level role repository | ansible-role-dnd-pipeline | done | Repository created and added to `workspace.yml` |
|
| 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-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-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 | Feature 0007 is complete; select the next suite-policy feature |
|
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | in_progress | Review the proposed Feature 0009 shared filesystem and execution roadmap |
|
||||||
| M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism |
|
| 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` |
|
| 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 |
|
| F0002 | Install and configure Audita | ansible-role-audita | done | Field-specific configuration completed in `e61f02f` and `847c4c3`; full suite passed |
|
||||||
@@ -25,6 +25,8 @@ Current focus: Select the next unit of work.
|
|||||||
| F0006 | Establish pipeline-role composition | ansible-role-dnd-pipeline | done | Implemented and validated through remediation commit `4ea4358` |
|
| 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` |
|
| 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` |
|
| 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` |
|
||||||
|
| 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` |
|
| 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 |
|
| R0001 | Simplify completed standalone-role test suites | workspace and standalone roles | done | Role commits `e08c63c`, `d2d0b9d`, and `cfecf37` passed implementation and independent review |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user