Files
ansible-workspace-dnd/docs/roadmap/implementation.md

24 KiB

Implementation Plan 0007: Deploy D&D Assets and Integrate Scriptorium

Status: ready

Target executor: GPT-5.6-Terra

Feature roadmap: Feature 0007: D&D Asset Deployment and Scriptorium Integration

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:

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:

/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:

/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:

../.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:

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:

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.