From 5fdd92b2970f4678db60e570e06ef5ce6400bff5 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Thu, 10 Sep 2026 15:37:00 +0000 Subject: [PATCH] Plan D&D asset deployment --- ...-deployment-and-scriptorium-integration.md | 348 ++++++++++ docs/roadmap/implementation.md | 595 +++++++++++++++++- docs/roadmap/mvp.md | 43 +- docs/status.md | 5 +- 4 files changed, 970 insertions(+), 21 deletions(-) create mode 100644 docs/roadmap/features/0007-dnd-asset-deployment-and-scriptorium-integration.md diff --git a/docs/roadmap/features/0007-dnd-asset-deployment-and-scriptorium-integration.md b/docs/roadmap/features/0007-dnd-asset-deployment-and-scriptorium-integration.md new file mode 100644 index 0000000..fee0300 --- /dev/null +++ b/docs/roadmap/features/0007-dnd-asset-deployment-and-scriptorium-integration.md @@ -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 `/prompts` and + `/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. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index b927a9b..1e8ca64 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -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. diff --git a/docs/roadmap/mvp.md b/docs/roadmap/mvp.md index f88f7a8..925c7b2 100644 --- a/docs/roadmap/mvp.md +++ b/docs/roadmap/mvp.md @@ -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/` for root-owned application source checkouts - `/usr/local/bin/` 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 diff --git a/docs/status.md b/docs/status.md index 859a2c4..54abd2c 100644 --- a/docs/status.md +++ b/docs/status.md @@ -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 |