Initial commit

This commit is contained in:
2026-09-07 17:08:09 +00:00
commit 0349682eb9
9 changed files with 561 additions and 0 deletions

16
.gitignore vendored Normal file
View File

@@ -0,0 +1,16 @@
# Independent repositories managed within this workspace.
/ansible-collection-dnd/
/ansible-role-dnd-pipeline/
/ansible-role-audita/
/ansible-role-narratio/
/ansible-role-notarius/
/ansible-role-scriptorium/
/ansible-role-seriatim/
/rakestraw-ansible/
# Local tool state.
/.codebase-memory/
/.idea/
/.vscode/
*.swp
*~

77
AGENTS.md Normal file
View File

@@ -0,0 +1,77 @@
# Workspace Instructions
## Purpose
This is the control repository for the Ansible roles and collection that
deploy the D&D transcript-processing pipeline. It owns cross-repository plans,
decisions, status, and workspace tooling. Each application and Ansible project
is an independent Git repository.
## Repository Map
Repositories inside this directory:
- `ansible-collection-dnd`: the `rakestraw.dnd` collection that bundles and
distributes the pipeline suite.
- `ansible-role-dnd-pipeline`: independent source repository for the
suite-level role exposed by the collection as `rakestraw.dnd.pipeline`.
- `ansible-role-{narratio,notarius,audita,seriatim,scriptorium}`: standalone
application roles.
- `rakestraw-ansible`: working deployment repository containing the
`pipeline_dnd` proof of concept; treat it as read-only reference unless the
task explicitly includes it.
Relevant upstream repositories are siblings of this directory:
- `../{narratio,notarius,audita,seriatim,scriptorium}`: application source and
authoritative application contracts.
- `../narratio-prompts`: pipeline prompt-library content.
Use `workspace.yml` as the complete machine-readable inventory of paths and
remotes.
## Sources of Truth
- `docs/roadmap/mvp.md`: settled MVP scope, architecture, and open design work.
- `docs/status.md`: current cross-repository progress and next work.
- `docs/decisions/`: durable rationale for significant architectural choices.
- `docs/plans/`: temporary implementation plans for substantial work.
- Application repositories: CLI, configuration, build, and integration
contracts.
- Individual Ansible repositories: implementation and repository-local tests.
Do not duplicate an application contract in workspace documentation when a
link and a concise deployment consequence are sufficient.
## Working Conventions
- Confirm the target repository before editing; never treat this directory as
a monorepo.
- Inspect the relevant upstream application before designing or changing its
Ansible role.
- Keep standalone application roles independently usable. Cross-application
policy belongs in `ansible-role-dnd-pipeline` and is exposed to consumers as
`rakestraw.dnd.pipeline`.
- Use `ansible.builtin` modules directly unless a concrete requirement justifies
another dependency.
- Prefer codebase-memory graph tools for code discovery. Use text/file search
for documentation, configuration, literals, or when the graph is
insufficient.
- Preserve unrelated and pre-existing working-tree changes in every
repository.
- Never place credentials or secret values in plans, examples, inventory, or
tests.
- Validate changes in the repository that owns them and report the commands
run.
## Planning and Progress
- Update `docs/roadmap/mvp.md` when a design question becomes a settled scope
or architecture decision.
- Update `docs/status.md` when cross-repository work starts, becomes blocked,
or is completed. Completed items must point to concrete evidence.
- Create a file in `docs/plans/` only for work spanning multiple meaningful
steps or repositories. Remove or archive stale execution detail after the
work is complete; durable rationale belongs in `docs/decisions/`.
- Use the status values `proposed`, `ready`, `in_progress`, `blocked`, `done`,
and `deferred`.

26
README.md Normal file
View File

