Plan D&D asset deployment

This commit is contained in:
2026-09-10 15:37:00 +00:00
parent e46c8182f1
commit 5fdd92b297
4 changed files with 970 additions and 21 deletions

View File

@@ -0,0 +1,348 @@
# Feature 0007: D&D Asset Deployment and Scriptorium Integration
Status: ready
## Summary
Extend the standalone D&D pipeline role to deploy the authoritative campaign
registry and Narratio prompt library, then connect those assets to Narratio
and Scriptorium through the application roles' existing public interfaces.
The result is an assembled suite in which Narratio can resolve a deployed
campaign and Scriptorium can discover the deployed D&D prompts and schemas.
## Problem or Opportunity
Feature 0006 composes and configures all five applications, but intentionally
leaves the suite's content roots empty. A consumer still has to deploy the
`campaigns` and `narratio-prompts` repositories separately and override
application configuration before the installed tools can find that content.
Both authoritative content repositories are now present in the workspace.
Their layouts make the required integration concrete: the campaign repository
is already organized as Narratio's campaign registry, while the prompt
repository contains top-level `prompts/` and `schemas/` trees. The prompt
repository does not contain execution profiles, so this feature must not
invent or configure a profile directory on its behalf.
Inspection also found four stale references in the current prompt content.
The character-analysis and session-recap definitions name a shared Markdown
file that does not exist under that name, and the two JSON-schema prompts name
schema paths that do not match the repository's `schemas/` layout. Deploying
those definitions without correcting their source would leave known-broken
suite content.
Both campaign definitions also retain an `inputs.players_file` field that
Narratio 2.0 rejects, and both `party.yml` documents use Narratio's legacy
list format. Narratio's canonical party model now obtains player identity from
a versioned `party_file`; the obsolete field must be removed and the party
documents migrated before either deployed campaign can pass native
configuration validation.
## Governing Policies
- [The Ansible house style](../../ansible.md) governs the role interface,
direct desired-state tasks, privilege escalation, and downstream role
configuration.
- [The testing house style](../../testing.md) governs focused native outcome
coverage and clean repeated convergence.
- [The MVP roadmap](../mvp.md) assigns campaign and prompt deployment to the
pipeline role, fixes the campaign registry location, and requires the
prompt library to track upstream until it publishes releases.
- [Decision 0001](../../decisions/0001-minimal-module-driven-ansible.md)
requires module-owned convergence without supplemental state or redundant
verification.
## Scope
- Add suite-owned repository URL, revision, and installation-root variables
for campaign and prompt content.
- Default both repositories to their authoritative Gitea origins and the
`main` branch, while allowing a caller to select another branch, tag,
commit, origin, or local Git fixture.
- Check out the campaign repository directly at
`/usr/local/share/narratio/campaigns` by default.
- Check out the prompt repository directly at
`/usr/local/share/narratio/prompt-library` by default.
- Treat both Git checkouts as root-managed, remotely authoritative content
that is updated during ordinary role convergence.
- Pass the selected campaign root to the Narratio role.
- Pass `<prompt-library-root>/prompts` and
`<prompt-library-root>/schemas` to the Scriptorium role as its native prompt
and schema directories.
- Leave Scriptorium's profile directory unset; the prompt repository does not
provide profiles.
- Remove the obsolete `inputs.players_file` declaration from both campaign
definitions while retaining their `party_file` inputs.
- Migrate both legacy party lists to the `narratio.party.v1` document shape,
preserving their supported character, player, class, and level data.
- Correct the two invalid shared-content references and the two invalid schema
paths in the authoritative `narratio-prompts` repository.
- Align pipeline-role defaults, argument specifications, dependency metadata,
README documentation, and focused integration coverage with the expanded
suite contract.
## Non-goals
- Defining Scriptorium execution profiles, model backends, API endpoints, or
credentials.
- Selecting the final D&D prompt/profile combinations used by Narratio stages
and artifacts.
- Defining the broader opinionated Audita, Narratio, Notarius, Seriatim, or
Scriptorium processing policy; that remains a later pipeline feature.
- Enabling Notarius or defining its D&D pipelines.
- Managing human operators or their group membership.
- Delivering secrets or environment files.
- Supporting non-Git asset sources, archive downloads, local overlay trees,
per-campaign selection, or merges of multiple campaign repositories.
- Making managed-host edits coexist with the authoritative repositories.
- Purging untracked files, maintaining asset manifests, recording deployed
commits in sidecar state, or adding independent drift/integrity checks.
- Adding an asset-specific release mechanism before either content repository
publishes releases.
- Running a real LLM request, WhisperX request, or end-to-end transcript.
- Re-testing the standalone roles' installation and configuration matrices.
- Incorporating the pipeline role into `rakestraw.dnd` or publishing a role or
collection release.
## Target End State
Applying `rakestraw.dnd_pipeline` on a supported host installs the application
suite and converges two root-managed Git working trees. The campaign checkout
itself is Narratio's campaign registry, so its top-level campaign directories
are immediately addressable by campaign ID. The prompt-library checkout
contains its native `prompts/` and `schemas/` subdirectories without copied or
rearranged content.
Narratio's managed pipeline configuration uses the same suite-selected
campaign root that the pipeline role populates. Scriptorium's managed
configuration points its `prompt_dir` and `schema_dir` fields to the
corresponding subdirectories of the suite-selected prompt root. Its
`profile_dir` remains omitted unless a caller or later suite-policy feature
provides one.
By default, each convergence fetches and reconciles the `main` branch of both
content repositories. A caller that needs reproducibility can select an
immutable commit through the corresponding revision variable. Ordinary Git
module change detection reports content updates, and an immediate repeat with
unchanged upstream state reports no changes.
The corrected prompt repository is internally consistent with its installed
layout: shared content files named by prompt definitions exist relative to the
definitions, and schema paths resolve relative to Scriptorium's configured
schema root. No compatibility links or installation-time content rewrites are
needed.
## Repository Ownership
- `ansible-role-dnd-pipeline` owns the suite asset variables, Git checkout
tasks, application-role variable wiring, documentation, and integration
coverage. It is the primary implementation repository.
- `assets/narratio-prompts` owns prompt definitions and their internal content
and schema references. It changes only to correct the four discovered stale
references; the pipeline role does not patch content at deployment time.
- `assets/campaigns` owns the campaign registry content and layout. It changes
only to remove the obsolete `players_file` fields and migrate the two party
documents to Narratio's current native schema; the pipeline role does not
rewrite campaign content at deployment time.
- `ansible-role-narratio` and `ansible-role-scriptorium` remain unchanged and
are read-only authorities for their public configuration variables.
- `../narratio` and `../scriptorium` remain read-only authorities for native
content discovery and validation behavior.
- `rakestraw-ansible` is a read-only historical reference. Its older
`/usr/local/etc` asset layout and monolithic deployment tasks are not copied.
- `ansible-workspace-dnd` owns this roadmap, the later staged implementation
plan, the settled MVP decisions, and aggregate status.
- `ansible-collection-dnd` remains unchanged until collection assembly is
selected.
## Constraints and Settled Decisions
- The public additions are:
| Variable | Default | Purpose |
| --- | --- | --- |
| `dnd_pipeline_campaigns_repository_url` | `https://gitea.maximumdirect.net/eric/campaigns.git` | Authoritative campaign Git origin |
| `dnd_pipeline_campaigns_revision` | `main` | Campaign branch, tag, or commit |
| `dnd_pipeline_campaigns_root` | `/usr/local/share/narratio/campaigns` | Campaign checkout and Narratio registry root |
| `dnd_pipeline_prompt_library_repository_url` | `https://gitea.maximumdirect.net/eric/narratio-prompts.git` | Authoritative prompt-library Git origin |
| `dnd_pipeline_prompt_library_revision` | `main` | Prompt-library branch, tag, or commit |
| `dnd_pipeline_prompt_library_root` | `/usr/local/share/narratio/prompt-library` | Prompt-library checkout root |
- Both repositories currently have no release tags. Tracking `main` is the
deliberate suite default; callers can opt into commit pinning without a
separate update switch.
- `ansible.builtin.git` owns checkout creation, fetch/update behavior, tracked
content convergence, and change reporting. The role does not run Git
commands, compare commits, or persist revision state separately.
- `update: true` and `force: true` express that the configured remote revision
owns tracked content. The role does not separately remove untracked files.
- The role performs the privileged content operations with task-level
`become: true`.
- The Narratio dependency creates the campaign root as `root:narratio` mode
`0755`. The pipeline role reuses that root rather than duplicating its
directory task.
- The pipeline role creates the prompt-library root as `root:narratio` mode
`0755` before checkout. Repository files retain their Git modes and remain
operator-readable; no recursive permission normalization is required.
- The pipeline role passes `dnd_pipeline_campaigns_root` as
`narratio_campaigns_root`,
`dnd_pipeline_prompt_library_root ~ '/prompts'` as
`scriptorium_prompt_dir`, and
`dnd_pipeline_prompt_library_root ~ '/schemas'` as
`scriptorium_schema_dir` through ordinary dependency metadata.
- `scriptorium_profile_dir` is not set by this feature. The default profile IDs
named by prompt definitions do not create profile definitions, and selecting
usable suite profiles belongs with the later D&D application-policy work.
- The prompt source corrections use the paths actually present in the
repository: `../common/previous_recap.user.md`,
`analyze/scene_map.schema.json`, and `trim/bounds.schema.json`.
- The campaign source corrections remove `inputs.players_file` from
`centaurs/campaign.yml` and `dilfs/campaign.yml`. The existing
`inputs.party_file` field remains the canonical party source.
- Each party document uses `schema_version: narratio.party.v1` and a
`characters` map. Stable character IDs are the lowercase underscore forms
of their names: `krek`, `rick_oathbreaker`, `tlann`,
`torvass_oathbreaker`, `hrank_greenfield`, `alan_hohey`, `svend_balderk`,
and `popov`.
- Each character retains its player name, display name, class, and level in
the corresponding native nested fields. Legacy `category: pc` is implicit
in membership in the canonical character map. Legacy free-form notes are
retained as adjacent YAML comments because `narratio.party.v1` has no note
field. Popov's evident `pladin` typo is corrected to `paladin` during the
otherwise mechanical migration.
- The now-unused `players.yml` files are not deleted or otherwise repurposed
by this feature.
- The existing dependency-management switch is not expanded. With
`dnd_pipeline_manage_build_dependencies: true`, the composed application
roles install Git before pipeline tasks execute. A caller that disables
dependency management remains responsible for providing Git as well as Go.
- Repository URLs and revisions are data, not secrets. No credentials are
added to role defaults or tests.
## Simplest Viable Implementation
The production change should remain a small extension of the composition
role:
1. Remove the obsolete `players_file` field from both campaign definitions
and migrate both party documents to `narratio.party.v1`.
2. Correct the four stale paths in the prompt source repository.
3. Add and type the six asset variables.
4. Map the campaign root and prompt/schema directories into the existing
Narratio and Scriptorium dependency variables.
5. Declare the prompt-library root with `ansible.builtin.file`.
6. Converge the campaign and prompt repositories with two
`ansible.builtin.git` tasks.
7. Update consumer documentation and extend the existing integration driver
with the asset-specific native outcomes and clean repeat.
No preliminary `stat`, remote revision query, registered-result conditional,
handler, checksum, manifest, or post-checkout permission sweep is required.
The file and Git modules already own the selected desired states.
## Rationale and Alternatives
Checking each repository out directly at its installed root preserves the
upstream layout and makes updates a single module-owned operation. Copying
files from a separate checkout would add a second synchronization boundary,
and installing compatibility links for stale prompt references would encode
source defects into deployment logic. Correcting those paths at their source
is smaller and makes the asset repository useful outside this role as well.
The dedicated `/usr/local/share/narratio/prompt-library` root makes the
relationship clear without producing a confusing `prompts/prompts` path.
Its `prompts/` and `schemas/` children map directly to Scriptorium's native
configuration fields. `/usr/local/share` is appropriate for host-wide,
root-managed, architecture-independent application data and is consistent
with the already selected campaign location.
One suite root variable per content repository keeps the Git destination and
application configuration coupled. Hard-coding each path independently would
permit accidental divergence, while exposing separate checkout and installed
paths would add flexibility for which no consumer requirement exists.
Tracking `main` matches the prompt-library policy already selected for the MVP
and is also the practical campaign default while that repository has no
releases. A single revision variable still permits immutable deployments.
Adding an update boolean would create overlapping modes without improving that
choice: selecting a commit already fixes content, and selecting a branch
expresses the intent to follow it.
## Acceptance Criteria
### Required Asset Behavior
- Applying the pipeline role checks out the configured campaign repository at
`dnd_pipeline_campaigns_root` and the configured prompt repository at
`dnd_pipeline_prompt_library_root`.
- The default origins, revisions, and roots match the fixed public interface.
- A caller can replace either origin, revision, or root through its suite
variable without editing role tasks or dependency metadata.
- Narratio's managed configuration names the exact campaign root populated by
the pipeline role.
- Scriptorium's managed configuration names the deployed `prompts/` and
`schemas/` directories and does not acquire a profile directory from this
feature.
- Both deployed campaign definitions and their versioned party documents
conform to Narratio 2.0's canonical party-input contract and pass native
validation by campaign ID.
- The two prompt definitions that use previous-recap content load the existing
`previous_recap.user.md` file, and both JSON-schema definitions resolve
paths beneath the configured schema directory.
- The managed content roots are root-owned and operator-readable. Runtime and
operator accounts do not receive write access through this feature.
- Upstream changes to a selected branch are applied by a later role run;
selecting an immutable commit produces stable content.
- An immediate repeated role application with unchanged inputs and upstream
state reports no changes.
- The role contains no content copies, deployment-time prompt rewrites,
redundant state probes, revision sidecars, checksums, or production
self-validation.
- Only `ansible-role-dnd-pipeline`, `assets/campaigns`,
`assets/narratio-prompts`, and workspace planning/status documentation
change.
### Required Validation
- YAML syntax checking and production-profile ansible-lint pass for the role
and its test playbooks.
- The integration driver uses explicit repository URL and revision inputs for
controlled local Git fixtures rather than depending on mutable network
state.
- Narratio natively validates its managed pipeline configuration with a
campaign selected by ID from the deployed registry.
- Scriptorium natively inspects a deployed prompt through its managed
configuration, including a representative definition that uses the repaired
shared-content path.
- A representative JSON-schema prompt has a schema path that resolves beneath
the configured deployed schema directory.
- The asset-enabled baseline is followed immediately by a convergence that
reports no changes.
- Existing suite version-forwarding coverage remains intact; the feature does
not repeat standalone application installation matrices.
- Tests do not assert current default revisions as immutable facts, enumerate
every asset as a snapshot, inspect Git internals, trace task execution, or
re-test `ansible.builtin.file` and `ansible.builtin.git` behavior.
## Dependencies and Follow-up Work
Feature 0006 and all five standalone roles are complete. The managed host must
be able to reach the selected content repositories unless callers provide
local origins. The narrow campaign and prompt source corrections must be
committed before an integration test pins or checks out their resulting
revisions.
The next suite-policy feature should select actual Scriptorium profiles and
backends together with Narratio prompt IDs, artifacts, and other opinionated
D&D application settings. Operator access, secret delivery, end-to-end
processing validation, and collection assembly also remain separate work.
Before a suite or collection release, both asset repositories need an explicit
release policy. If they begin publishing immutable releases, the suite should
replace its branch defaults with compatible released revisions.
## Potential Future Hardening
- Verify signed asset releases when the repositories publish them.
- Protect managed checkouts against hostile repository ownership changes.
- Provide a controlled offline mirror or packaged asset artifact.

