19 KiB
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 governs the role interface, direct desired-state tasks, privilege escalation, and downstream role configuration.
- The testing house style governs focused native outcome coverage and clean repeated convergence.
- The MVP roadmap 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 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
mainbranch, 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/campaignsby default. - Check out the prompt repository directly at
/usr/local/share/narratio/prompt-libraryby 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>/promptsand<prompt-library-root>/schemasto 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_filedeclaration from both campaign definitions while retaining theirparty_fileinputs. - Migrate both legacy party lists to the
narratio.party.v1document 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-promptsrepository. - 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.dndor 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-pipelineowns the suite asset variables, Git checkout tasks, application-role variable wiring, documentation, and integration coverage. It is the primary implementation repository.assets/narratio-promptsowns 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/campaignsowns the campaign registry content and layout. It changes only to remove the obsoleteplayers_filefields 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-narratioandansible-role-scriptoriumremain unchanged and are read-only authorities for their public configuration variables.../narratioand../scriptoriumremain read-only authorities for native content discovery and validation behavior.rakestraw-ansibleis a read-only historical reference. Its older/usr/local/etcasset layout and monolithic deployment tasks are not copied.ansible-workspace-dndowns this roadmap, the later staged implementation plan, the settled MVP decisions, and aggregate status.ansible-collection-dndremains unchanged until collection assembly is selected.
Constraints and Settled Decisions
-
The public additions are:
Variable Default Purpose dnd_pipeline_campaigns_repository_urlhttps://gitea.maximumdirect.net/eric/campaigns.gitAuthoritative campaign Git origin dnd_pipeline_campaigns_revisionmainCampaign branch, tag, or commit dnd_pipeline_campaigns_root/usr/local/share/narratio/campaignsCampaign checkout and Narratio registry root dnd_pipeline_prompt_library_repository_urlhttps://gitea.maximumdirect.net/eric/narratio-prompts.gitAuthoritative prompt-library Git origin dnd_pipeline_prompt_library_revisionmainPrompt-library branch, tag, or commit dnd_pipeline_prompt_library_root/usr/local/share/narratio/prompt-libraryPrompt-library checkout root -
Both repositories currently have no release tags. Tracking
mainis the deliberate suite default; callers can opt into commit pinning without a separate update switch. -
ansible.builtin.gitowns 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: trueandforce: trueexpress 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:narratiomode0755. The pipeline role reuses that root rather than duplicating its directory task. -
The pipeline role creates the prompt-library root as
root:narratiomode0755before checkout. Repository files retain their Git modes and remain operator-readable; no recursive permission normalization is required. -
The pipeline role passes
dnd_pipeline_campaigns_rootasnarratio_campaigns_root,dnd_pipeline_prompt_library_root ~ '/prompts'asscriptorium_prompt_dir, anddnd_pipeline_prompt_library_root ~ '/schemas'asscriptorium_schema_dirthrough ordinary dependency metadata. -
scriptorium_profile_diris 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, andtrim/bounds.schema.json. -
The campaign source corrections remove
inputs.players_filefromcentaurs/campaign.ymlanddilfs/campaign.yml. The existinginputs.party_filefield remains the canonical party source. -
Each party document uses
schema_version: narratio.party.v1and acharactersmap. Stable character IDs are the lowercase underscore forms of their names:krek,rick_oathbreaker,tlann,torvass_oathbreaker,hrank_greenfield,alan_hohey,svend_balderk, andpopov. -
Each character retains its player name, display name, class, and level in the corresponding native nested fields. Legacy
category: pcis implicit in membership in the canonical character map. Legacy free-form notes are retained as adjacent YAML comments becausenarratio.party.v1has no note field. Popov's evidentpladintypo is corrected topaladinduring the otherwise mechanical migration. -
The now-unused
players.ymlfiles 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:
- Remove the obsolete
players_filefield from both campaign definitions and migrate both party documents tonarratio.party.v1. - Correct the four stale paths in the prompt source repository.
- Add and type the six asset variables.
- Map the campaign root and prompt/schema directories into the existing Narratio and Scriptorium dependency variables.
- Declare the prompt-library root with
ansible.builtin.file. - Converge the campaign and prompt repositories with two
ansible.builtin.gittasks. - 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_rootand the configured prompt repository atdnd_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/andschemas/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.mdfile, 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.fileandansible.builtin.gitbehavior.
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.