Files
ansible-workspace-dnd/docs/roadmap/features/0007-dnd-asset-deployment-and-scriptorium-integration.md

354 lines
19 KiB
Markdown

# Feature 0007: D&D Asset Deployment and Scriptorium Integration
Status: done
## 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.
Feature 0007 was completed by campaign commit `d1193e8`, prompt-library commit
`c7e1845`, pipeline-role commits `a6ce224` and `cbfd601`, and final test-quality
remediation commit `7572fa3`. The complete integration suite and post-remediation
review passed with no remaining findings.
## 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.