View File

@@ -1,14 +1,589 @@
# Implementation Plan
# Implementation Plan 0007: Deploy D&D Assets and Integrate Scriptorium
Status: pending
Status: ready
No implementation plan is currently active. Feature 0006 was implemented in
`ansible-role-dnd-pipeline` commits `b515968` and `61869d1`, independently
reviewed, and finalized by remediation commit `4ea4358`.
Target executor: GPT-5.6-Terra
Its durable scope and rationale remain in
[the Feature 0006 roadmap](features/0006-pipeline-role-composition-foundation.md),
and its final review record remains in [the remediation record](remediation.md).
Feature roadmap:
[Feature 0007: D&D Asset Deployment and Scriptorium Integration](features/0007-dnd-asset-deployment-and-scriptorium-integration.md)
Select and approve the next unit of work before replacing this notice with a
new staged implementation plan.
Active plan location: `docs/roadmap/implementation.md`
## Objective
Implement the asset layer selected by Feature 0007. Correct the known-invalid
campaign and prompt references in their authoritative repositories, extend
`rakestraw.dnd_pipeline` with the six approved asset inputs and three direct
desired-state tasks, connect the deployed roots to Narratio and Scriptorium,
and prove the assembled behavior through native application interfaces and an
immediate clean repeat.
The feature roadmap remains authoritative for scope, rationale, target end
state, public variables, filesystem layout, and acceptance criteria.
## Execution Rules
- Execute Stage 1 through Stage 4 in numeric order.
- Immediately before each stage, read every document in that stage's Required
Policy Review, then confirm its preconditions and the owning repository's
working-tree state. Do not rely on policy recalled from an earlier stage.
- Modify only the repository named for the active stage. Preserve unrelated
changes and stop if that repository is unexpectedly dirty.
- Correct asset defects in their source repositories; do not compensate for
them with pipeline-role copies, rewrites, symlinks, or compatibility trees.
- Implement the production role with one `ansible.builtin.file` task and two
`ansible.builtin.git` tasks. Do not add preliminary probes, registered-result
conditionals, handlers, revision queries, checksums, manifests, cleanup
commands, or recursive metadata passes.
- Use task-level `become: true` for the three privileged pipeline tasks. Do not
require play-level escalation.
- Configure the existing application roles only through their public
variables. Do not modify or reproduce their templates or tasks.
- Do not set `scriptorium_profile_dir`, invent execution profiles, select
model backends, enable Notarius, or add the later opinionated D&D processing
policy.
- Let `ansible.builtin.git` own creation, update, tracked-content convergence,
and change reporting. Use the roadmap-selected `update: true` and
`force: true`; do not separately purge untracked files.
- Keep tests at the suite-content boundary. Use explicit local Git origins and
revisions for controlled inputs, then observe campaign and prompt discovery
through Narratio and Scriptorium. Do not inspect Git internals or re-test the
file and Git modules.
- Retain the existing Feature 0006 composition and explicit-version coverage.
Do not reproduce any standalone role's installation or configuration
matrix.
- Never place credentials or secret values in content, plans, examples, or
tests.
- Run every stage's validation before committing it. Do not begin a dependent
stage after an earlier stage fails.
- Commit each completed stage with its specified plain-English message. Do not
push during out-of-band implementation.
## Starting State and Preconditions
- Feature 0006 is complete and independently reviewed.
- This plan, the agreed Feature 0007 roadmap, the corresponding MVP decisions,
and workspace status are committed before out-of-band execution begins.
- `assets/narratio-prompts` is clean on `main` at
`eef72b7d822a97d3e398a05f48bbfa20a2a6c109`, tracking `origin/main`
without divergence.
- `assets/campaigns` is clean on `main` at
`bb0aedf36a9a510d90a36e4df6b2c5c63135c025`, tracking `origin/main`
without divergence.
- `ansible-role-dnd-pipeline` is clean on `main` at
`4ea43580f66867d95ac23804554b07b67dbbaaee`, tracking `origin/main`
without divergence.
- The local controller and managed-host proxy are Ubuntu 26.04 `x86_64`, with
gathered facts and passwordless task-level privilege escalation available.
Local execution remains the approved proxy for both supported host
architectures during this MVP.
- Workspace tooling is available in `.venv`: Ansible Core 2.21.3 and
ansible-lint 26.8.0. Scriptorium `v0.13.0` and Narratio `v2.0.0` are
available through the completed roles for native validation.
- `community.general` 13.3.0 and Go Snap channel `1.26/stable` remain
available. The existing pipeline integration entry point passes before
implementation begins.
- The two local asset repositories are valid Git origins. Stage 4 may use
their absolute `file://` URLs and explicit commit revisions without copying
their content into the pipeline-role repository.
- The prompt repository contains no execution profiles. The current source
defects are limited to the four references identified by the feature
roadmap:
- two uses of `../common/transcript.previous_recap.md` must name the existing
`../common/previous_recap.user.md` file;
- `pipeline-dnd/analyze/scene_map.schema.json` must resolve as
`analyze/scene_map.schema.json`; and
- `automation-pipeline-dnd/trim/bounds.schema.json` must resolve as
`trim/bounds.schema.json`.
- Both campaign definitions contain an obsolete `inputs.players_file` field
that Narratio 2.0 rejects. Their existing `inputs.party_file` fields remain
the canonical party sources, but the referenced documents still use the
legacy `party` list rather than `narratio.party.v1`.
## Repository Scope
Repositories that change:
- `assets/campaigns`: owns the two campaign-input corrections and two party
schema migrations in Stage 1.
- `assets/narratio-prompts`: owns the four prompt-definition path
corrections in Stage 2.
- `ansible-role-dnd-pipeline`: owns the public asset interface, downstream
role wiring, direct deployment tasks, README, and integration coverage in
Stages 3 and 4.
Repositories that may be inspected but must remain unchanged:
- `ansible-workspace-dnd`: authoritative roadmap, plan, policies, inventory,
and status during out-of-band execution.
- `ansible-role-narratio` and `ansible-role-scriptorium`: authoritative public
role interfaces.
- The other standalone application roles and all five application source
repositories.
- `ansible-collection-dnd`: future collection assembly target.
- `rakestraw-ansible`: historical style and deployment reference.
- Every other repository in `workspace.yml`.
## Stage 1: Align Campaign Definitions with Narratio 2.0
### Objective
Make both authoritative campaigns valid under Narratio 2.0's canonical
party-input contract by removing the obsolete input and mechanically migrating
the party documents without deleting legacy source files.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/testing.md`
### Preconditions
- `assets/campaigns` is at the starting revision above and has no uncommitted
changes.
- Both `centaurs/campaign.yml` and `dilfs/campaign.yml` contain a valid
`inputs.party_file` value and the obsolete `inputs.players_file` value.
- Both referenced `party.yml` files contain the legacy list entries documented
by the feature roadmap and have not already been partially migrated.
- `/usr/local/bin/narratio` is available for native campaign validation. If it
is unavailable, stop and report the missing completed-role prerequisite
rather than modifying application source or installing an unplanned
substitute.
### Owning Repository
`assets/campaigns`
### Required Changes
1. Remove only the `inputs.players_file` entry from `centaurs/campaign.yml`
and `dilfs/campaign.yml`. Retain each `party_file` entry and all other
campaign fields unchanged.
2. Replace each legacy `party` list with a `narratio.party.v1` document using
`schema_version` and a `characters` map.
3. Use exactly these stable character IDs: `krek`, `rick_oathbreaker`,
`tlann`, `torvass_oathbreaker`, `hrank_greenfield`, `alan_hohey`,
`svend_balderk`, and `popov`.
4. For every character, preserve the authored player name and character
display name. Convert the single legacy class and level into one entry in
`character.classes`. Correct Popov's evident class typo from `pladin` to
`paladin`.
5. Omit the legacy `category: pc` field because character membership is
implicit in the native map. Preserve each free-form legacy note as an
adjacent YAML comment because the strict native schema has no note field.
6. Do not delete or rewrite either `players.yml` file. Removing or migrating
unused legacy files is not required for native campaign validity and is
outside this feature.
### Validation
Create `/tmp/dnd-pipeline-feature-0007.yml` with this temporary minimal
configuration:
```yaml
workspace:
root: /tmp/dnd-pipeline-feature-0007-workspace
campaigns:
root: /home/eric/Workspace/ansible-dnd/assets/campaigns
spool:
root: /tmp/dnd-pipeline-feature-0007-spool
cache:
root: /tmp/dnd-pipeline-feature-0007-cache
whisperx:
transcribe_url: http://127.0.0.1:8000/transcribe
```
From `assets/campaigns`, run:
```text
/usr/local/bin/narratio config validate --config /tmp/dnd-pipeline-feature-0007.yml --campaign centaurs
/usr/local/bin/narratio config validate --config /tmp/dnd-pipeline-feature-0007.yml --campaign dilfs
git diff --check
git status --short
```
Delete only the temporary configuration after validation. Expected result:
Narratio natively validates both campaigns by registry ID; whitespace
validation passes; and only the two `campaign.yml` and two `party.yml` files
are modified.
### Completion Criteria
- Neither campaign definition contains `inputs.players_file`.
- Both retain `inputs.party_file`, whose document uses
`schema_version: narratio.party.v1` and the roadmap's fixed character IDs.
- Player, character, class, level, and note information survives the migration
in supported native fields or adjacent comments, with only the selected
`paladin` typo correction.
- Both campaigns pass Narratio's native configuration validation.
- No `players.yml` or unrelated asset changes.
### Commit
Commit intent: `Align campaign definitions with Narratio`
## Stage 2: Correct the Prompt Library's Internal References
### Objective
Make the authoritative prompt repository internally consistent with its own
`prompts/` and `schemas/` layout so the pipeline role can deploy it without
content transformation or compatibility artifacts.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/testing.md`
### Preconditions
- Stage 1 is committed and `assets/campaigns` is otherwise clean.
- `assets/narratio-prompts` is at the starting revision above and has no
uncommitted changes.
- The existing shared content file is
`prompts/analyze/common/previous_recap.user.md`.
- The existing schema files are `schemas/analyze/scene_map.schema.json` and
`schemas/trim/bounds.schema.json`.
- `/usr/local/bin/scriptorium` is available for read-only native prompt
inspection. If it is unavailable, stop and report the missing completed-role
prerequisite rather than modifying application source or installing an
unplanned substitute.
### Owning Repository
`assets/narratio-prompts`
### Required Changes
1. In
`prompts/analyze/character_meta_analysis/character_meta_analysis.yml` and
`prompts/analyze/session_recap/recap.yml`, replace the nonexistent shared
content reference with `../common/previous_recap.user.md`.
2. In `prompts/analyze/scene_map/scene_map.yml`, set `output.schema_path` to
`analyze/scene_map.schema.json`, relative to the configured schema root.
3. In `prompts/trim/bounds.yml`, set `output.schema_path` to
`trim/bounds.schema.json`, relative to the configured schema root.
4. Make no other editorial, prompt-content, version, profile, schema-content,
or layout changes. Do not rename files or add compatibility links.
### Validation
From `assets/narratio-prompts`, run:
```text
/usr/local/bin/scriptorium inspect prompt --prompt-dir "$PWD/prompts" --prompt dnd.character_meta_analysis --prompt-version 2.0.0 --format json
/usr/local/bin/scriptorium inspect prompt --prompt-dir "$PWD/prompts" --prompt dnd.session_recap --prompt-version 2.0.0 --format json
../../.venv/bin/python - <<'PY'
from pathlib import Path
import yaml
root = Path.cwd()
definitions = (
root / "prompts/analyze/scene_map/scene_map.yml",
root / "prompts/trim/bounds.yml",
)
for definition in definitions:
document = yaml.safe_load(definition.read_text())
schema = root / "schemas" / document["output"]["schema_path"]
if not schema.is_file():
raise SystemExit(f"missing schema for {definition}: {schema}")
PY
git diff --check
git status --short
```
Expected result: Scriptorium loads both definitions that previously named the
missing shared file; both schema paths resolve to real files beneath
`schemas/`; whitespace validation passes; and only the four intended YAML
definitions are modified.
### Completion Criteria
- All four stale paths use the repository's actual shared-content and schema
layout.
- Both corrected shared-content definitions load through Scriptorium's native
inspection interface.
- Both schema references resolve relative to the repository's `schemas/`
directory.
- No prompt semantics, IDs, versions, profiles, schemas, or unrelated assets
change.
### Commit
Commit intent: `Correct prompt asset references`
## Stage 3: Add Minimal Asset Deployment to the Pipeline Role
### Objective
Implement the complete production asset interface, application-role wiring,
and module-driven deployment flow without adding test or verification logic to
role convergence.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
### Preconditions
- Stage 1 and Stage 2 are committed, and both asset repositories are otherwise
clean.
- Record both asset commits for Stage 4's explicit local revisions.
- `ansible-role-dnd-pipeline` is at the starting revision above and has no
uncommitted changes.
- The pipeline role's existing Feature 0006 defaults, argument
specifications, dependency declarations, and empty task file remain intact.
- The completed Narratio role accepts `narratio_campaigns_root`; the completed
Scriptorium role accepts `scriptorium_prompt_dir` and
`scriptorium_schema_dir`.
### Owning Repository
`ansible-role-dnd-pipeline`
### Required Changes
1. Add exactly these six defaults to `defaults/main.yml`:
- `dnd_pipeline_campaigns_repository_url` with
`https://gitea.maximumdirect.net/eric/campaigns.git`;
- `dnd_pipeline_campaigns_revision` with `main`;
- `dnd_pipeline_campaigns_root` with
`/usr/local/share/narratio/campaigns`;
- `dnd_pipeline_prompt_library_repository_url` with
`https://gitea.maximumdirect.net/eric/narratio-prompts.git`;
- `dnd_pipeline_prompt_library_revision` with `main`; and
- `dnd_pipeline_prompt_library_root` with
`/usr/local/share/narratio/prompt-library`.
2. Add matching argument-specification entries with concise descriptions.
Use `str` for origins and revisions and `path` for roots. All six are
required at role invocation because defaults always define them.
3. In `meta/main.yml`, pass `dnd_pipeline_campaigns_root` to the Narratio
dependency as `narratio_campaigns_root`.
4. In the Scriptorium dependency, pass the prompt root's `prompts` child as
`scriptorium_prompt_dir` and its `schemas` child as
`scriptorium_schema_dir`. Use clear Jinja path expressions and do not set
`scriptorium_profile_dir`.
5. Replace the empty production task list with exactly three tasks:
- declare `dnd_pipeline_prompt_library_root` as a directory owned by
`root:narratio` with mode `0755` using `ansible.builtin.file`;
- converge the campaign Git origin and revision directly at
`dnd_pipeline_campaigns_root`; and
- converge the prompt-library Git origin and revision directly at
`dnd_pipeline_prompt_library_root`.
6. For both `ansible.builtin.git` tasks, set `repo`, `dest`, and `version` from
the corresponding public variables and set `update: true` and
`force: true`. Apply `become: true` to all three tasks.
7. Do not duplicate the campaign-root directory declaration already owned by
the Narratio dependency. Do not register task results, add `when`
conditions, run handlers or commands, normalize repository contents
recursively, purge untracked files, or validate content during production
convergence.
8. Update the README to document automatic campaign and prompt-library
deployment, all six asset variables and defaults, branch-following and
immutable-commit selection, the direct installed layouts, Narratio and
Scriptorium path wiring, and the remaining profile/backend/credential and
D&D-policy deferrals.
9. Clarify that callers disabling common dependency management must provide
both Git and Go. Remove Feature 0006 language claiming campaign and prompt
content are deferred, but do not document unimplemented operators, secrets,
removal, profiles, or end-to-end processing.
### Validation
From `ansible-role-dnd-pipeline`, run:
```text
../.venv/bin/ansible-playbook -i tests/inventory --syntax-check tests/converge.yml
../.venv/bin/ansible-lint --offline --profile production tests/converge.yml
git diff --check
git status --short
```
Expected result: Ansible accepts the expanded public interface, dependency
wiring, and three-task production role; production-profile lint passes; and
only intended defaults, metadata, task, and README files are modified. Full
asset convergence is deferred to Stage 4's controlled integration inputs.
### Completion Criteria
- Defaults and argument specifications expose exactly the six selected asset
inputs in addition to the existing Feature 0006 interface.
- Narratio receives the same campaign root the Git task populates.
- Scriptorium receives the deployed `prompts/` and `schemas/` children and no
profile directory.
- Production convergence consists of one direct directory declaration and two
direct Git declarations, all with task-level privilege escalation.
- README documentation matches the implemented asset contract and remaining
deferrals.
- Syntax, lint, and whitespace checks pass without test-specific production
logic.
### Commit
Commit intent: `Deploy D&D pipeline assets`
## Stage 4: Add Focused Asset Integration Coverage
### Objective
Demonstrate that the real pipeline role deploys controlled campaign and prompt
repositories, connects them to the native applications, and coalesces cleanly
without testing trusted module internals or freezing mutable defaults.
### Required Policy Review
Before beginning this stage, read:
- `AGENTS.md`
- `docs/orientation.md`
- `docs/conventions.md`
- `docs/ansible.md`
- `docs/testing.md`
### Preconditions
- Stage 1 through Stage 3 are committed, and all three owning repositories are
otherwise clean.
- Stage 3 static validation passes.
- The Stage 1 campaign commit and Stage 2 prompt commit are available from the
local Git repositories.
- The existing integration driver still bootstraps exact application-role and
collection dependencies into private temporary paths, exercises the
Feature 0006 baseline and explicit Seriatim selection, and restores the
baseline suite during cleanup.
- No test requires network access to the two default content origins. Network
access needed by the existing application-role dependency and source-build
flow remains unchanged.
### Owning Repository
`ansible-role-dnd-pipeline`
### Required Changes
1. Extend the existing `tests/integration` entry point rather than adding a
new framework or scenario tree.
2. Resolve the absolute local paths of `../assets/campaigns` and
`../assets/narratio-prompts` relative to the pipeline repository. Resolve
each repository's current commit with read-only Git commands.
3. Add explicit baseline extra variables selecting those two local Git origins
with `file://` URLs and their resolved immutable commits. Reuse the same
explicit asset inputs for every convergence and cleanup invocation.
Continue to supply the test WhisperX URL.
4. Do not assert that either selected commit or `main` is the role's current
default. The explicit revisions are controlled test inputs, not snapshots
of suite policy.
5. After baseline convergence, use Narratio's native configuration validator
as the `narratio` account with the managed pipeline configuration and a
campaign ID present in the deployed campaign registry, such as `centaurs`.
Replace the less specific campaign-free validation where redundant.
6. Use Scriptorium's native `inspect prompt` interface with its managed
configuration to load a deployed prompt whose repaired shared content is
required, such as `dnd.session_recap` version `2.0.0`.
7. Inspect one deployed JSON-schema prompt through Scriptorium and verify that
the schema path reported by that native definition resolves beneath the
configured deployed schema directory. This is an integration assertion
about the prompt-library contract; do not inspect Git metadata or duplicate
the Git task's file and ownership arguments.
8. Immediately reapply the identical asset-enabled baseline and require the
aggregate recap to report `changed=0` and `failed=0`.
9. Retain the explicit Seriatim `v1.4.0` forwarding case and its immediate
clean repeat. Include the same controlled asset inputs so version coverage
does not switch content sources or fetch mutable asset branches.
10. Ensure best-effort cleanup reapplies the asset-enabled baseline and removes
only the integration driver's private temporary directory. Do not delete
the managed campaign or prompt roots, source trees, binaries, runtime
areas, or any caller content.
11. Update the README validation description only as needed to describe native
campaign resolution, deployed prompt/schema discovery, controlled local
asset inputs, clean repetition, and the retained version-forwarding case.
12. Do not add assertions for file ownership, modes, directory existence,
checkout revisions, remote update mechanics, task order, task results,
exact current defaults, every campaign, or every prompt. Do not run a real
backend, WhisperX request, or transcript workflow.
### Validation
From `ansible-role-dnd-pipeline`, run:
```text
bash -n tests/integration
tests/integration
git diff --check
git status --short
```
Expected result: fresh dependency bootstrap, syntax checking, and
production-profile lint pass; controlled local asset revisions deploy through
the real role; Narratio validates a campaign selected from the deployed
registry; Scriptorium loads the repaired prompt and resolves a deployed schema;
the baseline and explicit-version repeats both report `changed=0` and
`failed=0`; cleanup restores the asset-enabled compatible baseline; and only
the intended integration-driver and README changes are present.
### Completion Criteria
- The integration suite uses explicit local Git origins and immutable
revisions without freezing the role's mutable defaults.
- Narratio proves campaign discovery through its native validator.
- Scriptorium proves prompt discovery through its managed configuration and a
representative deployed schema resolves under the configured schema root.
- Immediate repeated convergence is clean with the asset layer enabled.
- Existing application-composition and version-forwarding behavior remains
covered and successful.
- No trusted-module tests, task-trace assertions, broad asset snapshots, or
unrelated test matrices are added.
### Commit
Commit intent: `Add focused asset integration coverage`
## Final Validation and Handoff
After Stage 4, run:
```text
cd assets/campaigns
git log --oneline -1
git status --short --branch
cd ../narratio-prompts
/usr/local/bin/scriptorium inspect prompt --prompt-dir "$PWD/prompts" --prompt dnd.session_recap --prompt-version 2.0.0 --format json
git log --oneline -1
git status --short --branch
cd ../../ansible-role-dnd-pipeline
tests/integration
git log --oneline -2
git status --short --branch
cd ..
./scripts/status
```
Report the Stage 1 campaign commit, Stage 2 prompt commit, and Stage 3 and
Stage 4 pipeline-role commits; native prompt and campaign validation;
schema-resolution evidence; both clean-repeat results; cleanup outcome; and
every repository's working-tree state. Identify any deviation, unresolved
concern, or complexity beyond the planned three-task production flow and the
acceptance criterion that required it.
Do not edit workspace planning files, mark Feature 0007 `done`, modify
standalone roles, or push during out-of-band implementation. Both asset
commits must eventually be pushed before a default remote deployment can
consume them, but pushing and feature completion remain post-review actions.
## Progress Notes
- No stages completed.