@@ -0,0 +1,26 @@
# Ansible D&D Development Workspace
This repository coordinates development of the Ansible roles and collection
used to deploy the D&D transcript-processing pipeline. The application and
Ansible projects remain independent Git repositories; this repository tracks
only workspace documentation, planning, and shared development utilities.
## Start Here
- [`AGENTS.md`](AGENTS.md) describes repository boundaries and working
conventions.
- [`workspace.yml`](workspace.yml) inventories the repositories used during
development.
- [`docs/roadmap/mvp.md`](docs/roadmap/mvp.md) records settled MVP decisions
and open design work.
- [`docs/status.md`](docs/status.md) records current cross-repository progress.
Run `./scripts/status` to see the branch and working-tree state of every
repository in the workspace manifest.
## Repository Boundaries
The directories ignored by this repository are intentional nested Git working
trees. Run Git commands from within the repository whose history should be
affected. A commit in this control repository never includes changes from an
application, role, collection, or proof-of-concept repository.

8
docs/decisions/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Architecture Decisions
Use this directory for concise records of significant decisions whose
rationale should remain visible after implementation plans and roadmap details
change. Number records sequentially, for example
`0001-application-and-suite-role-boundaries.md`.
Do not create a decision record for routine implementation choices.

37
docs/plans/template.md Normal file
View File

@@ -0,0 +1,37 @@
# Plan: <Title>
Status: proposed
## Goal
State the outcome this plan must achieve.
## Non-goals
List adjacent work that is intentionally outside this plan.
## Owning Repositories
List every repository this work may change and what each repository owns.
## Dependencies and Settled Decisions
Link applicable roadmap sections and decision records. Record prerequisites
that constrain implementation.
## Acceptance Criteria
- Define observable conditions for completion.
## Implementation Sequence
1. Describe the first independently verifiable step.
## Validation
List the commands, tests, or inspections that demonstrate completion.
## Progress
Keep only concise current state and blockers here. Git history should preserve
obsolete execution detail.

229
docs/roadmap/mvp.md Normal file
View File

