354 lines
19 KiB
Markdown
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.
|