View File

@@ -186,15 +186,39 @@ application-role releases in one source repository.
- The pipeline role installs Narratio's PromptKit-compatible prompt library
from the `narratio-prompts` Git repository. The Scriptorium role owns its
native prompt, profile, and schema directory configuration, while the
pipeline role owns populating those locations with suite integration
content.
native prompt and schema directory configuration, while the pipeline role
owns populating those locations with suite integration content.
- The upstream repository is
`https://gitea.maximumdirect.net/eric/narratio-prompts`.
- For the MVP, the pipeline role tracks and pulls the latest upstream commit.
`https://gitea.maximumdirect.net/eric/narratio-prompts.git`.
- The repository is checked out at
`/usr/local/share/narratio/prompt-library` by default. Scriptorium's prompt
and schema directories are the checkout's `prompts/` and `schemas/`
subdirectories.
- The repository does not currently contain execution profiles. The pipeline
role does not set Scriptorium's profile directory until a later suite-policy
feature selects and deploys profiles.
- For the MVP, the pipeline role tracks and pulls the repository's `main`
branch. The origin, revision, and checkout root are configurable, and a
caller may select an immutable commit when required.
- Pinning the prompt library to a version or release is deferred until the
upstream repository provides versioned releases.
### Campaign registry content
- The pipeline role checks out the `campaigns` Git repository directly into
Narratio's campaign registry root. The upstream repository is
`https://gitea.maximumdirect.net/eric/campaigns.git`.
- The default campaign root remains
`/usr/local/share/narratio/campaigns`, and the pipeline role passes that same
value to the Narratio application role.
- For the MVP, the pipeline role tracks and pulls the repository's `main`
branch. The origin, revision, and campaign root are configurable, and a
caller may select an immutable commit when required.
- Both asset checkouts are root-managed and remotely authoritative. Operators
may read the content but do not edit it on the managed host. Ordinary Git
module convergence owns tracked-content updates; the role does not maintain
separate revision state or purge untracked files.
### Accounts, ownership, and operator access
- The standalone Narratio role creates a dedicated system `narratio` user and
@@ -257,6 +281,8 @@ later design decision changes them:
- `/usr/local/etc/notarius/config.yml` for Notarius configuration
- `/usr/local/etc/scriptorium/config.yml` for Scriptorium configuration
- `/usr/local/share/narratio/campaigns` for version-controlled campaign data
- `/usr/local/share/narratio/prompt-library` for version-controlled prompts
and schemas
- `/usr/local/src/<app>` for root-owned application source checkouts
- `/usr/local/bin/<app>` for root-owned application binaries
- `/var/lib/narratio` for durable workspace and session state
@@ -266,8 +292,8 @@ later design decision changes them:
The Narratio role creates and configures the campaign root; the pipeline role
populates it from the selected campaign source. `/usr/local/share` assumes Git
is authoritative and operators do not edit campaign content directly on the
managed host. The exact prompt-library checkout and installed-content paths
remain to be designed.
managed host. The prompt-library checkout retains its upstream `prompts/` and
`schemas/` layout at the fixed root above.
## Deferred Beyond the MVP
@@ -276,6 +302,7 @@ remain to be designed.
- Installation from prebuilt application release artifacts
- Deploying or managing WhisperX
- Versioned Narratio prompt-library releases and pinning
- Versioned campaign-content releases and default release pinning
- A role-managed scheduler or persistent Narratio service
- Cryptographic artifact verification, supply-chain hardening, and protection
against adversarial source or dependency infrastructure
@@ -290,8 +317,6 @@ The following areas require investigation and decisions before implementation:
- The mechanism used to incorporate the independently developed pipeline role
into collection releases
- The prompt-library destination and its integration with Scriptorium
- The campaign repository's checkout revision and deployment/update policy
- Secret injection and storage
- Suite-level operator-selection variables
- Upgrade, downgrade, and removal behavior

View File

@@ -4,7 +4,7 @@ Last updated: 2026-09-10
Current milestone: M1-03 suite-level pipeline role
Current focus: Select the next suite-level pipeline role feature.
Current focus: Execute the staged Feature 0007 implementation plan.
| ID | Deliverable | Owner | State | Evidence or next step |
| --- | --- | --- | --- | --- |
@@ -15,7 +15,7 @@ Current focus: Select the next suite-level pipeline role feature.
| 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 | Composition foundation complete; select the next suite-policy feature |
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | in_progress | Feature 0007 proposes campaign and prompt-library deployment |
| 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 |
@@ -23,6 +23,7 @@ Current focus: Select the next suite-level pipeline role feature.
| F0004 | Install and configure Scriptorium | ansible-role-scriptorium | done | Implemented and validated through remediation commit `8f47aa8` |
| F0005 | Install and configure Narratio | ansible-role-narratio | done | Implemented and validated through remediation commit `7feff47` |
| 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 | ready | Execute `docs/roadmap/implementation.md` in stage order |
| 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 |