@@ -0,0 +1,229 @@
# Initial Roadmap
## Purpose
This document records the decisions that define the initial MVP of the
Narratio Ansible roles and D&D collection. It is the durable reference for
choices that have been settled while the suite is being designed. Open
questions and later ideas should remain clearly distinguished from these
locked decisions.
## MVP Goal
Build independently usable Ansible roles for the five Narratio applications
and compose them through a suite-level role developed in its own repository.
The `rakestraw.dnd` collection exposes that role as `rakestraw.dnd.pipeline`.
The suite-level role installs and configures the complete D&D transcript
processing pipeline on a single supported host. Human operators invoke
Narratio commands directly to process D&D session recordings and produce
transcripts and related artifacts.
## Locked Decisions
### Supported platform
- The MVP supports Ubuntu 26.04.
- The MVP supports both `amd64` and `arm64` hosts.
- The roles should be structured so support for additional distributions and
releases can be added after the MVP without redesigning them.
### Managed applications
The suite-level role installs and configures all five applications in the
Narratio suite:
- Narratio
- Notarius
- Audita
- Seriatim
- Scriptorium
WhisperX is an external HTTP service consumed by Narratio. Deploying or
managing the WhisperX service is outside the MVP scope, although the Narratio
role will manage the native configuration needed to connect to it.
### Application installation
- The MVP builds all five applications from their official Git repositories on
the target host. This consistent model avoids making the suite depend on
every upstream project publishing prebuilt artifacts.
- Released roles build an explicitly selected application release tag.
Development may override the selected revision with a branch or commit.
- Source checkouts reside at `/usr/local/src/<app>` and are owned by `root`.
- Roles build into a staging location, validate the result, and then install
the binary at `/usr/local/bin/<app>` with `root:root` ownership and mode
`0755`. A failed build must not replace a working installed binary.
- Builds use the application repository's own build contract, including any
application-specific version-injection linker flags. The common baseline is
`GOWORK=off`, `GOTOOLCHAIN=local`, `CGO_ENABLED=0`, and `-trimpath`.
- Build state must account for the checked-out commit, Go toolchain, and build
arguments so that roles rebuild when a relevant input changes rather than
relying only on the existence of the installed binary.
- Each application role exposes variables for its repository, selected
version or revision, source directory, binary path, and build settings.
### Go toolchain
- Go is installed on the target host through the official Snap package using
classic confinement.
- The Snap channel is configurable and should track an explicit Go minor
release channel, rather than unconstrained `latest/stable`, when that channel
is available for the required Go version.
- The installed Go toolchain must satisfy the application's `go.mod`
requirement. Builds set `GOTOOLCHAIN=local` so provisioning does not silently
download a different toolchain.
- Each standalone application role can install its own build prerequisites and
exposes a variable allowing that behavior to be disabled. Repeating an
idempotent prerequisite task across the small roles is preferable to adding
a shared-role dependency during the MVP.
### Role and collection architecture
- All Ansible roles and collections in this suite use the root namespace
`rakestraw`.
- Each of the five managed applications has a separate, targeted Ansible role
in its own repository.
- Each application role owns installation and native configuration of that
application.
- The Narratio application role remains application-specific even though
Narratio is the runtime orchestrator for the full pipeline.
- The suite-level role is developed in the standalone
`ansible-role-dnd-pipeline` repository rather than directly in the collection
repository.
- The application and pipeline roles are independently developed, tested,
versioned, and released. An application-specific change therefore requires a
release of that application's role without requiring changes or releases in
unrelated role repositories.
- The collection is named `rakestraw.dnd`.
- The collection bundles and exposes the independently developed suite-level
role as `rakestraw.dnd.pipeline`, providing one opinionated interface for
consumers.
- The pipeline role owns compatible application-version selection,
cross-application configuration, D&D campaign deployment, prompt-library
deployment, operator access, the pipeline-wide secret-delivery policy, and
end-to-end validation.
- The pipeline role uses the Git-hosted standalone application roles as
dependencies. This is an intentional choice for the controlled project
environment despite the additional repository and dependency structure and
Ansible's preference for published collection dependencies.
- Consumer installation may require a dependency manifest or bootstrap step
that installs both the collection and its standalone role dependencies; a
plain collection installation is not assumed to resolve arbitrary Git role
dependencies by itself.
This design keeps repository ownership and change blast radius aligned with
the independently released applications while retaining a single opinionated
installation interface for the complete suite. It avoids forcing each small
role to become its own published collection and avoids coupling unrelated
application-role releases in one source repository.
### Ansible dependencies and task structure
- The standalone application roles are self-contained and use
`ansible.builtin` modules directly.
- The roles do not depend on the private
`maximumdirect.core.ansible_role_loader` role used by the proof of concept.
- Platform-specific task selection may be added later using ordinary Ansible
includes when another supported platform creates a concrete need.
- Small amounts of repeated prerequisite or installation logic are acceptable
during the MVP. A shared helper role or collection plugin should be
introduced only if substantial, stable shared behavior emerges.
### Dependency and release reproducibility
- Development dependency manifests may temporarily refer to branches or
commits while the roles are changing rapidly.
- Every released dependency manifest must pin each Git-hosted role dependency
to an immutable role release tag.
- The collection release is the compatibility record for the exact set of
application-role versions it composes.
- Collection integration tests must install and exercise the same pinned role
combination delivered to consumers, starting from an environment in which
the dependencies are not already installed.
- Updating one application role in the suite requires updating its pinned
version in the collection, validating the assembled suite, and releasing a
new collection version. Unrelated application-role repositories remain
unchanged.
### Prompt library
- 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.
- The upstream repository is
`https://gitea.maximumdirect.net/eric/narratio-prompts`.
- For the MVP, the pipeline role tracks and pulls the latest upstream commit.
- Pinning the prompt library to a version or release is deferred until the
upstream repository provides versioned releases.
### Accounts, ownership, and operator access
- The roles create a dedicated `narratio` user and `narratio` group as needed.
- The `narratio` account owns Narratio's writable runtime directories.
- Application source trees and installed binaries are owned by `root` and are
not writable by operators or the runtime account.
- Ordinary human users run `narratio run` and other Narratio commands directly.
- Those operators receive the required access by membership in the `narratio`
group.
- Managed configuration should be owned by `root`, readable by the `narratio`
group where needed, and remain under Ansible control rather than being
routinely edited by operators on the host.
- Shared runtime directories must grant the `narratio` group the write access
needed for direct operator invocations.
### Execution model
- Narratio is installed as a command-line application, not a persistent
daemon.
- Scheduling Narratio invocations through cron, systemd timers, or another
automation mechanism is not currently part of the locked MVP scope.
## Expected Filesystem Areas
The roles align with the applications' established default locations unless a
later design decision changes them:
- `/usr/local/etc/narratio` for Narratio configuration
- `/usr/local/etc/audita/config.yml` for Audita configuration
- `/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/src/<app>` for root-owned application source checkouts
- `/usr/local/bin/<app>` for root-owned application binaries
- `/var/lib/narratio` for durable workspace and session state
- `/var/spool/narratio` for spool data
- `/var/cache/narratio` for cached data
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.
## Deferred Beyond the MVP
- Linux distributions and Ubuntu releases other than Ubuntu 26.04
- Architectures other than `amd64` and `arm64`
- Installation from prebuilt application release artifacts
- Deploying or managing WhisperX
- Versioned Narratio prompt-library releases and pinning
- A role-managed scheduler or persistent Narratio service
## Design Work Still Open
The following areas require investigation and decisions before implementation:
- Exact application repository URLs, default release tags, build commands,
version-injection flags, and validation commands
- Standalone role Galaxy names and the dependency-manifest/bootstrap layout
- The mechanism used to incorporate the independently developed pipeline role
into collection releases
- Configuration contracts and filesystem requirements of Notarius, Audita,
Seriatim, and Scriptorium
- The prompt-library destination and its integration with Scriptorium
- Secret injection and storage
- Operator-group membership variables and directory permission details
- Upgrade, downgrade, and removal behavior
- Ansible dependency, validation, and test strategy

