Compare commits
26 Commits
88a0eaacf5
...
539c75cb18
| Author | SHA1 | Date | |
|---|---|---|---|
| 539c75cb18 | |||
| fc8f5709b0 | |||
| 0e0034ef02 | |||
| 40ca08a352 | |||
| 956c50cc2f | |||
| e24e8d0d05 | |||
| 943ece7a65 | |||
| b98fb5783f | |||
| 253d283234 | |||
| 8f57e1bcf5 | |||
| b359eee321 | |||
| 2b1448ab91 | |||
| ec3c0b9706 | |||
| 1a81db660e | |||
| bc1cf31f0e | |||
| 9a86cdb57e | |||
| 54a2362c02 | |||
| d2bd48cc99 | |||
| 731a799873 | |||
| bbc8d25d64 | |||
| 9b0949f2ac | |||
| 358051af98 | |||
| 6d9b4b87f8 | |||
| 7ac9220e87 | |||
| 7f8ce88b43 | |||
| 5b2effd68a |
@@ -48,6 +48,13 @@ file modes are `0750` and `0640`, respectively, with
|
|||||||
shared credentials. Configuration may contain credential reference names but
|
shared credentials. Configuration may contain credential reference names but
|
||||||
never raw credential values.
|
never raw credential values.
|
||||||
|
|
||||||
|
Narratio's general operational guidance recommends `0700` directories and
|
||||||
|
`0600` files for a single-user credential store. The suite deliberately grants
|
||||||
|
group read/traverse access instead: membership in the selected `narratio`
|
||||||
|
runtime group authorizes both pipeline execution and use of its shared provider
|
||||||
|
credentials. Deployments that do not trust every group member require a
|
||||||
|
different per-user credential policy and are outside this decision.
|
||||||
|
|
||||||
Version-controlled campaign and prompt assets may remain root-managed because
|
Version-controlled campaign and prompt assets may remain root-managed because
|
||||||
Git is authoritative, but they are world-readable. The suite does not add
|
Git is authoritative, but they are world-readable. The suite does not add
|
||||||
confidentiality controls to non-secret D&D content.
|
confidentiality controls to non-secret D&D content.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Feature 0010: D&D Notarius Extraction Integration
|
# Feature 0010: D&D Notarius Extraction Integration
|
||||||
|
|
||||||
Status: ready
|
Status: done
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,389 @@
|
|||||||
|
# Feature 0011: Managed Pipeline Credentials and Notarius Reuse
|
||||||
|
|
||||||
|
Status: done
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Upgrade the generic Narratio role and D&D pipeline to Narratio v2.1.0, manage
|
||||||
|
provider credentials through Narratio's conventional ConfigKit secrets
|
||||||
|
directory, and use the release's typed Notarius credential and checkpoint-reuse
|
||||||
|
controls. Credential values remain outside ordinary application YAML and are
|
||||||
|
readable only by the selected runtime user and group. Ordinary pipeline runs
|
||||||
|
reuse compatible Notarius checkpoints, while forced extraction retains
|
||||||
|
Narratio's native refresh behavior.
|
||||||
|
|
||||||
|
## Problem or Opportunity
|
||||||
|
|
||||||
|
The pipeline role currently writes credential reference names but manages no
|
||||||
|
credential values. A caller must prepare the invoking environment through an
|
||||||
|
external mechanism before a real run can reach the selected model providers.
|
||||||
|
|
||||||
|
The installed Narratio v2.0.0 release also cannot forward a selected provider
|
||||||
|
credential to Notarius. Its Notarius child receives a restricted environment,
|
||||||
|
and the v2.0 configuration contract exposes no typed credential field. The
|
||||||
|
pipeline records Notarius checkpoints but cannot ask Notarius to reuse them.
|
||||||
|
|
||||||
|
Narratio v2.1.0, immutable tag `v2.1.0` at `c45e042`, resolves both application
|
||||||
|
contract gaps. It adds optional `notarius.llm_api_key`, `notarius.resume`, and
|
||||||
|
`notarius.chunk_cache` fields without requiring migration of existing v2
|
||||||
|
configuration. The credential field resolves through the existing process
|
||||||
|
environment or secrets-directory bootstrap, forwards only the exact selected
|
||||||
|
name and value, and participates in the application's existing redaction
|
||||||
|
boundary. Ordinary extraction may request checkpoint reuse; forced extraction
|
||||||
|
omits resume and refreshes the active chunk plan.
|
||||||
|
|
||||||
|
The suite separately configures Audita proposal and validation with different
|
||||||
|
environment names even though both use the same endpoint and model. Narratio's
|
||||||
|
Audita boundary accepts one typed credential. This feature therefore
|
||||||
|
coordinates both suite-default Audita sections on `AUDITA_LLM_API_KEY` while
|
||||||
|
retaining their existing independently overrideable variables.
|
||||||
|
|
||||||
|
## Governing Policies
|
||||||
|
|
||||||
|
- [The Ansible house style](../../ansible.md) governs the direct desired-state
|
||||||
|
implementation, native configuration interface, and ordinary module
|
||||||
|
convergence.
|
||||||
|
- [The testing house style](../../testing.md) governs synthetic, native,
|
||||||
|
behavior-oriented validation without live provider calls or filesystem
|
||||||
|
metadata assertions.
|
||||||
|
- [The MVP roadmap](../mvp.md) assigns pipeline-wide secret delivery,
|
||||||
|
application-version coordination, and cache policy to the suite role.
|
||||||
|
- [Decision 0002](../../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
|
defines the selected runtime group as the authorization boundary and fixes
|
||||||
|
`0750` directory and `0640` file modes for shared credential material.
|
||||||
|
- [Feature 0009](0009-shared-pipeline-filesystem-and-execution.md) establishes
|
||||||
|
the service-user and existing-group-member invocation model.
|
||||||
|
- [Feature 0010](0010-dnd-notarius-extraction-integration.md) establishes the
|
||||||
|
Notarius pipeline, FHS cache roots, automatic chunk-plan reuse, and checkpoint
|
||||||
|
recording extended by this feature.
|
||||||
|
- Narratio's immutable v2.1.0 release documentation and current configuration
|
||||||
|
and Notarius integration references are authoritative for the application
|
||||||
|
fields, resolution semantics, forced-run behavior, and redaction contract.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Advance the standalone Narratio role's selected application release from
|
||||||
|
v2.0.0 to v2.1.0 without changing its established source-build task flow.
|
||||||
|
- Expose the three new native optional fields through nullable, field-specific
|
||||||
|
role variables: `narratio_notarius_llm_api_key`,
|
||||||
|
`narratio_notarius_resume`, and `narratio_notarius_chunk_cache`.
|
||||||
|
- Keep the standalone role generic. All three variables default to null and
|
||||||
|
are omitted unless a caller selects them, leaving Narratio's native defaults
|
||||||
|
in control.
|
||||||
|
- Advance the pipeline role's compatible Narratio application version to
|
||||||
|
v2.1.0 and pin its Narratio role dependency to the reviewed revision that
|
||||||
|
provides the new interface.
|
||||||
|
- Use `/usr/local/etc/narratio/secrets`, the conventional directory adjacent
|
||||||
|
to `/usr/local/etc/narratio/pipeline.yml`, as the suite's sole managed
|
||||||
|
credential location.
|
||||||
|
- Create that directory as the selected pipeline runtime user and group with
|
||||||
|
mode `0750`.
|
||||||
|
- Add one public `dnd_pipeline_secrets` mapping from environment-variable names
|
||||||
|
to string file contents. Each supplied entry means that the named credential
|
||||||
|
file must be present with that content; an omitted key is unmanaged.
|
||||||
|
- Default `dnd_pipeline_secrets` to an empty mapping so the role never invents
|
||||||
|
credentials and remains usable with externally prepared process environment
|
||||||
|
values.
|
||||||
|
- Validate selected keys as environment-variable names and values as strings
|
||||||
|
before constructing a destination path.
|
||||||
|
- Write supplied credential files as the selected runtime user and group with
|
||||||
|
mode `0640`.
|
||||||
|
- Suppress credential values from Ansible task output during validation,
|
||||||
|
creation, and updates.
|
||||||
|
- Keep ordinary application configuration limited to non-secret credential
|
||||||
|
reference names.
|
||||||
|
- Coordinate Audita proposal and validation on the suite-default
|
||||||
|
`AUDITA_LLM_API_KEY` name and pass that name through the standalone Narratio
|
||||||
|
role's existing `narratio_audita_llm_api_key` interface.
|
||||||
|
- Add `dnd_pipeline_narratio_notarius_llm_api_key`, default it to
|
||||||
|
`OPENROUTER_API_KEY` for Notarius's selected production profile, and pass it
|
||||||
|
through Narratio's typed Notarius credential field.
|
||||||
|
- Add `dnd_pipeline_narratio_notarius_resume`, default it to true, and pass it
|
||||||
|
through Narratio so ordinary extraction requests reuse of the checkpoints
|
||||||
|
already recorded by the suite's Notarius configuration.
|
||||||
|
- Expose Narratio's native `notarius.chunk_cache` in the standalone role but do
|
||||||
|
not duplicate it behind a suite variable or set it from the pipeline role.
|
||||||
|
The suite already configures Notarius's ordinary chunk-plan mode as `auto`;
|
||||||
|
Narratio v2.1.0 independently owns its forced-extraction refresh override.
|
||||||
|
- Preserve Scriptorium's application-owned `api_key_env` profile selection.
|
||||||
|
Narratio's secrets bootstrap supplies the selected environment value and the
|
||||||
|
existing Scriptorium adapter passes that named credential to its child.
|
||||||
|
- Document the mapping interface, Ansible Vault inventory pattern, process
|
||||||
|
environment precedence, shared-group authorization boundary, application
|
||||||
|
credential flow, and checkpoint-reuse policy.
|
||||||
|
- Add focused integration coverage using distinctive synthetic values and
|
||||||
|
native Narratio configuration loading. No default test contacts a model
|
||||||
|
provider.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Storing raw credentials in Narratio, Audita, Notarius, or Scriptorium YAML.
|
||||||
|
- Providing real credentials, unencrypted example values, or a default secret
|
||||||
|
mapping.
|
||||||
|
- Implementing Ansible Vault, choosing a vault password mechanism, or requiring
|
||||||
|
one specific inventory encryption workflow.
|
||||||
|
- Integrating an external secret manager, cloud vault, hardware-backed key
|
||||||
|
store, or dynamic credential broker.
|
||||||
|
- Making the pipeline role authoritative for files omitted from
|
||||||
|
`dnd_pipeline_secrets`, purging the whole directory, or recursively changing
|
||||||
|
pre-existing content.
|
||||||
|
- Adding a launcher script, shell profile, environment file, systemd unit,
|
||||||
|
scheduler, or persistent service merely to inject credentials.
|
||||||
|
- Passing arbitrary caller-defined environment variables through Narratio's
|
||||||
|
subprocess boundary.
|
||||||
|
- Managing human accounts or their membership in the runtime group.
|
||||||
|
- Running Audita, Notarius, or Scriptorium against a live endpoint during the
|
||||||
|
default integration suites.
|
||||||
|
- Testing Notarius checkpoint reuse end to end in the Ansible role. Narratio
|
||||||
|
and Notarius own that behavior; the role validates the selected native
|
||||||
|
configuration and immediate Ansible convergence.
|
||||||
|
- Setting Narratio's optional `notarius.chunk_cache` field redundantly when
|
||||||
|
the deployed Notarius configuration already selects `auto`.
|
||||||
|
- Changing Narratio's native forced-extraction refresh policy.
|
||||||
|
- Rotating credentials, retaining prior values, validating provider
|
||||||
|
authorization, or recovering deliberately corrupted secret files.
|
||||||
|
- Adding storage or publishing credentials before the suite selects a storage
|
||||||
|
or publishing feature.
|
||||||
|
- Modifying any upstream application source.
|
||||||
|
|
||||||
|
## Target End State
|
||||||
|
|
||||||
|
The standalone Narratio role installs v2.1.0 by default and can render all
|
||||||
|
three new Notarius fields when a caller supplies them. It owns no credential
|
||||||
|
files and selects no D&D-specific credential or cache policy.
|
||||||
|
|
||||||
|
The pipeline role owns this conventional restricted subtree:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/usr/local/etc/narratio/
|
||||||
|
├── pipeline.yml
|
||||||
|
└── secrets/ narratio:narratio 0750
|
||||||
|
├── AUDITA_LLM_API_KEY narratio:narratio 0640
|
||||||
|
└── OPENROUTER_API_KEY narratio:narratio 0640
|
||||||
|
```
|
||||||
|
|
||||||
|
The filenames are suite-selected reference names, never credential values.
|
||||||
|
The selected runtime user and group remain configurable through the existing
|
||||||
|
pipeline interface.
|
||||||
|
|
||||||
|
A consumer may keep encrypted values in inventory without embedding any value
|
||||||
|
in ordinary configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dnd_pipeline_secrets:
|
||||||
|
AUDITA_LLM_API_KEY: "{{ vault_dnd_audita_llm_api_key }}"
|
||||||
|
OPENROUTER_API_KEY: "{{ vault_dnd_openrouter_api_key }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
The role owns only the supplied named entries for this invocation and leaves
|
||||||
|
every omitted name alone. The actual `vault_dnd_*` values belong in encrypted
|
||||||
|
inventory and must not appear in examples, plans, test logs, commits, or
|
||||||
|
ordinary generated configuration.
|
||||||
|
|
||||||
|
When Narratio runs without `--secrets-dir`, it discovers the sibling directory
|
||||||
|
and loads its immediate regular files before resolving the pipeline. An
|
||||||
|
already-set process environment value wins over the corresponding file. The
|
||||||
|
base and `testing` profiles use the same delivery mechanism; profiles select
|
||||||
|
models and application profiles, not a second credential store.
|
||||||
|
|
||||||
|
The suite deliberately uses `narratio:narratio`, directory mode `0750`, and
|
||||||
|
file mode `0640` rather than Narratio's general single-user recommendation of
|
||||||
|
`0700` and `0600`. Membership in the selected runtime group is an explicit
|
||||||
|
authorization to invoke this pipeline with its shared provider credentials.
|
||||||
|
No world access is granted. Deployments that do not trust every group member
|
||||||
|
must use separate process-environment or `--secrets-dir` provisioning and are
|
||||||
|
outside this shared-operator policy.
|
||||||
|
|
||||||
|
Audita's proposal and validation configuration both reference
|
||||||
|
`AUDITA_LLM_API_KEY` by default. Narratio resolves that typed reference and
|
||||||
|
passes the value explicitly to the Audita child. Callers may still override
|
||||||
|
the existing Audita reference variables, but a custom split-key design also
|
||||||
|
requires an application boundary capable of forwarding both values and is not
|
||||||
|
promised by this feature.
|
||||||
|
|
||||||
|
Narratio's effective Notarius configuration names `OPENROUTER_API_KEY`, or a
|
||||||
|
caller-selected replacement, through `notarius.llm_api_key`. Narratio resolves
|
||||||
|
the named secret and forwards only that exact name and value to Notarius. It
|
||||||
|
does not infer a provider from Notarius configuration or forward unrelated
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
Ordinary extraction sets `notarius.resume: true`. Notarius continues to own
|
||||||
|
checkpoint recording, identity, and storage beneath the configured
|
||||||
|
`/var/cache/notarius/checkpoints` root. Narratio requests reuse but does not
|
||||||
|
inspect the cache. The pipeline leaves Narratio's `notarius.chunk_cache` field
|
||||||
|
unset because the Notarius root configuration already selects `auto` at the
|
||||||
|
native owner. Forced extraction follows Narratio v2.1.0 behavior: resume is
|
||||||
|
omitted and the active chunk plan is refreshed without deleting unrelated
|
||||||
|
cache content.
|
||||||
|
|
||||||
|
Scriptorium continues to select credential names through its PromptKit
|
||||||
|
profiles. The Narratio process receives those names from the secret bootstrap,
|
||||||
|
and its existing adapter forwards the selected profile credential.
|
||||||
|
|
||||||
|
## Repository Ownership
|
||||||
|
|
||||||
|
- `../narratio` at immutable tag `v2.1.0` is the read-only application
|
||||||
|
authority for secrets bootstrap, typed Notarius credential forwarding,
|
||||||
|
checkpoint reuse, forced refresh, and subprocess redaction.
|
||||||
|
- `ansible-role-narratio` advances the application release and exposes the
|
||||||
|
three native Notarius fields through its generic field-specific interface.
|
||||||
|
It does not manage secret files or select suite policy.
|
||||||
|
- `ansible-role-dnd-pipeline` owns the conventional secrets directory, managed
|
||||||
|
credential mapping, suite-level Audita and Notarius reference coordination,
|
||||||
|
checkpoint-reuse selection, consumer documentation, and behavioral tests.
|
||||||
|
- `ansible-workspace-dnd` owns this roadmap, the settled MVP policy, progress,
|
||||||
|
and independent review record.
|
||||||
|
- The Audita, Notarius, and Scriptorium application roles remain unchanged;
|
||||||
|
they continue to own only their native configuration interfaces.
|
||||||
|
- The collection, asset, remaining application, and reference repositories
|
||||||
|
remain unchanged.
|
||||||
|
|
||||||
|
## Constraints and Settled Decisions
|
||||||
|
|
||||||
|
- Raw credential bytes never enter ordinary application YAML, Git-tracked
|
||||||
|
examples, workspace plans, or committed test fixtures.
|
||||||
|
- The role manages secret values only through `ansible.builtin.copy` content
|
||||||
|
or an equally direct secret-safe module operation with `no_log: true`.
|
||||||
|
- The conventional directory path is fixed because automatic Narratio
|
||||||
|
discovery depends on its relationship to the fixed root pipeline document.
|
||||||
|
- Credential filenames must match the environment-variable grammar accepted
|
||||||
|
by ConfigKit. Validation exists to prevent a caller-controlled key from
|
||||||
|
becoming a path outside the secrets directory.
|
||||||
|
- Credential values are written as supplied strings. ConfigKit and the typed
|
||||||
|
application reference own any nonempty-value requirement when a credential
|
||||||
|
is selected for use.
|
||||||
|
- An omitted mapping key is outside the role's ownership. Exact-directory
|
||||||
|
mirroring and deletion of unlisted files are intentionally excluded.
|
||||||
|
- The shared runtime group is an authorization group. Its members may read the
|
||||||
|
managed credentials; all other local users are denied access.
|
||||||
|
- The suite's group-readable credential policy deliberately differs from
|
||||||
|
Narratio's general single-user mode recommendation. ConfigKit does not
|
||||||
|
enforce those recommended modes, and the selected policy grants no world
|
||||||
|
access.
|
||||||
|
- Application adapters, rather than Ansible, own the secure transfer of loaded
|
||||||
|
values to child processes. Ansible does not create wrappers or reconstruct
|
||||||
|
the subprocess environment.
|
||||||
|
- Notarius's root configuration remains the single owner of ordinary
|
||||||
|
chunk-plan mode. Narratio's native `resume` field expresses the distinct
|
||||||
|
request to load compatible recorded checkpoints.
|
||||||
|
- Production convergence performs no provider call, credential validity test,
|
||||||
|
cache probe, content checksum bookkeeping, backup, or post-write reread.
|
||||||
|
|
||||||
|
## Simplest Viable Implementation Shape
|
||||||
|
|
||||||
|
The standalone Narratio role needs only a release update and three nullable
|
||||||
|
field-specific variables rendered through its existing template. It remains
|
||||||
|
generic and does not own credential files or suite policy.
|
||||||
|
|
||||||
|
The pipeline role needs one empty credential mapping, two Narratio Notarius
|
||||||
|
policy variables, coordinated Audita reference defaults, and ordinary
|
||||||
|
dependency wiring. Credential convergence consists of one directory task, one
|
||||||
|
validation loop, and one copy loop for supplied entries. Both secret-bearing
|
||||||
|
loops suppress their output.
|
||||||
|
|
||||||
|
Documentation and focused native integration coverage complete the public
|
||||||
|
interface. No state probe, handler, template assembly, manifest, wrapper,
|
||||||
|
directory scan, or role-private bookkeeping is required. The validation loop
|
||||||
|
is deliberate: the mapping key becomes a filesystem path, so rejecting
|
||||||
|
anything other than a valid environment-variable name protects the declared
|
||||||
|
destination boundary.
|
||||||
|
|
||||||
|
## Rationale and Alternatives
|
||||||
|
|
||||||
|
Narratio's native ConfigKit bootstrap is preferable to a shell wrapper or
|
||||||
|
service-specific environment file because every pipeline-loading command uses
|
||||||
|
the same application-owned behavior, whether invoked by the service account or
|
||||||
|
an authorized human operator. It also preserves the application's existing
|
||||||
|
environment-precedence and redaction rules.
|
||||||
|
|
||||||
|
A mapping is more ergonomic for inventory than a list of file objects because
|
||||||
|
the native identity of each entry is already its environment-variable name.
|
||||||
|
Omitted files remain unmanaged so consumers can combine Ansible-managed
|
||||||
|
credentials with another provisioning mechanism. Credential removal and
|
||||||
|
directory mirroring remain outside this feature until an operator-facing
|
||||||
|
lifecycle requirement is expressly selected.
|
||||||
|
|
||||||
|
Per-user `0700` directories would follow Narratio's general recommendation but
|
||||||
|
would require separate keys or an additional invocation convention for every
|
||||||
|
authorized human. The selected shared group already defines who may execute
|
||||||
|
the suite with shared state, so group-readable and world-inaccessible
|
||||||
|
credentials provide the intended operational model with less duplication.
|
||||||
|
|
||||||
|
Selecting Narratio checkpoint reuse completes the suite's earlier decision to
|
||||||
|
enable every available Notarius cache. Duplicating `chunk_cache: auto` in both
|
||||||
|
Narratio and Notarius configuration would add no ordinary behavior, so the
|
||||||
|
pipeline leaves the optional Narratio override unset and relies on each
|
||||||
|
application's documented ownership boundary.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- The standalone Narratio role installs an explicitly selected v2.1.0 and can
|
||||||
|
render representative non-null and falsey values for
|
||||||
|
`narratio_notarius_llm_api_key`, `narratio_notarius_resume`, and
|
||||||
|
`narratio_notarius_chunk_cache` while omitting null values.
|
||||||
|
- The pipeline role selects Narratio v2.1.0 and pins the reviewed standalone
|
||||||
|
role revision that provides its native fields.
|
||||||
|
- The pipeline role creates `/usr/local/etc/narratio/secrets` with the selected
|
||||||
|
runtime ownership and suite credential-directory mode.
|
||||||
|
- `dnd_pipeline_secrets` defaults to an empty mapping and accepts valid
|
||||||
|
environment names with string values.
|
||||||
|
- Invalid names and non-string values fail before any destination outside the
|
||||||
|
declared secret directory can be constructed.
|
||||||
|
- Supplied entries converge to regular files with the selected runtime
|
||||||
|
ownership and mode `0640`; omitted names remain unmanaged.
|
||||||
|
- Credential values are suppressed from Ansible output and never appear in
|
||||||
|
application YAML, generated examples, native effective-configuration output,
|
||||||
|
test logs, or committed fixtures.
|
||||||
|
- Audita proposal and validation use `AUDITA_LLM_API_KEY` by default, and
|
||||||
|
Narratio's typed Audita field names that reference so the adapter explicitly
|
||||||
|
supplies the loaded value.
|
||||||
|
- Narratio's effective pipeline selects `OPENROUTER_API_KEY` through the typed
|
||||||
|
Notarius field and selects checkpoint resume for ordinary extraction.
|
||||||
|
- Narratio's optional chunk-cache override remains absent from the suite
|
||||||
|
configuration while Notarius's effective root configuration continues to
|
||||||
|
select `auto`.
|
||||||
|
- Scriptorium continues to receive the credential named by its selected
|
||||||
|
profile through the existing adapter behavior.
|
||||||
|
- A synthetic pipeline integration invocation with the relevant ambient
|
||||||
|
variables unset loads credentials through the conventional directory and
|
||||||
|
succeeds at native offline configuration validation as the service account
|
||||||
|
and one existing-group-member fixture.
|
||||||
|
- A distinctive synthetic secret never appears in captured integration output.
|
||||||
|
- The baseline credential application reports `changed=0` and `failed=0` on
|
||||||
|
an immediate identical repeat.
|
||||||
|
- Syntax checking, production-profile lint, and the complete standalone
|
||||||
|
Narratio and pipeline integration entry points pass.
|
||||||
|
- No live provider, WhisperX service, storage backend, model call, or
|
||||||
|
application cache execution occurs in default tests.
|
||||||
|
|
||||||
|
## Dependencies and Follow-up Work
|
||||||
|
|
||||||
|
- Features 0005, 0006, 0008, 0009, and 0010 are complete prerequisites.
|
||||||
|
- Narratio v2.1.0 at immutable tag `c45e042` satisfies the former typed
|
||||||
|
Notarius credential and cache-control prerequisite.
|
||||||
|
- The completed upstream feature request was removed from Narratio's active
|
||||||
|
roadmap during its v2.1.0 release cleanup; the release reference now owns the
|
||||||
|
delivered behavior.
|
||||||
|
- The standalone Narratio-role commit produced by this feature must be
|
||||||
|
available from its canonical Git origin before the pipeline's isolated
|
||||||
|
dependency test can use it.
|
||||||
|
- Collection assembly should follow this feature so the first assembled
|
||||||
|
collection packages a pipeline with complete credential delivery and cache
|
||||||
|
reuse.
|
||||||
|
- Storage and publishing policy may later add S3 or other credential reference
|
||||||
|
names to consumer inventory without changing the file-delivery mechanism.
|
||||||
|
- Operator selection, group-membership management, services, scheduling,
|
||||||
|
upgrades, removal, and external secret-manager integration remain separate
|
||||||
|
features.
|
||||||
|
|
||||||
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
- Integrate a dedicated external secret manager or short-lived credential
|
||||||
|
broker.
|
||||||
|
- Support distinct per-operator secret directories for deployments that do
|
||||||
|
not treat runtime-group membership as shared credential authorization.
|
||||||
|
- Add explicit credential rotation orchestration and provider-side validity
|
||||||
|
checks.
|
||||||
|
- Add an explicit credential-removal or directory-lifecycle contract if an
|
||||||
|
operator need is identified.
|
||||||
|
- Add platform-specific mandatory-access-control policy for credential files.
|
||||||
304
docs/roadmap/features/0012-collection-assembly.md
Normal file
304
docs/roadmap/features/0012-collection-assembly.md
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
# Feature 0012: Assemble the D&D Collection
|
||||||
|
|
||||||
|
Status: done
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Turn the existing `ansible-collection-dnd` repository into a valid, buildable
|
||||||
|
`rakestraw.dnd` Ansible collection that exposes the independently developed
|
||||||
|
pipeline role as `rakestraw.dnd.pipeline`. The collection will carry a
|
||||||
|
self-contained snapshot of the pipeline role, publish the collection
|
||||||
|
dependencies Ansible can resolve natively, and provide one consumer bootstrap
|
||||||
|
manifest for the five Git-hosted application roles.
|
||||||
|
|
||||||
|
## Problem or Opportunity
|
||||||
|
|
||||||
|
The standalone application roles and the opinionated pipeline role are now
|
||||||
|
implemented and independently tested, but the collection repository still
|
||||||
|
contains only a placeholder README and repository metadata. A consumer cannot
|
||||||
|
build or install `rakestraw.dnd`, invoke the intended fully qualified role
|
||||||
|
name, or reproduce the reviewed combination of application-role dependencies
|
||||||
|
from that repository.
|
||||||
|
|
||||||
|
The pipeline role must remain independently developed, versioned, and usable.
|
||||||
|
At the same time, the collection artifact must contain the role it advertises;
|
||||||
|
it cannot depend on a sibling checkout, a symbolic link, or workspace-only
|
||||||
|
tooling at runtime. The assembly boundary therefore needs an explicit,
|
||||||
|
repeatable source-import convention and focused integration coverage of the
|
||||||
|
packaged result.
|
||||||
|
|
||||||
|
## Governing Policies
|
||||||
|
|
||||||
|
- [The Ansible house style](../../ansible.md) governs collection metadata,
|
||||||
|
dependency declarations, documentation, and the preference for native
|
||||||
|
Ansible packaging behavior.
|
||||||
|
- [The testing house style](../../testing.md) governs behavior-oriented,
|
||||||
|
state-based validation and the avoidance of tests that merely restate file
|
||||||
|
layout or implementation details.
|
||||||
|
- [The MVP roadmap](../mvp.md) establishes the collection name, independently
|
||||||
|
released role repositories, Git-hosted application-role dependencies, and
|
||||||
|
the collection as the compatibility record for an assembled release.
|
||||||
|
- Features [0006](0006-pipeline-role-composition-foundation.md) through
|
||||||
|
[0011](0011-managed-pipeline-credential-delivery.md) define the pipeline
|
||||||
|
role behavior being assembled; this feature does not reopen those contracts.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Add valid Ansible Galaxy metadata for collection namespace `rakestraw`, name
|
||||||
|
`dnd`, development version `0.1.0`, the repository's existing license and
|
||||||
|
README, and its supported Ansible version.
|
||||||
|
- Declare the exact `ansible.posix` and `community.general` versions already
|
||||||
|
selected by the pipeline role as collection dependencies.
|
||||||
|
- Import the complete standalone pipeline-role repository into
|
||||||
|
`roles/pipeline` as a squashed Git subtree at an explicitly reviewed commit.
|
||||||
|
- Treat `ansible-role-dnd-pipeline` as authoritative: changes are made and
|
||||||
|
reviewed there first, then deliberately imported into the collection. Do
|
||||||
|
not edit role behavior directly beneath the collection's subtree prefix.
|
||||||
|
- Document the initial subtree import and subsequent update commands so the
|
||||||
|
source relationship is reproducible without custom tooling or private
|
||||||
|
knowledge.
|
||||||
|
- Ensure the standalone pipeline role's collection-facing documentation
|
||||||
|
distinguishes its standalone role name and invocation from
|
||||||
|
`rakestraw.dnd.pipeline` use without changing its public behavior.
|
||||||
|
- Add `meta/runtime.yml` with `requires_ansible: ">=2.18.0"`, matching the
|
||||||
|
implemented roles' supported baseline.
|
||||||
|
- Add one root `requirements.yml` that combines the five Git-hosted
|
||||||
|
application-role dependencies with the two collection dependencies needed
|
||||||
|
to bootstrap the assembled suite.
|
||||||
|
- Pin application roles to the exact reviewed commits already selected by the
|
||||||
|
standalone pipeline role during development. Keep the root bootstrap
|
||||||
|
manifest and the imported role's dependency manifests consistent.
|
||||||
|
- Configure collection builds to omit development-only content embedded in the
|
||||||
|
role subtree, including its integration suite, local Ansible configuration,
|
||||||
|
and nested dependency manifests. Retain operator-facing role documentation
|
||||||
|
and licensing in the source collection unless Ansible packaging requires
|
||||||
|
otherwise.
|
||||||
|
- Replace the collection's placeholder README with concise instructions for
|
||||||
|
dependency bootstrap, collection build and installation, FQCN invocation,
|
||||||
|
subtree provenance and updates, supported platform, and the distinction
|
||||||
|
between development commit pins and future released role tags.
|
||||||
|
- Add a focused collection integration suite that starts with isolated role
|
||||||
|
and collection paths, installs the root bootstrap manifest and the locally
|
||||||
|
built collection artifact, invokes `rakestraw.dnd.pipeline`, validates the
|
||||||
|
assembled pipeline through the applications' native configuration
|
||||||
|
interfaces, and verifies an immediate second application converges with no
|
||||||
|
reported changes.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Publishing the collection to Ansible Galaxy, Automation Hub, Gitea, or any
|
||||||
|
other registry.
|
||||||
|
- Creating the first collection release tag or application-role release tags.
|
||||||
|
- Replacing development commit pins with immutable role tags before those tags
|
||||||
|
exist.
|
||||||
|
- Vendoring any of the five standalone application roles into the collection.
|
||||||
|
- Moving authoritative pipeline-role development into the collection
|
||||||
|
repository or permitting collection-local role forks.
|
||||||
|
- Changing pipeline defaults, host convergence, application versions,
|
||||||
|
application configuration, asset deployment, credentials, or runtime
|
||||||
|
behavior.
|
||||||
|
- Adding collection plugins, modules, filters, playbooks, execution
|
||||||
|
environments, CI workflows, release automation, or a general-purpose sync
|
||||||
|
framework.
|
||||||
|
- Repeating every standalone pipeline integration scenario inside the
|
||||||
|
collection suite or asserting the exact contents of metadata and manifests
|
||||||
|
as an implementation snapshot.
|
||||||
|
- Supporting installation without network access. The collection artifact is
|
||||||
|
self-contained for the pipeline role, but its declared external role and
|
||||||
|
collection dependencies must still be made available to Ansible.
|
||||||
|
|
||||||
|
## Target End State
|
||||||
|
|
||||||
|
The collection repository has this durable shape:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ansible-collection-dnd/
|
||||||
|
├── galaxy.yml
|
||||||
|
├── meta/
|
||||||
|
│ └── runtime.yml
|
||||||
|
├── requirements.yml
|
||||||
|
├── roles/
|
||||||
|
│ └── pipeline/ imported pipeline-role subtree
|
||||||
|
├── tests/
|
||||||
|
│ ├── converge.yml
|
||||||
|
│ ├── integration assembled-artifact behavior test
|
||||||
|
│ └── inventory
|
||||||
|
├── LICENSE
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
`ansible-galaxy collection build` produces a valid
|
||||||
|
`rakestraw-dnd-0.1.0.tar.gz` artifact. After the documented bootstrap installs
|
||||||
|
the root dependency manifest and the built artifact into clean Ansible paths,
|
||||||
|
a consumer can invoke:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install and configure the D&D transcript pipeline
|
||||||
|
hosts: pipeline_hosts
|
||||||
|
roles:
|
||||||
|
- role: rakestraw.dnd.pipeline
|
||||||
|
```
|
||||||
|
|
||||||
|
The collection contains ordinary role files at `roles/pipeline`; it has no
|
||||||
|
runtime link to the standalone repository. Git history records that directory
|
||||||
|
as a squashed subtree import from `ansible-role-dnd-pipeline`. Maintainers make
|
||||||
|
pipeline changes in the standalone repository, validate and commit them there,
|
||||||
|
then update the collection subtree from the desired reviewed commit.
|
||||||
|
|
||||||
|
The root bootstrap manifest is the consumer-facing compatibility manifest for
|
||||||
|
development. It contains the same five application-role sources and reviewed
|
||||||
|
commit pins as the imported pipeline role, plus exact versions of
|
||||||
|
`ansible.posix` and `community.general`. The collection's Galaxy metadata also
|
||||||
|
declares those two collection dependencies because Ansible can resolve them as
|
||||||
|
native collection dependencies. This intentional duplication serves two
|
||||||
|
different installation boundaries and must remain consistent.
|
||||||
|
|
||||||
|
Development-only files may remain in the subtree source for faithful
|
||||||
|
provenance, but they are excluded from the built artifact. The collection's
|
||||||
|
own integration suite exercises the artifact rather than the repository role
|
||||||
|
directory, with role and collection paths isolated from ordinary user
|
||||||
|
installations.
|
||||||
|
|
||||||
|
## Repository Ownership
|
||||||
|
|
||||||
|
- `ansible-collection-dnd` owns collection metadata, the consumer bootstrap
|
||||||
|
manifest, the imported pipeline snapshot, collection-facing documentation,
|
||||||
|
build exclusions, and assembled-artifact integration coverage.
|
||||||
|
- `ansible-role-dnd-pipeline` remains authoritative for all pipeline-role code,
|
||||||
|
defaults, templates, dependency metadata, standalone documentation, and its
|
||||||
|
comprehensive integration suite. This feature changes only the wording
|
||||||
|
needed to document both standalone and collection use.
|
||||||
|
- The five standalone application-role repositories remain authoritative for
|
||||||
|
their roles and are read-only inputs to this feature.
|
||||||
|
- `campaigns` and `narratio-prompts` remain independently managed asset
|
||||||
|
repositories and are read-only integration inputs.
|
||||||
|
- `ansible-workspace-dnd` owns this feature roadmap, progress tracking, and the
|
||||||
|
later independent review record.
|
||||||
|
- Application source repositories and `rakestraw-ansible` remain unchanged.
|
||||||
|
|
||||||
|
## Constraints and Settled Decisions
|
||||||
|
|
||||||
|
- The collection is `rakestraw.dnd`; the bundled role's FQCN is
|
||||||
|
`rakestraw.dnd.pipeline`.
|
||||||
|
- A squashed Git subtree is the selected incorporation mechanism. It yields a
|
||||||
|
normal, self-contained collection artifact while preserving an auditable
|
||||||
|
upstream relationship and avoiding submodule checkout requirements,
|
||||||
|
symbolic links, manual copying, or custom synchronization state.
|
||||||
|
- The subtree prefix is `roles/pipeline`, and the standalone pipeline
|
||||||
|
repository remains the only place where role behavior is authored.
|
||||||
|
- The first development build uses collection version `0.1.0`. This version
|
||||||
|
enables ordinary Galaxy build and install validation but does not itself
|
||||||
|
authorize publication or establish a release tag.
|
||||||
|
- Development dependencies use exact reviewed commits. A later release pass
|
||||||
|
must replace all application-role commit pins with immutable role release
|
||||||
|
tags and revalidate the assembled artifact before publishing.
|
||||||
|
- Collection dependencies remain exactly `ansible.posix` 2.2.0 and
|
||||||
|
`community.general` 13.3.0, matching the existing reviewed pipeline
|
||||||
|
manifests.
|
||||||
|
- Galaxy metadata cannot install arbitrary standalone Git roles. The root
|
||||||
|
unified requirements manifest and documented bootstrap are therefore part
|
||||||
|
of the collection's public installation contract.
|
||||||
|
- The collection integration suite must not receive dependencies from the
|
||||||
|
developer's normal Ansible paths. Its success must demonstrate that the
|
||||||
|
documented manifest and built artifact are sufficient.
|
||||||
|
- The collection suite owns only the packaging boundary: buildability,
|
||||||
|
dependency bootstrap, FQCN resolution, representative assembled behavior,
|
||||||
|
native configuration acceptance, and convergence. Detailed pipeline feature
|
||||||
|
matrices remain in the standalone role's tests.
|
||||||
|
- The collection does not add probes, manifests, checksums, copied-file
|
||||||
|
comparisons, or private state to police the subtree. Git and the documented
|
||||||
|
subtree workflow are the provenance mechanism.
|
||||||
|
|
||||||
|
## Simplest Viable Implementation
|
||||||
|
|
||||||
|
Use Ansible's conventional collection layout and metadata directly. Import the
|
||||||
|
reviewed pipeline repository with ordinary `git subtree add --squash`, then
|
||||||
|
exclude only the subtree's development fixtures and nested bootstrap files
|
||||||
|
from Galaxy builds. No wrapper role, generated role, symbolic link, submodule,
|
||||||
|
or synchronization script is required.
|
||||||
|
|
||||||
|
Derive the root unified dependency manifest directly from the pipeline role's
|
||||||
|
two existing manifests. The only deliberate duplication is the collection
|
||||||
|
dependency declaration in `galaxy.yml`, because the artifact and the source
|
||||||
|
bootstrap have distinct native Ansible dependency interfaces.
|
||||||
|
|
||||||
|
Use one representative integration path: build into a temporary directory,
|
||||||
|
install dependencies and the artifact into isolated temporary Ansible paths,
|
||||||
|
apply `rakestraw.dnd.pipeline` using the same offline synthetic inputs already
|
||||||
|
proven by the standalone suite, run native application configuration
|
||||||
|
validation, and apply the play a second time to assert `changed=0` and
|
||||||
|
`failed=0`. This tests the behavior unique to collection assembly without
|
||||||
|
duplicating the standalone role's full test matrix.
|
||||||
|
|
||||||
|
## Rationale and Alternatives
|
||||||
|
|
||||||
|
A squashed subtree is preferable to a Git submodule because Ansible collection
|
||||||
|
archives require real role content and should build correctly from an ordinary
|
||||||
|
checkout without a second initialization step. It is preferable to a symbolic
|
||||||
|
link because archive behavior and installed collection paths would be fragile.
|
||||||
|
It is preferable to an unrecorded copy because subtree history retains the
|
||||||
|
source relationship and provides a standard update command. Squashing avoids
|
||||||
|
injecting the pipeline repository's entire development history into the
|
||||||
|
collection while still recording each reviewed import.
|
||||||
|
|
||||||
|
Moving the role permanently into the collection would simplify assembly, but
|
||||||
|
would discard the settled requirement that the suite role remain independently
|
||||||
|
developed, tested, versioned, and usable. A thin collection wrapper that
|
||||||
|
depends on `rakestraw.dnd_pipeline` would avoid source import but would not
|
||||||
|
actually bundle the role or satisfy the desired FQCN without adding another
|
||||||
|
runtime dependency layer.
|
||||||
|
|
||||||
|
Keeping one unified root requirements file gives consumers one bootstrap
|
||||||
|
command for both dependency kinds. Retaining the imported role's own
|
||||||
|
requirements files in source preserves standalone repository fidelity; build
|
||||||
|
exclusion prevents those nested development interfaces from confusing users
|
||||||
|
of the installed artifact.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- The collection repository is recognized by `ansible-galaxy` as
|
||||||
|
`rakestraw.dnd` version `0.1.0` and builds successfully from a clean checkout.
|
||||||
|
- The built archive contains `roles/pipeline` and excludes the imported role's
|
||||||
|
development-only integration suite, local Ansible configuration, and nested
|
||||||
|
dependency manifests.
|
||||||
|
- The role content at `roles/pipeline` is traceable to a documented reviewed
|
||||||
|
commit of `ansible-role-dnd-pipeline` through the repository's squashed
|
||||||
|
subtree history.
|
||||||
|
- The standalone pipeline README accurately documents both
|
||||||
|
`rakestraw.dnd_pipeline` and `rakestraw.dnd.pipeline` consumption without
|
||||||
|
changing role behavior.
|
||||||
|
- `meta/runtime.yml` selects Ansible 2.18 or newer, and Galaxy metadata declares
|
||||||
|
the exact two collection dependencies used by the pipeline.
|
||||||
|
- The root bootstrap manifest contains all five standalone application roles
|
||||||
|
at the same reviewed commits used by the imported pipeline role and the
|
||||||
|
exact two required collections.
|
||||||
|
- Collection documentation provides sufficient commands to install the
|
||||||
|
bootstrap dependencies, build and install the artifact, invoke the pipeline
|
||||||
|
FQCN, and update the subtree from a future reviewed pipeline commit.
|
||||||
|
- The integration suite starts with isolated Ansible role and collection
|
||||||
|
paths, installs only the declared bootstrap inputs and built artifact, and
|
||||||
|
resolves `rakestraw.dnd.pipeline` without access to a sibling role checkout.
|
||||||
|
- The representative assembled deployment passes the applications' native
|
||||||
|
configuration validation and an immediate identical second run reports
|
||||||
|
`changed=0` and `failed=0`.
|
||||||
|
- Existing standalone pipeline-role validation continues to pass after its
|
||||||
|
documentation-only change.
|
||||||
|
- No application role, application source, asset behavior, or pipeline host
|
||||||
|
convergence behavior changes as part of this feature.
|
||||||
|
|
||||||
|
## Dependencies and Follow-up Work
|
||||||
|
|
||||||
|
- Features 0001 through 0011 and their reviewed role commits are prerequisites.
|
||||||
|
- A subsequent release feature must create immutable role tags, replace
|
||||||
|
development commit pins, select the release collection version, validate the
|
||||||
|
tagged combination, create release notes and tags, and publish or distribute
|
||||||
|
the artifact.
|
||||||
|
- CI automation may later run the collection integration suite after a local,
|
||||||
|
repeatable workflow exists.
|
||||||
|
|
||||||
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
- Sign collection artifacts or publish checksums and software bills of
|
||||||
|
materials when a distribution threat model requires them.
|
||||||
|
- Automate subtree provenance checks and dependency-pin synchronization if
|
||||||
|
manual collection updates become frequent enough to justify that machinery.
|
||||||
285
docs/roadmap/features/0013-first-coordinated-suite-release.md
Normal file
285
docs/roadmap/features/0013-first-coordinated-suite-release.md
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
# Feature 0013: Publish the First Coordinated Suite Release
|
||||||
|
|
||||||
|
Status: in_progress
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Publish the reviewed D&D pipeline as the first immutable, remotely installable
|
||||||
|
release of its five application roles, standalone pipeline role, and
|
||||||
|
`rakestraw.dnd` collection. The release establishes `v0.1.0` tags in the
|
||||||
|
projects' public Gitea repositories, replaces development commit pins with
|
||||||
|
those role tags, and makes the built `rakestraw-dnd-0.1.0.tar.gz` collection
|
||||||
|
artifact available from the collection's Gitea release.
|
||||||
|
|
||||||
|
## Problem or Opportunity
|
||||||
|
|
||||||
|
The application roles, pipeline role, and collection have been implemented,
|
||||||
|
reviewed, and tested as one compatible suite. Their current dependency
|
||||||
|
manifests still select application roles by development commit, however, and
|
||||||
|
none of the seven Ansible repositories has an immutable release tag. The
|
||||||
|
collection documentation consequently describes a development build rather
|
||||||
|
than a published release, and a consumer cannot bootstrap the reviewed suite
|
||||||
|
entirely from named releases and a published collection artifact.
|
||||||
|
|
||||||
|
The initial release should turn the existing reviewed compatibility set into a
|
||||||
|
durable public installation boundary without changing application behavior or
|
||||||
|
introducing release automation. It must prove that the release is consumable
|
||||||
|
from Gitea alone rather than from sibling repositories or unpublished local
|
||||||
|
artifacts.
|
||||||
|
|
||||||
|
## Governing Policies
|
||||||
|
|
||||||
|
- [The Ansible house style](../../ansible.md) governs dependency manifests,
|
||||||
|
collection packaging, and concise consumer documentation.
|
||||||
|
- [The testing house style](../../testing.md) governs release validation. The
|
||||||
|
feature reuses behavior-oriented repository suites and adds only validation
|
||||||
|
specific to the remote publication boundary.
|
||||||
|
- [The planning policy](../../planning.md) governs the cross-repository
|
||||||
|
implementation and review workflow.
|
||||||
|
- [The MVP roadmap](../mvp.md) defines independent role releases, immutable
|
||||||
|
release pins, the collection as the compatibility record, and public Gitea
|
||||||
|
as the release source.
|
||||||
|
- [Feature 0012](0012-collection-assembly.md) defines the authoritative
|
||||||
|
pipeline subtree, unified consumer manifest, and assembled-artifact testing
|
||||||
|
boundary that this feature releases without redesigning.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Publish `v0.1.0` as the initial release of each standalone application role:
|
||||||
|
`rakestraw.audita`, `rakestraw.narratio`, `rakestraw.notarius`,
|
||||||
|
`rakestraw.seriatim`, and `rakestraw.scriptorium`.
|
||||||
|
- Point those application-role tags at the exact reviewed commits already
|
||||||
|
selected by the pipeline compatibility manifest. No application-role code
|
||||||
|
or default changes are part of release preparation.
|
||||||
|
- Replace the five development commit pins in the authoritative pipeline
|
||||||
|
role's root dependency manifest with the corresponding immutable `v0.1.0`
|
||||||
|
role tags.
|
||||||
|
- Update the pipeline documentation to describe the released dependency pins
|
||||||
|
and its standalone installation path without changing its role interface or
|
||||||
|
runtime behavior.
|
||||||
|
- Validate and publish `v0.1.0` of the standalone pipeline role after its
|
||||||
|
release manifest and documentation are complete.
|
||||||
|
- Import the published pipeline `v0.1.0` state into the collection's
|
||||||
|
`roles/pipeline` subtree using the established remote-only, squashed subtree
|
||||||
|
workflow.
|
||||||
|
- Replace the collection's five application-role commit pins with the same
|
||||||
|
`v0.1.0` tags used by the authoritative pipeline role, retaining the exact
|
||||||
|
`ansible.posix` and `community.general` version pins already selected.
|
||||||
|
- Retain collection version `0.1.0` in `galaxy.yml`, update collection
|
||||||
|
documentation from development-build language to released installation
|
||||||
|
instructions, and identify the release as the compatibility record for the
|
||||||
|
seven selected component versions.
|
||||||
|
- Create and push public, immutable `v0.1.0` tags for all seven Ansible
|
||||||
|
repositories.
|
||||||
|
- Build `rakestraw-dnd-0.1.0.tar.gz` from the tagged collection content and
|
||||||
|
create a concise public Gitea `v0.1.0` collection release whose attachment
|
||||||
|
is that exact artifact.
|
||||||
|
- Validate that a clean consumer can obtain the tag-pinned dependency manifest
|
||||||
|
and collection archive from their public Gitea URLs, install them into
|
||||||
|
isolated Ansible paths, invoke `rakestraw.dnd.pipeline`, and obtain an
|
||||||
|
immediate clean repeat.
|
||||||
|
- Record the completed release and its immutable compatibility set in the
|
||||||
|
workspace status and durable release-facing documentation.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Changing application versions, role defaults, pipeline configuration,
|
||||||
|
filesystem policy, credentials, assets, or deployed runtime behavior.
|
||||||
|
- Synchronizing future versions of independently released roles. The shared
|
||||||
|
initial version is a convenient baseline, not a lockstep release policy.
|
||||||
|
- Publishing the collection to Ansible Galaxy, Automation Hub, or another
|
||||||
|
package registry.
|
||||||
|
- Vendoring the five application roles into the collection or changing the
|
||||||
|
selected pipeline subtree model.
|
||||||
|
- Adding CI/CD, a release script, a changelog generator, dependency-update
|
||||||
|
automation, or a general-purpose release framework.
|
||||||
|
- Adding tests that snapshot manifest text, tag names, defaults, task traces,
|
||||||
|
or other implementation details. Release validation should exercise the
|
||||||
|
public installation and deployed behavior.
|
||||||
|
- Signing tags or artifacts, generating checksums or software bills of
|
||||||
|
materials, mirroring dependencies, or adding other supply-chain hardening.
|
||||||
|
- Defining upgrade, downgrade, removal, scheduling, or optional human-operator
|
||||||
|
account management.
|
||||||
|
|
||||||
|
## Target End State
|
||||||
|
|
||||||
|
Each public application-role repository has an immutable `v0.1.0` tag for the
|
||||||
|
exact role revision already reviewed as part of the assembled suite:
|
||||||
|
|
||||||
|
| Role | Released revision |
|
||||||
|
| --- | --- |
|
||||||
|
| `rakestraw.audita` | `66ebea9a47ce82bfdbdc5e2855f3dfaaff8e2a16` |
|
||||||
|
| `rakestraw.narratio` | `292d8669e7aad5cfe80b0c469d22b6177e8cf0f1` |
|
||||||
|
| `rakestraw.notarius` | `14a38e04e35ef524d6a97fa7fb5a04981a0a2161` |
|
||||||
|
| `rakestraw.seriatim` | `e08c63c0b078658bdfa2d10a2e6e1e4f9372a075` |
|
||||||
|
| `rakestraw.scriptorium` | `8b4c86e48e7d8655e479b26dc510bf01683a0c8f` |
|
||||||
|
|
||||||
|
The standalone pipeline role has its own immutable public `v0.1.0` tag. Its
|
||||||
|
role dependency manifest selects all five application roles with
|
||||||
|
`version: v0.1.0`, and its collection dependency manifest retains
|
||||||
|
`ansible.posix` 2.2.0 and `community.general` 13.3.0. The pipeline release is
|
||||||
|
independently installable under `rakestraw.dnd_pipeline`.
|
||||||
|
|
||||||
|
The collection's `roles/pipeline` subtree is a faithful squashed import of the
|
||||||
|
published pipeline `v0.1.0` release. Its consumer-facing `requirements.yml`
|
||||||
|
contains the same five role tags and collection versions as the standalone
|
||||||
|
pipeline manifests. `galaxy.yml` remains version `0.1.0`, and the collection
|
||||||
|
repository has an immutable `v0.1.0` tag and corresponding public Gitea
|
||||||
|
release to carry the built artifact.
|
||||||
|
|
||||||
|
The collection release includes the archive produced from that released tree,
|
||||||
|
named `rakestraw-dnd-0.1.0.tar.gz`. Its public release notes identify the exact
|
||||||
|
five application-role versions, pipeline-role version, native collection
|
||||||
|
dependencies, supported platform, and consumer bootstrap steps. A consumer
|
||||||
|
can fetch the tagged manifest and archive through public Gitea URLs and
|
||||||
|
install the suite without access to this development workspace.
|
||||||
|
|
||||||
|
## Repository Ownership
|
||||||
|
|
||||||
|
- The five standalone application-role repositories own their respective
|
||||||
|
`v0.1.0` tags. Their reviewed role content remains unchanged by this
|
||||||
|
feature.
|
||||||
|
- `ansible-role-dnd-pipeline` owns its tag-pinned role manifest, standalone
|
||||||
|
release documentation, and `v0.1.0` tag.
|
||||||
|
- `ansible-collection-dnd` owns the released pipeline subtree, unified
|
||||||
|
tag-pinned consumer manifest, collection release documentation, collection
|
||||||
|
tag, built artifact, and Gitea release attachment.
|
||||||
|
- `ansible-workspace-dnd` owns this roadmap, cross-repository compatibility
|
||||||
|
record, active implementation plan, progress tracking, and independent
|
||||||
|
release review.
|
||||||
|
- The application source repositories, campaign repository, prompt-library
|
||||||
|
repository, and `rakestraw-ansible` are unchanged release inputs.
|
||||||
|
|
||||||
|
## Constraints and Settled Decisions
|
||||||
|
|
||||||
|
- Public repositories beneath
|
||||||
|
`https://gitea.maximumdirect.net/eric/` are the authoritative publication
|
||||||
|
channel for this release.
|
||||||
|
- Every Ansible repository uses initial release tag `v0.1.0`. The collection's
|
||||||
|
Galaxy version remains the corresponding unprefixed `0.1.0`, as required by
|
||||||
|
collection metadata and artifact naming.
|
||||||
|
- Tags are immutable release boundaries. A release candidate must be validated
|
||||||
|
before its tag is created and pushed; published tags must not be moved to
|
||||||
|
repair a failed release.
|
||||||
|
- The five application-role tags identify the exact reviewed commits shown in
|
||||||
|
the target end state. Release metadata must not create otherwise unnecessary
|
||||||
|
commits in those repositories.
|
||||||
|
- Released role dependency manifests use tag names, not branches or commit
|
||||||
|
hashes. Application repositories remain independently versioned after this
|
||||||
|
shared initial baseline.
|
||||||
|
- The pipeline repository remains authoritative. Its release must be pushed
|
||||||
|
to Gitea before the collection imports the `v0.1.0` revision through the
|
||||||
|
documented remote-only subtree command.
|
||||||
|
- The collection tag identifies the exact source tree from which the attached
|
||||||
|
artifact is built. The attached file must not be rebuilt from a later or
|
||||||
|
dirty tree while retaining the same version.
|
||||||
|
- The public collection release attachment is the selected binary publication
|
||||||
|
interface. The repository tag remains the source publication interface.
|
||||||
|
- Consumer validation must not use sibling checkouts, normal user Ansible
|
||||||
|
paths, preinstalled project roles, or an unpublished local collection
|
||||||
|
archive.
|
||||||
|
- The collection's Gitea release description and existing repository
|
||||||
|
documentation are
|
||||||
|
sufficient for the initial release. This feature does not introduce
|
||||||
|
repository-local changelog files solely to duplicate those notes.
|
||||||
|
|
||||||
|
## Simplest Viable Implementation
|
||||||
|
|
||||||
|
Use ordinary Git tags, one collection Gitea release, existing Ansible
|
||||||
|
dependency manifests, the established subtree command, and `ansible-galaxy
|
||||||
|
collection build`. The five application roles need validation and tags only.
|
||||||
|
The pipeline and collection need small manifest and documentation changes
|
||||||
|
before their respective release tags are created.
|
||||||
|
|
||||||
|
Reuse the existing repository-local integration entry points as release gates.
|
||||||
|
The collection integration suite already exercises isolated dependency
|
||||||
|
bootstrap, archive construction and installation, FQCN resolution, native
|
||||||
|
application behavior, and clean repeated convergence. Adapt its inputs only as
|
||||||
|
necessary to consume the release tags, and use a focused final smoke path to
|
||||||
|
download the published manifest and attached archive from Gitea. Do not add a
|
||||||
|
second release framework or duplicate the detailed behavior matrices owned by
|
||||||
|
the standalone repositories.
|
||||||
|
|
||||||
|
Publication is intentionally manual for the first release. The work does not
|
||||||
|
yet justify release scripts, workflow files, persistent staging state, or a
|
||||||
|
new packaging service.
|
||||||
|
|
||||||
|
## Rationale and Alternatives
|
||||||
|
|
||||||
|
Immutable role tags give consumers meaningful versions while preserving the
|
||||||
|
settled model of independently released repositories. Publishing only commit
|
||||||
|
hashes would be reproducible but would not establish the named release
|
||||||
|
contract required by the MVP. Publishing branches would not be immutable.
|
||||||
|
|
||||||
|
Using `v0.1.0` for every initial role and the collection makes the first
|
||||||
|
compatibility baseline easy to understand. Future role releases remain
|
||||||
|
independent, and future collection releases record whatever combination is
|
||||||
|
then supported; no synchronized-version policy is implied.
|
||||||
|
|
||||||
|
Attaching the Galaxy-built archive to the public Gitea collection release
|
||||||
|
provides a direct installation artifact without introducing another registry.
|
||||||
|
Requiring consumers to clone and build the collection would expose unnecessary
|
||||||
|
development steps, while publishing to Ansible Galaxy or Automation Hub would
|
||||||
|
add an unselected distribution channel and account lifecycle.
|
||||||
|
|
||||||
|
Manual publication is appropriate for one initial release and keeps the
|
||||||
|
release contract visible. Automation can be considered after repeated release
|
||||||
|
work demonstrates a stable process worth encoding.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Each application-role repository advertises a public, immutable `v0.1.0`
|
||||||
|
tag at the exact reviewed revision listed in this roadmap.
|
||||||
|
- Each application role's existing syntax, lint, integration, and clean-repeat
|
||||||
|
validation passes for the candidate being tagged; no role behavior is
|
||||||
|
changed merely to create the release.
|
||||||
|
- The pipeline role's released manifest selects all five application roles by
|
||||||
|
`v0.1.0`, and its collection dependency versions remain unchanged.
|
||||||
|
- The pipeline's existing validation installs its application-role
|
||||||
|
dependencies from the public Gitea tags, exercises the role through its
|
||||||
|
public interface, and passes its immediate clean repeat.
|
||||||
|
- The pipeline repository advertises a public, immutable `v0.1.0` tag at the
|
||||||
|
validated release commit.
|
||||||
|
- The collection subtree matches the published pipeline `v0.1.0` tree outside
|
||||||
|
repository-specific Git metadata and records the remote Gitea import in Git
|
||||||
|
history.
|
||||||
|
- The collection's root manifest uses the same five `v0.1.0` application-role
|
||||||
|
pins and exact native collection versions as the released pipeline role.
|
||||||
|
- `ansible-galaxy collection build` from the collection release candidate
|
||||||
|
produces `rakestraw-dnd-0.1.0.tar.gz`, and the existing artifact-boundary
|
||||||
|
exclusions remain effective.
|
||||||
|
- The collection's existing integration suite passes against the release
|
||||||
|
candidate, including isolated bootstrap, installed-artifact FQCN use,
|
||||||
|
representative native application checks, and immediate `changed=0` and
|
||||||
|
`failed=0` convergence.
|
||||||
|
- The collection repository advertises a public, immutable `v0.1.0` tag and
|
||||||
|
matching Gitea release. The archive attached to that release is the artifact
|
||||||
|
built from the tagged tree.
|
||||||
|
- A clean remote-only smoke validation downloads the public tag-pinned
|
||||||
|
manifest and public collection attachment, installs into isolated paths,
|
||||||
|
resolves `rakestraw.dnd.pipeline`, and completes with a clean immediate
|
||||||
|
repeat without referencing any sibling repository or unpublished artifact.
|
||||||
|
- Release-facing documentation no longer describes collection `0.1.0` or the
|
||||||
|
role release tags as future or unpublished, and it gives the complete public
|
||||||
|
Gitea installation path without requiring the development workspace.
|
||||||
|
- All participating repositories are clean, their release commits and tags
|
||||||
|
are present upstream, and workspace status records the published
|
||||||
|
compatibility baseline.
|
||||||
|
|
||||||
|
## Dependencies and Follow-up Work
|
||||||
|
|
||||||
|
Feature 0012 and its remediation must remain complete. Credentials capable of
|
||||||
|
pushing commits and tags and creating the public collection Gitea release and
|
||||||
|
attachment must be available during implementation.
|
||||||
|
|
||||||
|
Potential later features include release automation, publication to an Ansible
|
||||||
|
registry, independently versioned follow-up releases, optional suite-level
|
||||||
|
operator membership management, and defined upgrade, downgrade, or removal
|
||||||
|
behavior. None is required for the initial release.
|
||||||
|
|
||||||
|
## Potential Future Hardening
|
||||||
|
|
||||||
|
- Signed Git tags or release artifacts.
|
||||||
|
- Published checksums, provenance attestations, or software bills of
|
||||||
|
materials.
|
||||||
|
- Automated verification and publication in a controlled CI environment.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -106,6 +106,13 @@ role will manage the native configuration needed to connect to it.
|
|||||||
- The collection bundles and exposes the independently developed suite-level
|
- The collection bundles and exposes the independently developed suite-level
|
||||||
role as `rakestraw.dnd.pipeline`, providing one opinionated interface for
|
role as `rakestraw.dnd.pipeline`, providing one opinionated interface for
|
||||||
consumers.
|
consumers.
|
||||||
|
- The collection incorporates the pipeline role at `roles/pipeline` as a
|
||||||
|
squashed Git subtree. The standalone pipeline repository remains
|
||||||
|
authoritative; maintainers change and validate the role there, then import
|
||||||
|
a reviewed commit into the collection rather than editing the subtree copy.
|
||||||
|
- The subtree makes the collection artifact self-contained for its bundled
|
||||||
|
role without requiring submodule initialization, symbolic links, sibling
|
||||||
|
repositories, or custom synchronization tooling.
|
||||||
- The pipeline role owns compatible application-version selection,
|
- The pipeline role owns compatible application-version selection,
|
||||||
cross-application configuration, D&D campaign deployment, prompt-library
|
cross-application configuration, D&D campaign deployment, prompt-library
|
||||||
deployment, operator access, the pipeline-wide secret-delivery policy, and
|
deployment, operator access, the pipeline-wide secret-delivery policy, and
|
||||||
@@ -135,6 +142,10 @@ role will manage the native configuration needed to connect to it.
|
|||||||
collection dependencies. During active development, the Git roles are
|
collection dependencies. During active development, the Git roles are
|
||||||
pinned to reviewed commits; released manifests replace those commits with
|
pinned to reviewed commits; released manifests replace those commits with
|
||||||
immutable role release tags.
|
immutable role release tags.
|
||||||
|
- The collection supplies one consumer-facing root `requirements.yml` that
|
||||||
|
combines those same Git-hosted role pins with the shared collection
|
||||||
|
dependencies. Its Galaxy metadata separately declares the native collection
|
||||||
|
dependencies that Ansible can resolve while installing a collection.
|
||||||
- The pipeline role composes the five roles through ordinary Ansible role
|
- The pipeline role composes the five roles through ordinary Ansible role
|
||||||
dependency metadata. It exposes suite-prefixed variables for the small set
|
dependency metadata. It exposes suite-prefixed variables for the small set
|
||||||
of values the suite must coordinate, and does not duplicate every downstream
|
of values the suite must coordinate, and does not duplicate every downstream
|
||||||
@@ -172,13 +183,24 @@ application-role releases in one source repository.
|
|||||||
|
|
||||||
- Development dependency manifests may temporarily refer to branches or
|
- Development dependency manifests may temporarily refer to branches or
|
||||||
commits while the roles are changing rapidly.
|
commits while the roles are changing rapidly.
|
||||||
|
- The projects' public repositories beneath
|
||||||
|
`https://gitea.maximumdirect.net/eric/` are the authoritative release
|
||||||
|
sources. Standalone roles are published through immutable Git tags.
|
||||||
- Every released dependency manifest must pin each Git-hosted role dependency
|
- Every released dependency manifest must pin each Git-hosted role dependency
|
||||||
to an immutable role release tag.
|
to an immutable role release tag.
|
||||||
- The collection release is the compatibility record for the exact set of
|
- The collection release is the compatibility record for the exact set of
|
||||||
application-role versions it composes.
|
application-role versions it composes.
|
||||||
|
- A collection release consists of its immutable repository tag, matching
|
||||||
|
Gitea release, and the `ansible-galaxy collection build` archive produced
|
||||||
|
from that tagged tree and attached to the Gitea release.
|
||||||
- Collection integration tests must install and exercise the same pinned role
|
- Collection integration tests must install and exercise the same pinned role
|
||||||
combination delivered to consumers, starting from an environment in which
|
combination delivered to consumers, starting from an environment in which
|
||||||
the dependencies are not already installed.
|
the dependencies are not already installed.
|
||||||
|
- Collection integration tests build and install the collection artifact into
|
||||||
|
isolated Ansible paths, resolve `rakestraw.dnd.pipeline`, validate one
|
||||||
|
representative assembled deployment through native application interfaces,
|
||||||
|
and confirm immediate convergence. Detailed pipeline feature matrices remain
|
||||||
|
the standalone pipeline role's testing responsibility.
|
||||||
- Updating one application role in the suite requires updating its pinned
|
- Updating one application role in the suite requires updating its pinned
|
||||||
version in the collection, validating the assembled suite, and releasing a
|
version in the collection, validating the assembled suite, and releasing a
|
||||||
new collection version. Unrelated application-role repositories remain
|
new collection version. Unrelated application-role repositories remain
|
||||||
@@ -255,9 +277,28 @@ application-role releases in one source repository.
|
|||||||
- Debug output is not enabled by the MVP. Any later debug feature must either
|
- Debug output is not enabled by the MVP. Any later debug feature must either
|
||||||
produce world-readable non-secret D&D diagnostics or identify and justify a
|
produce world-readable non-secret D&D diagnostics or identify and justify a
|
||||||
narrower application contract before deployment.
|
narrower application contract before deployment.
|
||||||
- Credential material will live beneath a restricted `secrets/` subdirectory
|
- Credential material lives beneath the conventional
|
||||||
owned by `narratio:narratio`, with directories mode `0750` and files mode
|
`/usr/local/etc/narratio/secrets` subdirectory owned by
|
||||||
`0640`. Ordinary configuration contains only credential reference names.
|
`narratio:narratio`, with directory mode `0750` and file mode `0640`.
|
||||||
|
Membership in the `narratio` group is an explicit authorization to use the
|
||||||
|
suite's shared credentials. This deliberately differs from Narratio's
|
||||||
|
general single-user `0700` and `0600` recommendation while retaining no
|
||||||
|
world access. Ordinary configuration contains only credential reference
|
||||||
|
names.
|
||||||
|
- The pipeline role exposes one empty-by-default credential mapping from valid
|
||||||
|
environment-variable names to string file contents. Supplied entries manage
|
||||||
|
the corresponding files; omitted names remain unmanaged. Credential values
|
||||||
|
are expected to come from encrypted inventory such as Ansible Vault and are
|
||||||
|
suppressed from task output. Credential removal and directory mirroring are
|
||||||
|
outside the MVP.
|
||||||
|
- Narratio's native ConfigKit secrets bootstrap owns loading these files and
|
||||||
|
process-environment precedence. The suite does not add a wrapper, shell
|
||||||
|
profile, service environment file, or parallel credential loader.
|
||||||
|
- The suite coordinates Audita proposal and validation on the
|
||||||
|
`AUDITA_LLM_API_KEY` reference and selects `OPENROUTER_API_KEY` for
|
||||||
|
Notarius's production extraction profile. Narratio v2.1.0 resolves those
|
||||||
|
typed references and forwards only the selected credentials to the
|
||||||
|
corresponding subprocesses.
|
||||||
- [Decision 0002](../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
- [Decision 0002](../decisions/0002-shared-readable-pipeline-filesystem-policy.md)
|
||||||
records the complete rationale and boundary for this policy.
|
records the complete rationale and boundary for this policy.
|
||||||
|
|
||||||
@@ -309,8 +350,9 @@ application-role releases in one source repository.
|
|||||||
cache beneath `/var/cache/notarius`. That FHS cache root is owned by the
|
cache beneath `/var/cache/notarius`. That FHS cache root is owned by the
|
||||||
`narratio` account and group with mode `2775` and the suite's shared default
|
`narratio` account and group with mode `2775` and the suite's shared default
|
||||||
ACL policy. Notarius v0.7.0 leaves cache-entry access to that deployment
|
ACL policy. Notarius v0.7.0 leaves cache-entry access to that deployment
|
||||||
policy. Chunk plans are reused automatically; checkpoints are recorded but
|
policy. Chunk plans are reused automatically. Narratio v2.1.0 requests reuse
|
||||||
Narratio does not yet request their reuse.
|
of compatible recorded checkpoints during ordinary extraction; forced
|
||||||
|
extraction omits checkpoint loading and refreshes the active chunk plan.
|
||||||
- The standalone Notarius role exposes Notarius v0.7.0's native ConfigKit
|
- The standalone Notarius role exposes Notarius v0.7.0's native ConfigKit
|
||||||
import list while remaining independent of D&D content. The pipeline role
|
import list while remaining independent of D&D content. The pipeline role
|
||||||
owns an imported `pipelines/dnd-session.yml` fragment containing its
|
owns an imported `pipelines/dnd-session.yml` fragment containing its
|
||||||
@@ -376,10 +418,5 @@ managed host. The prompt-library checkout retains its upstream `prompts/` and
|
|||||||
|
|
||||||
The following areas require investigation and decisions before implementation:
|
The following areas require investigation and decisions before implementation:
|
||||||
|
|
||||||
- The mechanism used to incorporate the independently developed pipeline role
|
|
||||||
into collection releases
|
|
||||||
- Secret injection and storage
|
|
||||||
- Optional suite-level operator-selection and group-membership management
|
- Optional suite-level operator-selection and group-membership management
|
||||||
- Upgrade, downgrade, and removal behavior
|
- Upgrade, downgrade, and removal behavior
|
||||||
- Collection bootstrap and end-to-end validation details beyond the locked
|
|
||||||
dependency and testing policies above
|
|
||||||
|
|||||||
@@ -1,90 +1,173 @@
|
|||||||
# Feature 0009 Remediation Review
|
# Feature 0012 Remediation Review
|
||||||
|
|
||||||
Status: resolved
|
Status: resolved
|
||||||
|
|
||||||
Reviewed implementation commits:
|
Reviewed implementation commits:
|
||||||
|
|
||||||
- `66ebea9 Make Audita configuration ownership configurable`
|
- `600eb21 Document standalone and collection pipeline usage`
|
||||||
- `e9ae2dc Make Notarius configuration ownership configurable`
|
- `3f7f82e Establish the D&D collection foundation`
|
||||||
- `8b4c86e Make Scriptorium configuration ownership configurable`
|
- `c84aa0d Merge commit '5dbae8a' as 'roles/pipeline'`
|
||||||
- `eeb1105 Make Narratio configuration ownership configurable`
|
- `10ad31c Test the assembled D&D collection`
|
||||||
- `901ae35 Apply shared configuration ownership to the D&D pipeline`
|
|
||||||
- `dddc5ee Manage shared pipeline access with ACLs`
|
|
||||||
- `f53da82 Test shared pipeline access across users`
|
|
||||||
- `608d5be Document the shared pipeline execution model`
|
|
||||||
|
|
||||||
## Review Summary
|
## Review Summary
|
||||||
|
|
||||||
The production architecture and behavioral coverage implement Feature 0009 as
|
Feature 0012 implements the principal target architecture. The standalone
|
||||||
planned. The four standalone roles expose generic configuration ownership and
|
pipeline repository remains authoritative, and collection history records its
|
||||||
mode controls, and the pipeline selects its opinionated service-owned,
|
exact `600eb21` snapshot as a squashed subtree at `roles/pipeline`. The
|
||||||
world-readable policy through those interfaces. Narratio establishes the
|
collection has valid Galaxy and runtime metadata, exact native collection
|
||||||
runtime identity first. The pipeline then installs ACL support and directly
|
dependencies, one unified bootstrap manifest for the five Git-hosted roles,
|
||||||
converges access and default ACLs on the three existing shared roots. Focused
|
focused build exclusions, and an isolated artifact-level integration entry
|
||||||
integration coverage exercises actual cross-identity configuration access and
|
point. The collection builds as `rakestraw.dnd` 0.1.0 and exposes
|
||||||
bidirectional writes under a restrictive umask while preserving immediate clean
|
`rakestraw.dnd.pipeline`.
|
||||||
convergence.
|
|
||||||
|
|
||||||
No production code or test-suite remediation is required. One small consumer
|
Two low-severity issues were found and are now resolved. The collection's
|
||||||
documentation inconsistency remains.
|
subtree maintenance examples derived a commit from the local sibling
|
||||||
|
repository but told Git to fetch that commit from a remote which did not
|
||||||
|
contain it at review time. Separately, the collection integration driver
|
||||||
|
repeated secret-redaction assertions already owned by the standalone pipeline
|
||||||
|
suite; those assertions did not validate collection assembly and strengthened
|
||||||
|
the collection test contract beyond the selected packaging boundary.
|
||||||
|
|
||||||
## Finding 1: Operator Support Is Documented Inconsistently
|
## Finding 1: Subtree Maintenance Commands Mix Local and Remote Sources
|
||||||
|
|
||||||
Severity: low
|
Severity: low
|
||||||
|
|
||||||
`ansible-role-dnd-pipeline/README.md:201-217` first lists "operator access" as
|
`ansible-collection-dnd/README.md:51-63` obtains `pipeline_commit` from
|
||||||
deferred, then correctly states that invocation by an existing member of the
|
`../ansible-role-dnd-pipeline`, but passes the Gitea URL as the repository
|
||||||
selected runtime group is supported. The likely deferred concern is operator
|
argument to both `git subtree add` and `git subtree pull`. The reviewed
|
||||||
selection and group-membership management, not operator access itself.
|
pipeline commit was seven commits ahead of `origin/main` at review time; the
|
||||||
|
remote advertised `b15fe8d`, not imported commit `600eb21`. The documented
|
||||||
|
command therefore could not reproduce the current import.
|
||||||
|
|
||||||
The adjacent YAML fragment defines an otherwise unexplained
|
The collection artifact already contains the imported role, so consumers do
|
||||||
`operator_group_members` variable but shows no consumer task or role that uses
|
not run these commands or need a sibling checkout. The commands are the
|
||||||
it. As written, copying the example does not manage any membership and may lead
|
maintainer-facing assembly interface and should also be portable outside this
|
||||||
a reader to believe that the pipeline role consumes that variable.
|
workspace. The durable contract should therefore use Gitea exclusively: first
|
||||||
|
push the reviewed pipeline commit or tag to the authoritative repository, then
|
||||||
|
identify that remote revision explicitly and import it from the same URL.
|
||||||
|
|
||||||
### Required Remediation
|
### Required Remediation
|
||||||
|
|
||||||
- Replace "operator access" in the deferred list with the precise deferred
|
- Remove the sibling-repository `git rev-parse` commands from both subtree
|
||||||
behavior: operator selection and group-membership management.
|
examples.
|
||||||
- Replace the inert variable fragment with a concise, complete consumer-side
|
- Define an explicit `pipeline_revision` placeholder representing a reviewed
|
||||||
example that actually adds a selected account to the runtime group, or omit
|
commit or immutable tag that has already been pushed to Gitea, and pass that
|
||||||
the example and state the prerequisite directly.
|
revision with the authoritative Gitea URL to both `git subtree add` and
|
||||||
- Keep human account and membership management outside the production pipeline
|
`git subtree pull`.
|
||||||
role.
|
- State concisely that a pipeline revision must be committed, reviewed, and
|
||||||
|
pushed to the authoritative repository before collection assembly imports
|
||||||
|
it. Do not prescribe a branch name or require a release tag during active
|
||||||
|
development; a pushed full commit ID remains valid.
|
||||||
|
- Do not add a configured remote, sibling-path assumption, synchronization
|
||||||
|
script, lock file, or private provenance state.
|
||||||
|
- Do not rewrite subtree history or reimport the current role. This is a
|
||||||
|
collection-owned documentation correction only.
|
||||||
|
- Confirm that Gitea contains the selected pipeline revision, then validate
|
||||||
|
the corrected initial command in a disposable Git repository without using
|
||||||
|
the local sibling repository as the subtree source.
|
||||||
|
|
||||||
|
## Finding 2: The Collection Test Duplicates Secret-Redaction Coverage
|
||||||
|
|
||||||
|
Severity: low
|
||||||
|
|
||||||
|
`ansible-collection-dnd/tests/integration:19-20` defines two synthetic values
|
||||||
|
solely so lines 74-75 can search the first convergence log for them. Secret-safe
|
||||||
|
task output is pipeline behavior established by Feature 0011 and already
|
||||||
|
covered by `ansible-role-dnd-pipeline/tests/integration`. The collection owns
|
||||||
|
artifact construction, bootstrap installation, FQCN resolution, representative
|
||||||
|
assembled behavior, and clean repeated convergence; it does not own a second
|
||||||
|
credential-redaction contract.
|
||||||
|
|
||||||
|
The implementation plan required synthetic credentials so native
|
||||||
|
configuration could be exercised without real provider values, but it did not
|
||||||
|
require the collection to retest Feature 0011 redaction. These two assertions
|
||||||
|
are therefore an inadvertent strengthening by the implementing agent and
|
||||||
|
conflict with the roadmap's instruction to keep detailed pipeline feature
|
||||||
|
coverage in the standalone role.
|
||||||
|
|
||||||
|
The native Seriatim, Audita, Notarius, Scriptorium, and Narratio checks are not
|
||||||
|
part of this finding. They are state-based, inexpensive, and implement the
|
||||||
|
roadmap's express requirement for representative native validation of the
|
||||||
|
assembled suite.
|
||||||
|
|
||||||
|
### Required Remediation
|
||||||
|
|
||||||
|
- Retain distinctive synthetic credential contents in the collection
|
||||||
|
convergence variables; no real credential or live provider call may enter
|
||||||
|
the suite.
|
||||||
|
- Remove the two shell variables used only for log searching and remove the two
|
||||||
|
secret-content grep assertions.
|
||||||
|
- Retain isolated dependency installation, archive boundary checks, FQCN
|
||||||
|
syntax and lint validation, the selected native application checks, and the
|
||||||
|
immediate `changed=0 failed=0` repeat.
|
||||||
|
- Do not replace the removed assertions with another collection-level
|
||||||
|
credential, log, file-content, or implementation-trace test.
|
||||||
|
|
||||||
## Resolution
|
## Resolution
|
||||||
|
|
||||||
Resolved in pipeline-role commit `b15fe8d`. The deferred-work summary now
|
Resolved in collection commits `556b6ed` and `da67b34`.
|
||||||
names operator selection and group-membership management rather than operator
|
|
||||||
access. The shared-filesystem section retains existing-group-member invocation
|
The collection README now uses an explicit `PUSHED_COMMIT_OR_TAG` revision and
|
||||||
as supported behavior and provides a complete consumer-owned
|
the authoritative Gitea URL for both initial and subsequent subtree imports.
|
||||||
`ansible.builtin.user` example that adds a selected account to the runtime
|
It states that the selected revision must be committed, reviewed, and pushed
|
||||||
group. No production role behavior changed.
|
before collection assembly. The examples no longer inspect or depend on a
|
||||||
|
sibling checkout. A disposable repository successfully imported the exact
|
||||||
|
commit advertised by Gitea through the documented remote-only command shape.
|
||||||
|
|
||||||
|
The collection integration driver retains its distinctive synthetic
|
||||||
|
credential inputs but no longer defines separate values solely for log
|
||||||
|
searching or duplicates the standalone pipeline suite's two redaction
|
||||||
|
assertions. Its artifact, dependency, FQCN, native application, and clean
|
||||||
|
repeat coverage remain unchanged.
|
||||||
|
|
||||||
## Required Validation
|
## Required Validation
|
||||||
|
|
||||||
After the documentation correction, run:
|
After remediation, run:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
cd ansible-role-dnd-pipeline && tests/integration
|
cd ansible-collection-dnd
|
||||||
|
bash -n tests/integration
|
||||||
|
tests/integration
|
||||||
git diff --check
|
git diff --check
|
||||||
```
|
```
|
||||||
|
|
||||||
The expected result remains successful native configuration checks,
|
The result must demonstrate isolated dependency bootstrap, collection build
|
||||||
representative cross-identity access, and immediate repeats with `changed=0`
|
and artifact installation, FQCN resolution, the retained native application
|
||||||
and `failed=0`.
|
checks, and immediate clean convergence. The built artifact must still include
|
||||||
|
`roles/pipeline/tasks/main.yml` and exclude the selected development-only
|
||||||
|
subtree content.
|
||||||
|
|
||||||
|
Validate the corrected subtree example against Gitea in a disposable Git
|
||||||
|
repository without modifying the real collection history or relying on the
|
||||||
|
local sibling repository as the source. The standalone pipeline integration
|
||||||
|
suite does not need to be rerun for these collection-only documentation and
|
||||||
|
test-scope changes.
|
||||||
|
|
||||||
## Review Validation Evidence
|
## Review Validation Evidence
|
||||||
|
|
||||||
The independent review inspected the complete diffs for all eight stage
|
The review compared the complete standalone pipeline repository with
|
||||||
commits and confirmed that every dependency pin resolves to the intended
|
`roles/pipeline`; the trees are byte-for-byte identical outside Git metadata.
|
||||||
standalone-role commit. `git diff --check` passed across all five changed role
|
The root bootstrap manifest's role and collection sections exactly match the
|
||||||
repositories. The complete pipeline `tests/integration` entry point passed its
|
two imported pipeline manifests, and `galaxy.yml` declares the same native
|
||||||
isolated dependency installation, syntax check, production-profile lint,
|
collection versions.
|
||||||
native application checks, cross-identity access exercise, configurable
|
|
||||||
profile and version cases, and immediate clean repeats. All repositories were
|
|
||||||
clean before this review document was revised.
|
|
||||||
|
|
||||||
After remediation, the complete pipeline integration entry point and
|
A fresh collection build produced
|
||||||
`git diff --check` passed again. The test fixture was removed and the baseline
|
`rakestraw-dnd-0.1.0.tar.gz`. The archive contains the pipeline task entry
|
||||||
Seriatim version and pipeline configuration were restored during cleanup.
|
point and omits the selected nested tests, Ansible configuration, dependency
|
||||||
|
manifests, and Git ignore file. Installing that artifact into a temporary
|
||||||
|
collection path made `rakestraw.dnd.pipeline` discoverable. A separate
|
||||||
|
isolated bootstrap installed the unified requirements, after which syntax
|
||||||
|
checking and production-profile ansible-lint passed.
|
||||||
|
|
||||||
|
`bash -n ansible-collection-dnd/tests/integration`, manifest consistency
|
||||||
|
checks, `git diff --check`, and collection repository integrity checks also
|
||||||
|
passed during review.
|
||||||
|
|
||||||
|
After remediation, the remote-only subtree command successfully imported the
|
||||||
|
revision advertised by Gitea into a disposable repository, and a fresh
|
||||||
|
collection build succeeded. The complete collection integration entry point
|
||||||
|
then passed isolated dependency installation, artifact construction and
|
||||||
|
installation, syntax checking, production-profile lint, all retained native
|
||||||
|
application checks, and two recaps with `changed=0` and `failed=0`. The
|
||||||
|
standalone pipeline suite was not rerun because neither remediation changed
|
||||||
|
the authoritative pipeline role.
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
# Workspace Status
|
# Workspace Status
|
||||||
|
|
||||||
Last updated: 2026-09-15
|
Last updated: 2026-09-17
|
||||||
|
|
||||||
Current milestone: M1-03 suite-level pipeline role
|
Current milestone: First coordinated suite release
|
||||||
|
|
||||||
Current focus: Publish the completed Notarius role revision required to resume
|
Current focus: Independently review the Feature 0013 implementation.
|
||||||
Feature 0010.
|
|
||||||
|
|
||||||
| ID | Deliverable | Owner | State | Evidence or next step |
|
| ID | Deliverable | Owner | State | Evidence or next step |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
@@ -16,8 +15,8 @@ Feature 0010.
|
|||||||
| M0-05 | Suite-level role repository | ansible-role-dnd-pipeline | done | Repository created and added to `workspace.yml` |
|
| 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-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-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 | blocked | Publish the completed Notarius role revision, then resume Feature 0010 |
|
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | done | Features 0006 through 0011 completed through remediation commit `de1b191` |
|
||||||
| M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism |
|
| M1-04 | Collection assembly | ansible-collection-dnd | done | Implemented and independently reviewed through collection remediation commit `da67b34` |
|
||||||
| F0001 | Install Seriatim from pinned source | ansible-role-seriatim | done | Implementation, integration coverage, and final remediation completed through `fb8dc41` |
|
| 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 |
|
| F0002 | Install and configure Audita | ansible-role-audita | done | Field-specific configuration completed in `e61f02f` and `847c4c3`; full suite passed |
|
||||||
| F0003 | Install and configure Notarius | ansible-role-notarius | done | Implemented and validated through remediation commit `eb4f511` |
|
| F0003 | Install and configure Notarius | ansible-role-notarius | done | Implemented and validated through remediation commit `eb4f511` |
|
||||||
@@ -27,7 +26,10 @@ Feature 0010.
|
|||||||
| F0007 | Deploy D&D campaigns and prompt assets | ansible-role-dnd-pipeline, campaigns, and narratio-prompts | done | Implemented and validated through remediation commit `7572fa3` |
|
| F0007 | Deploy D&D campaigns and prompt assets | ansible-role-dnd-pipeline, campaigns, and narratio-prompts | done | Implemented and validated through remediation commit `7572fa3` |
|
||||||
| F0008 | Define opinionated D&D processing configuration | ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `3e253d7` |
|
| F0008 | Define opinionated D&D processing configuration | ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `3e253d7` |
|
||||||
| F0009 | Establish shared pipeline filesystem and execution | configuration-bearing application roles and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `b15fe8d` |
|
| F0009 | Establish shared pipeline filesystem and execution | configuration-bearing application roles and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `b15fe8d` |
|
||||||
| F0010 | Integrate D&D Notarius extraction | ansible-role-notarius and ansible-role-dnd-pipeline | blocked | Stage 1 completed in Notarius role commit `14a38e04e35ef524d6a97fa7fb5a04981a0a2161`; publish it to the canonical origin before Stage 2 |
|
| F0010 | Integrate D&D Notarius extraction | ansible-role-notarius and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `bbf01e1` |
|
||||||
|
| F0011 | Deliver pipeline credentials and Notarius reuse | ansible-role-narratio and ansible-role-dnd-pipeline | done | Implemented and independently reviewed through remediation commit `de1b191` |
|
||||||
|
| F0012 | Assemble the D&D collection | ansible-collection-dnd and ansible-role-dnd-pipeline | done | Pipeline `600eb21` assembled and validated through collection remediation commit `da67b34` |
|
||||||
|
| F0013 | Publish the first coordinated suite release | all Ansible repositories and workspace | in_progress | Public `v0.1.0` tags: Audita `66ebea9`, Narratio `292d866`, Notarius `14a38e0`, Seriatim `e08c63c`, Scriptorium `8b4c86e`, pipeline `7c2bad8`, collection `63e8f3f`; [collection release](https://gitea.maximumdirect.net/eric/ansible-collection-dnd/releases/tag/v0.1.0) |
|
||||||
| A0001 | Audit completed standalone-role test suites | workspace and standalone roles | done | Findings recorded in `docs/roadmap/test-suite-audit-findings.md` |
|
| 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 |
|
| R0001 | Simplify completed standalone-role test suites | workspace and standalone roles | done | Role commits `e08c63c`, `d2d0b9d`, and `cfecf37` passed implementation and independent review |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user