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`.
|
||||
|
||||
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
|
||||
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,
|
||||
declare its runtime-directory policy, map its accepted outputs into Narratio,
|
||||
and enable extraction. Later features should address storage/publishing and
|
||||
secret delivery together, operator access, collection assembly, and an
|
||||
end-to-end workflow that can use actual external services.
|
||||
and enable extraction after Feature 0009 establishes shared filesystem and
|
||||
execution policy. Later features should address storage/publishing and secret
|
||||
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
|
||||
|
||||
|
||||
@@ -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.
|
||||
The `rakestraw.dnd` collection exposes that role as `rakestraw.dnd.pipeline`.
|
||||
The suite-level role installs and configures the complete D&D transcript
|
||||
processing pipeline on a single supported host. Human operators invoke
|
||||
Narratio commands directly to process D&D session recordings and produce
|
||||
transcripts and related artifacts.
|
||||
processing pipeline on a single supported host. Operators or unattended
|
||||
automation invoke Narratio commands either under the dedicated `narratio`
|
||||
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
|
||||
|
||||
@@ -224,24 +226,40 @@ application-role releases in one source repository.
|
||||
- The standalone Narratio role creates a dedicated system `narratio` user and
|
||||
`narratio` group. The account uses `/var/lib/narratio` as its default home
|
||||
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
|
||||
not writable by operators or the runtime account.
|
||||
- Ordinary human users run `narratio run` and other Narratio commands directly.
|
||||
- Those operators receive the required access by membership in the `narratio`
|
||||
group.
|
||||
- Narratio's configuration directory is owned by `root:narratio` with mode
|
||||
`0750`, and its pipeline file is owned by `root:narratio` with mode `0640`.
|
||||
Configuration remains under Ansible control rather than being routinely
|
||||
edited by operators on the host.
|
||||
- The Narratio workspace, spool, and cache roots are owned by
|
||||
`narratio:narratio` with mode `2775`, preserving the group on created content
|
||||
and granting the shared write access needed for direct operator invocations.
|
||||
- The supported operational model runs `narratio run` and other processing
|
||||
commands either as the dedicated `narratio` account or as a human account
|
||||
that is already a member of the `narratio` group. The suite does not yet
|
||||
select those human accounts or manage their membership.
|
||||
- Application configuration directories and files are owned by
|
||||
`narratio:narratio`, use modes `0755` and `0644`, respectively, and are
|
||||
world-readable. Configuration remains under Ansible control rather than
|
||||
being routinely edited by operators on the host.
|
||||
- Workspace, spool, and cache roots are owned by `narratio:narratio` with mode
|
||||
`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`.
|
||||
Its content is readable by operators but is populated by the suite role and
|
||||
is not edited directly on the managed host.
|
||||
- The standalone role does not select human operators. The suite role owns the
|
||||
operator list and adds those accounts to the `narratio` group.
|
||||
Its content is world-readable but is populated by the suite role and is not
|
||||
edited directly on the managed host.
|
||||
- Configuration, transcripts, caches, generated artifacts, logs, campaign
|
||||
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
|
||||
|
||||
@@ -287,6 +305,20 @@ application-role releases in one source repository.
|
||||
Scriptorium artifacts and families. Audita initially uses the same endpoint
|
||||
and models in production and testing; identical values are inherited rather
|
||||
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
|
||||
|
||||
@@ -303,7 +335,10 @@ later design decision changes them:
|
||||
- `/usr/local/etc/narratio` for Narratio configuration
|
||||
- `/usr/local/etc/audita/config.yml` for Audita 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/narratio/secrets` for future restricted credential material
|
||||
- `/usr/local/share/narratio/campaigns` for version-controlled campaign data
|
||||
- `/usr/local/share/narratio/prompt-library` for version-controlled prompts
|
||||
and schemas
|
||||
@@ -312,6 +347,8 @@ later design decision changes them:
|
||||
- `/var/lib/narratio` for durable workspace and session state
|
||||
- `/var/spool/narratio` for spool 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
|
||||
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
|
||||
into collection releases
|
||||
- Secret injection and storage
|
||||
- Suite-level operator-selection variables
|
||||
- Optional suite-level operator-selection and group-membership management
|
||||
- Upgrade, downgrade, and removal behavior
|
||||
- Collection bootstrap and end-to-end validation details beyond the locked
|
||||
dependency and testing policies above
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Workspace Status
|
||||
|
||||
Last updated: 2026-09-11
|
||||
Last updated: 2026-09-14
|
||||
|
||||
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 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
@@ -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` |
|
||||
| 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 | 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 |
|
||||
| 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,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` |
|
||||
| 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` |
|
||||
| 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 |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user