26
docs/status.md Normal file
View File

@@ -0,0 +1,26 @@
# Workspace Status
Last updated: 2026-09-07
Current milestone: MVP design and workspace foundation
Current focus: Select the next open design topic before role implementation.
| ID | Deliverable | Owner | State | Evidence or next step |
| --- | --- | --- | --- | --- |
| M0-01 | Workspace control repository | workspace | done | Root repository and `workspace.yml` created |
| M0-02 | Workspace conventions | workspace | done | Root `AGENTS.md` created |
| M0-03 | Tracked MVP roadmap | workspace | done | `docs/roadmap/mvp.md` established |
| M0-04 | Aggregate repository status | workspace | done | `scripts/status` created |
| 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 | ready | Select the next item from the roadmap |
| M1-02 | Standalone application roles | role repositories | proposed | Begin after relevant interfaces are settled |
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | proposed | Begin after standalone role interfaces stabilize |
| M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism |
## Updating This File
Use `proposed`, `ready`, `in_progress`, `blocked`, `done`, or `deferred` for
state. Keep this dashboard concise. Link completed implementation work to the
owning repository's file, commit, test, or release rather than copying detailed
implementation notes here.

54
scripts/status Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -u
workspace_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
manifest="$workspace_root/workspace.yml"
if [[ ! -f "$manifest" ]]; then
printf 'workspace manifest not found: %s\n' "$manifest" >&2
exit 1
fi
printf '%-30s %-18s %-7s %s\n' REPOSITORY BRANCH STATE UPSTREAM
while IFS= read -r relative_path; do
if [[ "$relative_path" == "." ]]; then
repository_name=workspace
repository_path=$workspace_root
else
repository_name=$(basename "$relative_path")
repository_path="$workspace_root/$relative_path"
fi
if [[ ! -d "$repository_path/.git" ]]; then
printf '%-30s %-18s %-7s %s\n' "$repository_name" - missing "$relative_path"
continue
fi
branch=$(git -C "$repository_path" branch --show-current)
if [[ -z "$branch" ]]; then
branch="detached@$(git -C "$repository_path" rev-parse --short HEAD)"
fi
if [[ -n $(git -C "$repository_path" status --porcelain) ]]; then
state=dirty
else
state=clean
fi
upstream=$(git -C "$repository_path" rev-parse \
--abbrev-ref --symbolic-full-name '@{upstream}' 2>/dev/null || true)
if [[ -n "$upstream" ]]; then
read -r behind ahead < <(git -C "$repository_path" rev-list \
--left-right --count "$upstream...HEAD")
tracking="ahead=$ahead behind=$behind ($upstream)"
else
tracking=untracked
fi
printf '%-30s %-18s %-7s %s\n' \
"$repository_name" "$branch" "$state" "$tracking"
done < <(
printf '.\n'
awk '$1 == "path:" { print $2 }' "$manifest"
)

88
workspace.yml Normal file
View File

@@ -0,0 +1,88 @@
---
name: ansible-workspace-dnd
remote: https://gitea.maximumdirect.net/eric/ansible-workspace-dnd.git
repositories:
- name: ansible-collection-dnd
path: ansible-collection-dnd
remote: https://gitea.maximumdirect.net/eric/ansible-collection-dnd.git
category: ansible-collection
purpose: Bundles and distributes the rakestraw.dnd pipeline suite
- name: ansible-role-dnd-pipeline
path: ansible-role-dnd-pipeline
remote: https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline.git
category: ansible-role
purpose: Develops the suite-level role exposed as rakestraw.dnd.pipeline
- name: ansible-role-narratio
path: ansible-role-narratio
remote: https://gitea.maximumdirect.net/eric/ansible-role-narratio.git
category: ansible-role
purpose: Installs and configures Narratio
- name: ansible-role-notarius
path: ansible-role-notarius
remote: https://gitea.maximumdirect.net/eric/ansible-role-notarius.git
category: ansible-role
purpose: Installs and configures Notarius
- name: ansible-role-audita
path: ansible-role-audita
remote: https://gitea.maximumdirect.net/eric/ansible-role-audita.git
category: ansible-role
purpose: Installs and configures Audita
- name: ansible-role-seriatim
path: ansible-role-seriatim
remote: https://gitea.maximumdirect.net/eric/ansible-role-seriatim.git
category: ansible-role
purpose: Installs and configures Seriatim
- name: ansible-role-scriptorium
path: ansible-role-scriptorium
remote: https://gitea.maximumdirect.net/eric/ansible-role-scriptorium.git
category: ansible-role
purpose: Installs and configures Scriptorium
- name: rakestraw-ansible
path: rakestraw-ansible
remote: https://gitea.maximumdirect.net/eric/ansible.git
category: reference
purpose: Existing deployment repository and pipeline_dnd proof of concept
- name: narratio
path: ../narratio
remote: https://gitea.maximumdirect.net/eric/narratio.git
category: application
purpose: Narratio source and authoritative application contracts
- name: notarius
path: ../notarius
remote: https://gitea.maximumdirect.net/eric/notarius.git
category: application
purpose: Notarius source and authoritative application contracts
- name: audita
path: ../audita
remote: https://gitea.maximumdirect.net/eric/audita.git
category: application
purpose: Audita source and authoritative application contracts
- name: seriatim
path: ../seriatim
remote: https://gitea.maximumdirect.net/eric/seriatim.git
category: application
purpose: Seriatim source and authoritative application contracts
- name: scriptorium
path: ../scriptorium
remote: https://gitea.maximumdirect.net/eric/scriptorium.git
category: application
purpose: Scriptorium source and authoritative application contracts
- name: narratio-prompts
path: ../narratio-prompts
remote: https://gitea.maximumdirect.net/eric/narratio-prompts.git
category: content
purpose: PromptKit-compatible pipeline prompt library