Complete the Audita amendment and resume Notarius planning
This commit is contained in:
@@ -6,243 +6,244 @@ Status: done
|
||||
|
||||
Provide a small, independently usable `rakestraw.audita` role that installs
|
||||
Audita from a pinned Git tag, builds its executable on the managed host, and
|
||||
manages its versioned YAML configuration. Follow the module-driven Seriatim
|
||||
pattern while adding only the configuration behavior that distinguishes
|
||||
Audita.
|
||||
offers an ergonomic field-specific interface for its versioned YAML
|
||||
configuration. Unspecified optional fields are omitted so Audita retains
|
||||
ownership of its application defaults.
|
||||
|
||||
## Problem or Opportunity
|
||||
|
||||
The `ansible-role-audita` repository currently contains only its initial
|
||||
placeholder files. Audita needs a standalone installer before the suite role
|
||||
can compose the transcript-processing pipeline and supply D&D-specific runtime
|
||||
policy.
|
||||
The completed source-installation flow is concise and correct, but the initial
|
||||
configuration interface exposes only one `audita_config` mapping. That requires
|
||||
every caller to know and reproduce Audita's native nested schema, and it does
|
||||
not provide the ordinary role ergonomics expected for inventory variables.
|
||||
|
||||
An earlier implementation direction depended on the superseded Seriatim
|
||||
fingerprint, sidecar-state, staged-build, and corruption-recovery architecture.
|
||||
This roadmap replaces that direction with a concise implementation that trusts
|
||||
Ansible modules, rebuilds only for required conditions, and keeps production
|
||||
role tasks separate from integration verification.
|
||||
The role should expose documented variables for individual settings and render
|
||||
only values expressly selected by the caller. This permits straightforward
|
||||
`host_vars`, `group_vars`, play variables, and suite-role overrides while
|
||||
allowing upstream default changes to take effect automatically when a setting
|
||||
is not managed by Ansible.
|
||||
|
||||
## Scope
|
||||
|
||||
- Implement `ansible-role-audita` as a conventional standalone role.
|
||||
- Support Ubuntu 26.04 on native `amd64` and `arm64` hosts.
|
||||
- Install Git and the official Go Snap with classic confinement when build
|
||||
dependency management is enabled.
|
||||
- Default the Go Snap channel to `1.26/stable`.
|
||||
- Check out immutable Audita tag `v0.9.1` by default under the root-owned path
|
||||
`/usr/local/src/audita`.
|
||||
- Build Audita with its upstream release build contract and install the native
|
||||
executable at `/usr/local/bin/audita`.
|
||||
- Rebuild when the Git checkout changes or the binary is absent.
|
||||
- Converge the installed binary to `root:root` ownership and mode `0755`.
|
||||
- Manage a versioned Audita YAML configuration at
|
||||
`/usr/local/etc/audita/config.yml`, owned by `root:root` with mode `0644`.
|
||||
- Default the managed configuration to the minimal valid mapping
|
||||
`{"version": 1}`, allowing Audita's own defaults to govern application
|
||||
behavior.
|
||||
- Keep role defaults, argument specifications, README, metadata, dependency
|
||||
declaration, and focused local tests consistent with this contract.
|
||||
- Retain the completed Ubuntu 26.04 `amd64` and `arm64` source installation.
|
||||
- Retain default tag `v0.9.1`, Go Snap channel `1.26/stable`, source path
|
||||
`/usr/local/src/audita`, and binary path `/usr/local/bin/audita`.
|
||||
- Retain rebuild triggers of changed Git checkout or absent binary.
|
||||
- Replace the complete `audita_config` mapping with typed, field-specific
|
||||
configuration variables.
|
||||
- Always render the required configuration schema version, defaulting to `1`.
|
||||
- Define every optional configuration variable as `null` by default and omit
|
||||
its YAML field when it remains null.
|
||||
- Render nested YAML sections only when at least one setting in that section is
|
||||
non-null.
|
||||
- Manage `/usr/local/etc/audita/config.yml` from a Jinja template as
|
||||
`root:root` mode `0644`.
|
||||
- Keep defaults, argument specifications, template, README, metadata,
|
||||
dependency declaration, and focused tests consistent with this contract.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Copying Audita's built-in values into role defaults or the default rendered
|
||||
file.
|
||||
- D&D-specific model selection, concurrency, thresholds, transcript context,
|
||||
or other suite policy. The suite-level role will provide those overrides.
|
||||
- A separate Ansible variable for every field in Audita's configuration
|
||||
schema.
|
||||
- API keys, secret values, environment files, or another secret-delivery
|
||||
mechanism. Configuration may name environment variables but must not contain
|
||||
their secret values.
|
||||
- Creation or management of the `narratio` account, operator groups, campaign
|
||||
data, glossaries, transcript data, or diagnostics directories.
|
||||
- Installation or configuration of another pipeline application.
|
||||
- Services, scheduling, removal behavior, or pipeline composition.
|
||||
- Prebuilt release artifacts or cross-compilation.
|
||||
- Production execution of Audita to validate the build or configuration.
|
||||
- Detection of out-of-band binary modification, compiler changes, or fixed
|
||||
build-command changes.
|
||||
- Build fingerprints, checksums, sidecar state, staged replacement, manual Git
|
||||
cleanup, or special recovery for malformed or adversarial host state.
|
||||
- A shared build helper role or dedicated platform-matrix infrastructure.
|
||||
or other suite policy.
|
||||
- A parallel mapping-based configuration escape hatch or merge/precedence
|
||||
rules between two configuration interfaces.
|
||||
- API keys or other secret values. Variables may select environment-variable
|
||||
names, but the role does not manage their values.
|
||||
- Creation of the `narratio` account or management of runtime, campaign,
|
||||
glossary, transcript, diagnostics, or secret-delivery infrastructure.
|
||||
- Services, scheduling, removal behavior, pipeline composition, prebuilt
|
||||
artifacts, or cross-compilation.
|
||||
- Production execution of Audita for build or configuration validation.
|
||||
- Fingerprints, checksums, sidecar state, staged replacement, manual Git
|
||||
cleanup, compiler inspection, or out-of-band drift detection.
|
||||
|
||||
## Target End State
|
||||
|
||||
On an Ubuntu 26.04 `amd64` or `arm64` host, applying the role with defaults
|
||||
installs or confirms Git and Go, checks out Audita `v0.9.1` at
|
||||
`/usr/local/src/audita`, builds `/usr/local/bin/audita`, and writes
|
||||
`/usr/local/etc/audita/config.yml`. Source and installed files have the stated
|
||||
root ownership and permissions, and the configuration contains `version: 1`.
|
||||
With no configuration overrides, the role writes the minimal valid document:
|
||||
|
||||
An immediate second application reports no changes. A changed Git checkout or
|
||||
missing binary causes one build; configuration changes converge through the
|
||||
ordinary file-management module without rebuilding Audita. Repository-local
|
||||
tests execute the installed CLI to verify the build and validate the managed
|
||||
configuration.
|
||||
```yaml
|
||||
version: 1
|
||||
```
|
||||
|
||||
When a caller sets an optional role variable, the corresponding native Audita
|
||||
field appears in the correct YAML section. Fields whose variables remain null
|
||||
are absent, including their parent sections when no child is selected. Empty
|
||||
lists, empty strings, zero, and other expressly supplied non-null values are
|
||||
rendered rather than mistaken for omission and are left for Audita to validate.
|
||||
|
||||
Installation and configuration converge independently. A configuration-only
|
||||
change does not rebuild the binary, and an immediate repeat reports no changes.
|
||||
Repository-local tests execute Audita to verify the installed version and
|
||||
validate both minimal and representative managed configurations.
|
||||
|
||||
## Repository Ownership
|
||||
|
||||
- `ansible-role-audita` owns the role implementation, public interface,
|
||||
configuration rendering, metadata, dependency declaration, README, and
|
||||
repository-local validation.
|
||||
- `../audita` is the read-only authority for the build, CLI, and configuration
|
||||
contracts.
|
||||
- `rakestraw-ansible` is a read-only style and configuration-policy reference.
|
||||
- `ansible-role-dnd-pipeline` will later own the D&D-specific values supplied
|
||||
through the standalone role's configuration interface.
|
||||
- `ansible-workspace-dnd` owns this roadmap, the eventual staged implementation
|
||||
plan, and aggregate status.
|
||||
- `ansible-role-audita` owns installation, the public configuration interface,
|
||||
template, metadata, README, and repository-local tests.
|
||||
- `../audita` is the read-only authority for build, CLI, configuration schema,
|
||||
and application-default contracts.
|
||||
- `rakestraw-ansible` is a read-only style reference for field-specific role
|
||||
variables and conditional templates; its historical values are not
|
||||
authoritative defaults.
|
||||
- `ansible-role-dnd-pipeline` will later own D&D-specific overrides supplied
|
||||
through the standalone role variables.
|
||||
- `ansible-workspace-dnd` owns this roadmap, the staged plan, and aggregate
|
||||
status.
|
||||
- All other repositories remain unchanged.
|
||||
|
||||
## Constraints and Settled Decisions
|
||||
|
||||
- The selected release is tag `v0.9.1`, which resolves to commit
|
||||
`a84941d68168a1ed9ea7423b6477ae8218be73f9`.
|
||||
- Tags `v0.9.0` and `v0.9.1` resolve to the same commit, so `v0.9.0` cannot
|
||||
exercise checkout-change rebuilding. Focused integration may temporarily
|
||||
select buildable commit `46b7356a3b54a2771ce9a617e4fa3e8d13728cac`
|
||||
before restoring the default tag.
|
||||
- The tag declares Go 1.24.0. The suite-standard Go Snap channel remains
|
||||
`1.26/stable`.
|
||||
- The upstream release build uses package
|
||||
`gitea.maximumdirect.net/eric/audita/cmd/audita`, `CGO_ENABLED=0`,
|
||||
`GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and linker flags `-s -w -X
|
||||
gitea.maximumdirect.net/eric/audita/internal/buildinfo.Version=<version>`.
|
||||
- Audita exposes no release-version command needed by production convergence.
|
||||
The role uses only checkout change and binary absence as build triggers.
|
||||
- Audita configuration schema version `1` is strict. The native command
|
||||
`audita config validate --config <path>` reports `config is valid` for a
|
||||
valid file and is used only by tests.
|
||||
- Audita's default configuration search order prefers
|
||||
`/usr/local/etc/audita/config.yml` over `/etc/audita/config.yml`; the role
|
||||
manages the preferred path.
|
||||
- Configuration is exposed as one mapping rather than many field-specific
|
||||
variables. This preserves Audita's schema and gives the suite role one clear
|
||||
override boundary.
|
||||
- Configuration contains no secrets by default. Consumers use Audita's
|
||||
`api_key_env` fields and arrange secret environment variables outside this
|
||||
feature.
|
||||
- Tasks that install dependencies or manage root-owned application state use
|
||||
task-level `become: true`.
|
||||
- `community.general` is an approved dependency and supplies Snap management;
|
||||
pin version `13.3.0` in the role's collection requirements.
|
||||
- Tag `v0.9.1` resolves to
|
||||
`a84941d68168a1ed9ea7423b6477ae8218be73f9` and retains the build contract
|
||||
already implemented and validated through role commit `3a8c21f`.
|
||||
- Audita's strict schema version is `1`; all other top-level fields are
|
||||
optional and overlay application defaults.
|
||||
- `audita_config_version` names the schema version so `audita_version` remains
|
||||
unambiguously the selected application release.
|
||||
- Optional variables are present in role defaults with YAML null values. This
|
||||
documents the interface and enables argument validation without emitting
|
||||
upstream defaults.
|
||||
- Template conditions use `is not none`, not truthiness, so expressly supplied
|
||||
falsey values are rendered.
|
||||
- String and list values must be safely encoded as YAML values rather than
|
||||
interpolated with hand-written quoting.
|
||||
- A parent mapping is emitted only when at least one corresponding child value
|
||||
is non-null.
|
||||
- The role does not validate Audita's semantic constraints during production
|
||||
convergence. Native validation remains integration-test behavior.
|
||||
- Task-level `become: true`, `community.general` 13.3.0, and all existing
|
||||
installation decisions remain unchanged.
|
||||
|
||||
## Fixed Public Interface
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `audita_version` | `v0.9.1` | Git revision and release value supplied to the build |
|
||||
| `audita_repository_url` | `https://gitea.maximumdirect.net/eric/audita.git` | Source repository |
|
||||
| `audita_source_dir` | `/usr/local/src/audita` | Managed source checkout |
|
||||
| `audita_binary_path` | `/usr/local/bin/audita` | Installed executable |
|
||||
| `audita_manage_build_dependencies` | `true` | Whether to install Git and Go |
|
||||
| `audita_go_snap_channel` | `1.26/stable` | Go Snap channel |
|
||||
| `audita_go_binary` | `/snap/bin/go` | Go executable used for the build |
|
||||
| `audita_config_path` | `/usr/local/etc/audita/config.yml` | Managed configuration file |
|
||||
| `audita_config` | `{"version": 1}` | Complete versioned configuration mapping |
|
||||
Retain these installation variables:
|
||||
|
||||
The package, build flags, linker symbol, environment values, file ownership,
|
||||
and file modes are fixed implementation details. The selected version is both
|
||||
the Git revision and the value supplied to the upstream linker flag.
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `audita_version` | `v0.9.1` |
|
||||
| `audita_repository_url` | `https://gitea.maximumdirect.net/eric/audita.git` |
|
||||
| `audita_source_dir` | `/usr/local/src/audita` |
|
||||
| `audita_binary_path` | `/usr/local/bin/audita` |
|
||||
| `audita_manage_build_dependencies` | `true` |
|
||||
| `audita_go_snap_channel` | `1.26/stable` |
|
||||
| `audita_go_binary` | `/snap/bin/go` |
|
||||
| `audita_config_path` | `/usr/local/etc/audita/config.yml` |
|
||||
|
||||
Provide these configuration variables:
|
||||
|
||||
| Variable | Default | Native field |
|
||||
| --- | --- | --- |
|
||||
| `audita_config_version` | `1` | `version` |
|
||||
| `audita_pipeline_modules` | `null` | `pipeline.modules` |
|
||||
| `audita_output_schema` | `null` | `output.schema` |
|
||||
| `audita_llm_proposal_base_url` | `null` | `llm.proposal.base_url` |
|
||||
| `audita_llm_proposal_model` | `null` | `llm.proposal.model` |
|
||||
| `audita_llm_proposal_api_key_env` | `null` | `llm.proposal.api_key_env` |
|
||||
| `audita_llm_proposal_timeout` | `null` | `llm.proposal.timeout` |
|
||||
| `audita_llm_proposal_max_retries` | `null` | `llm.proposal.max_retries` |
|
||||
| `audita_llm_validation_base_url` | `null` | `llm.validation.base_url` |
|
||||
| `audita_llm_validation_model` | `null` | `llm.validation.model` |
|
||||
| `audita_llm_validation_api_key_env` | `null` | `llm.validation.api_key_env` |
|
||||
| `audita_llm_validation_timeout` | `null` | `llm.validation.timeout` |
|
||||
| `audita_llm_validation_max_retries` | `null` | `llm.validation.max_retries` |
|
||||
| `audita_concurrency_total_llm` | `null` | `concurrency.total_llm` |
|
||||
| `audita_concurrency_proposal_llm` | `null` | `concurrency.proposal_llm` |
|
||||
| `audita_concurrency_validation_llm` | `null` | `concurrency.validation_llm` |
|
||||
| `audita_chunking_target_sections` | `null` | `chunking.target_sections` |
|
||||
| `audita_chunking_max_section_tokens` | `null` | `chunking.max_section_tokens` |
|
||||
| `audita_chunking_min_section_tokens` | `null` | `chunking.min_section_tokens` |
|
||||
| `audita_normalization_max_segment_gap` | `null` | `normalization.max_segment_gap` |
|
||||
| `audita_normalization_ellipsis_gap` | `null` | `normalization.ellipsis_gap` |
|
||||
| `audita_normalization_max_segment_duration` | `null` | `normalization.max_segment_duration` |
|
||||
| `audita_normalization_max_segment_tokens` | `null` | `normalization.max_segment_tokens` |
|
||||
| `audita_thresholds_glossary` | `null` | `thresholds.glossary` |
|
||||
| `audita_thresholds_homophones` | `null` | `thresholds.homophones` |
|
||||
| `audita_thresholds_spoken_word` | `null` | `thresholds.spoken_word` |
|
||||
| `audita_thresholds_grammar` | `null` | `thresholds.grammar` |
|
||||
| `audita_context_description` | `null` | `context.description` |
|
||||
| `audita_diagnostics_work_dir` | `null` | `diagnostics.work_dir` |
|
||||
| `audita_diagnostics_retention` | `null` | `diagnostics.retention` |
|
||||
|
||||
The argument specification types values according to the native field shape.
|
||||
Duration-like fields accept strings or numeric seconds as supported by Audita;
|
||||
do not narrow the application contract unnecessarily.
|
||||
|
||||
## Simplest Viable Implementation
|
||||
|
||||
The expected implementation is approximately nine ordinary tasks in one
|
||||
readable task file:
|
||||
Retain the existing nine-task installation flow. Make only these production
|
||||
changes:
|
||||
|
||||
1. Assert Ubuntu 26.04 and architecture `x86_64` or `aarch64`.
|
||||
2. Install Git with `ansible.builtin.apt`, including
|
||||
`cache_valid_time: 3600`, when dependency management is enabled.
|
||||
3. Install the classic Go Snap from `audita_go_snap_channel` with
|
||||
`community.general.snap` when dependency management is enabled.
|
||||
4. Create the source, binary, and configuration parent directories with one
|
||||
`ansible.builtin.file` loop.
|
||||
5. Check out `audita_version` with `ansible.builtin.git`, `force: true`, and
|
||||
register the module result.
|
||||
6. Inspect whether `audita_binary_path` exists with `ansible.builtin.stat`.
|
||||
7. Run the upstream Go build through `audita_go_binary` when the checkout
|
||||
changed or the binary is absent.
|
||||
8. Converge recursive source ownership and binary ownership and mode with one
|
||||
item-driven `ansible.builtin.file` loop.
|
||||
9. Serialize `audita_config` as YAML and manage `audita_config_path` with
|
||||
`ansible.builtin.copy`.
|
||||
1. Replace `audita_config` in defaults and argument specifications with the
|
||||
field-specific variables above.
|
||||
2. Add `templates/config.yml.j2`, always rendering `version` and conditionally
|
||||
rendering every optional field and necessary parent mapping.
|
||||
3. Replace the final `ansible.builtin.copy` task with one
|
||||
`ansible.builtin.template` task using the existing destination, ownership,
|
||||
and mode.
|
||||
|
||||
Apply task-level privilege escalation only to tasks that require it. Use
|
||||
`argv` for the build command, and put its two conditions directly on the build
|
||||
task. Do not add a rebuild fact, handler, handler flush, executable discovery,
|
||||
compiler interrogation, configuration preflight, or post-operation validation
|
||||
to production tasks.
|
||||
Do not add configuration assembly facts, nested merge filters, validation
|
||||
commands, preliminary file probes, or multiple configuration tasks. The
|
||||
template is the direct expression of the selected configuration state.
|
||||
|
||||
## Rationale and Alternatives
|
||||
|
||||
Audita's installation mechanics are intentionally the same as Seriatim's:
|
||||
declarative dependency and checkout management surrounding one imperative
|
||||
build command. The binary existence probe is justified because Ansible cannot
|
||||
infer whether that command's output exists; no other build-state model is
|
||||
needed.
|
||||
Field-specific variables are the ordinary ergonomic interface for inventory
|
||||
and composing roles. Nullable defaults make that interface discoverable and
|
||||
typed without freezing a duplicate copy of Audita's application defaults into
|
||||
Ansible. Conditional rendering also preserves the distinction between an
|
||||
unset field and a caller intentionally supplying a falsey value.
|
||||
|
||||
A single configuration mapping is smaller and more durable than duplicating
|
||||
Audita's evolving schema as dozens of role variables. A minimal default mapping
|
||||
produces a valid configuration while preserving upstream defaults. The future
|
||||
suite role can supply its complete D&D-specific mapping without coupling the
|
||||
standalone role to one deployment.
|
||||
|
||||
Managing the preferred `/usr/local/etc` path follows the application's own
|
||||
discovery order and keeps locally installed software and its configuration
|
||||
together. `/etc/audita/config.yml` remains an unmanaged application fallback.
|
||||
Leaving variables entirely undefined would produce the same file but weaken
|
||||
interface documentation and argument validation. Section-level dictionaries
|
||||
would shorten the template but require callers to understand more of the
|
||||
native nested schema. Retaining `audita_config` beside field variables would
|
||||
require unneeded merge and precedence semantics. None is preferable to the
|
||||
single field-specific interface.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Unsupported distributions, Ubuntu releases, and architectures fail before
|
||||
application state is modified.
|
||||
- Default execution on the local Ubuntu 26.04 host installs or confirms Git
|
||||
and Go and checks out Audita tag `v0.9.1` at commit
|
||||
`a84941d68168a1ed9ea7423b6477ae8218be73f9`.
|
||||
- The role builds with the fixed upstream contract and installs
|
||||
`/usr/local/bin/audita` as `root:root` mode `0755`.
|
||||
- The managed source checkout is recursively owned by `root:root`.
|
||||
- The default configuration is a valid schema-version `1` document at
|
||||
`/usr/local/etc/audita/config.yml`, owned by `root:root` with mode `0644`.
|
||||
- Repository-local tests successfully execute the installed CLI and receive
|
||||
`config is valid` when validating the managed configuration.
|
||||
- An immediate second role run reports no changes.
|
||||
- A missing binary causes one rebuild followed by an unchanged run.
|
||||
- A changed checkout causes one rebuild followed by an unchanged run.
|
||||
- A configuration change updates only configuration state and does not rebuild
|
||||
the binary.
|
||||
- Dependency opt-out accepts a caller-supplied `audita_go_binary`.
|
||||
- A play connecting as an ordinary sudo-capable user can apply the role without
|
||||
play-level privilege escalation.
|
||||
- Defaults and argument specifications contain exactly the nine variables in
|
||||
the Fixed Public Interface.
|
||||
- The implementation contains no production CLI validation, fingerprints,
|
||||
checksums, sidecar build state, manual Git reset or clean commands, or probes
|
||||
before state already managed by APT, Snap, `file`, `git`, or `copy`.
|
||||
- Syntax checking, production-profile ansible-lint, focused local convergence,
|
||||
configuration validation, and clean repeated runs pass.
|
||||
- Role documentation describes the actual behavior, dependency opt-out,
|
||||
complete configuration mapping, privilege use, and local test effects.
|
||||
- No repository other than `ansible-role-audita` and the workspace control
|
||||
repository is modified.
|
||||
- All existing source-installation and platform acceptance criteria continue
|
||||
to pass without production task-flow expansion.
|
||||
- Defaults and argument specifications contain exactly the eight installation
|
||||
variables and thirty configuration variables in the Fixed Public Interface.
|
||||
- No `audita_config` compatibility variable remains.
|
||||
- Default convergence writes a YAML mapping containing exactly `version: 1`.
|
||||
- Every optional field is absent when its variable is null.
|
||||
- Setting a representative value in every configuration section renders the
|
||||
correct nested native fields and passes `audita config validate`.
|
||||
- Explicit falsey non-null values are rendered rather than omitted; semantic
|
||||
validity remains Audita's responsibility.
|
||||
- Configuration changes run the template task but not the build task and
|
||||
reach an unchanged immediate repeat.
|
||||
- The installed configuration remains a regular file owned by `root:root`
|
||||
with mode `0644`.
|
||||
- Production tasks do not invoke Audita, inspect the existing configuration,
|
||||
or construct intermediate configuration state.
|
||||
- The README documents each variable, null-as-unmanaged behavior, safe secret
|
||||
environment-variable naming, and the distinction between application and
|
||||
suite defaults.
|
||||
- Syntax checking, production-profile ansible-lint, complete integration
|
||||
testing, native minimal and representative configuration validation, and
|
||||
clean repeated runs pass.
|
||||
- Only `ansible-role-audita` and the workspace control repository change.
|
||||
|
||||
## Dependencies and Follow-up Work
|
||||
|
||||
The managed host requires access to the Audita Git repository, Ubuntu Snap
|
||||
infrastructure, and Go module sources. Runtime processing also requires a
|
||||
glossary, transcript inputs, LLM endpoints, and secret environment variables;
|
||||
those are consumers' or later suite-level features, not installation
|
||||
dependencies.
|
||||
The existing Audita role through commit `3a8c21f` is the implementation
|
||||
baseline. The managed host and test prerequisites are unchanged.
|
||||
|
||||
Implementation and focused integration coverage were completed in
|
||||
`ansible-role-audita` commits `47f1852`, `d37f590`, and `3a8c21f`. The D&D
|
||||
pipeline role can now select concrete `audita_config` values through the
|
||||
standalone role's complete-configuration interface.
|
||||
The configuration amendment was completed in `ansible-role-audita` commits
|
||||
`e61f02f` and `847c4c3` and validated by its complete integration suite. The
|
||||
proposed Notarius roadmap should use the same nullable field-specific approach
|
||||
where appropriate.
|
||||
|
||||
## Potential Future Hardening
|
||||
|
||||
- Build into a temporary path before replacing the installed executable.
|
||||
- Verify source signatures or release checksums.
|
||||
- Detect compiler, build-command, or out-of-band binary changes.
|
||||
- Validate configuration during production convergence.
|
||||
- Manage a dedicated runtime account, secret environment, diagnostics path,
|
||||
service, or schedule if later operating requirements select them.
|
||||
- Add dedicated Ubuntu release and architecture test matrices.
|
||||
- Validate configuration during production convergence if later operating
|
||||
requirements explicitly select that behavior.
|
||||
- Manage secret environment delivery, diagnostics paths, runtime accounts, or
|
||||
services as separate suite-level or application-level features.
|
||||
- Detect source signatures, compiler drift, or out-of-band binary changes if
|
||||
the threat model changes.
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
# Feature 0003: Notarius Source Installation and Configuration
|
||||
|
||||
Status: proposed
|
||||
|
||||
Planning note: the installation decisions are ready for review, but the
|
||||
configuration interface was drafted before the nullable field-specific
|
||||
convention was adopted. Revise that interface to follow
|
||||
`docs/conventions.md` before approving this roadmap.
|
||||
|
||||
## Summary
|
||||
|
||||
Provide a small, independently usable `rakestraw.notarius` role that installs
|
||||
Notarius from a pinned Git tag, builds its executable on the managed host, and
|
||||
manages its versioned YAML configuration. Reuse the established module-driven
|
||||
application-role pattern while leaving D&D pipeline policy to the suite-level
|
||||
role.
|
||||
|
||||
## Problem or Opportunity
|
||||
|
||||
The `ansible-role-notarius` repository currently contains only its initial
|
||||
placeholder files. Notarius is one of the five required pipeline applications
|
||||
and needs an independently usable installation and native-configuration role
|
||||
before the suite role can compose it with Seriatim, Audita, and the remaining
|
||||
applications.
|
||||
|
||||
Seriatim and Audita have established the preferred source-build architecture.
|
||||
Notarius can use the same concise task flow, with only its native configuration
|
||||
and build contract differing.
|
||||
|
||||
## Scope
|
||||
|
||||
- Implement `ansible-role-notarius` as a conventional standalone role.
|
||||
- Support Ubuntu 26.04 on native `amd64` and `arm64` hosts.
|
||||
- Install Git and the official Go Snap with classic confinement when build
|
||||
dependency management is enabled.
|
||||
- Default the Go Snap channel to `1.26/stable`.
|
||||
- Check out immutable Notarius tag `v0.6.0` by default under the root-owned
|
||||
path `/usr/local/src/notarius`.
|
||||
- Build Notarius with its upstream release build contract and install the
|
||||
native executable at `/usr/local/bin/notarius`.
|
||||
- Rebuild when the Git checkout changes or the binary is absent.
|
||||
- Converge the installed binary to `root:root` ownership and mode `0755`.
|
||||
- Manage a versioned Notarius YAML configuration at
|
||||
`/usr/local/etc/notarius/config.yml`, owned by `root:root` with mode `0644`.
|
||||
- Default the managed configuration to the minimal valid mapping
|
||||
`{"version": 4}`, allowing Notarius's built-in defaults to govern behavior.
|
||||
- Keep defaults, argument specifications, README, metadata, dependency
|
||||
declaration, and focused local tests consistent with this contract.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- A D&D pipeline definition, module selection, LLM profile, concurrency
|
||||
policy, output paths, cache policy, or other suite-specific configuration.
|
||||
- A separate Ansible variable for every Notarius configuration field.
|
||||
- API keys, secret values, environment files, or another secret-delivery
|
||||
mechanism.
|
||||
- PromptKit profiles or other externally maintained prompt content.
|
||||
- Creation or management of the `narratio` account, operator groups, campaign
|
||||
data, runtime output, debug, cache, checkpoint, or transcript directories.
|
||||
- Installation or configuration of another pipeline application.
|
||||
- Services, scheduling, removal behavior, or pipeline composition.
|
||||
- Prebuilt release artifacts or cross-compilation.
|
||||
- Production execution of Notarius to validate the build or configuration.
|
||||
- Detection of out-of-band binary modification, compiler changes, or fixed
|
||||
build-command changes.
|
||||
- Build fingerprints, checksums, sidecar state, staged replacement, manual Git
|
||||
cleanup, or special recovery for malformed or adversarial host state.
|
||||
- A shared build helper role or dedicated platform-matrix infrastructure.
|
||||
|
||||
## Target End State
|
||||
|
||||
On an Ubuntu 26.04 `amd64` or `arm64` host, applying the role with defaults
|
||||
installs or confirms Git and Go, checks out Notarius `v0.6.0` at
|
||||
`/usr/local/src/notarius`, builds `/usr/local/bin/notarius`, and writes
|
||||
`/usr/local/etc/notarius/config.yml`. Source and installed files have the
|
||||
stated root ownership and permissions, and the configuration contains
|
||||
`version: 4`.
|
||||
|
||||
An immediate second application reports no changes. A changed Git checkout or
|
||||
missing binary causes one build; configuration changes converge independently
|
||||
through the ordinary file-management module. Repository-local tests execute
|
||||
the installed CLI to verify the selected build and validate the managed
|
||||
configuration.
|
||||
|
||||
## Repository Ownership
|
||||
|
||||
- `ansible-role-notarius` owns the role implementation, public interface,
|
||||
configuration serialization, metadata, dependency declaration, README, and
|
||||
repository-local validation.
|
||||
- `../notarius` is the read-only authority for build, CLI, and configuration
|
||||
contracts.
|
||||
- `rakestraw-ansible` is a read-only style and deployment-policy reference.
|
||||
- `ansible-role-dnd-pipeline` will later own the D&D-specific configuration
|
||||
supplied through the standalone role's mapping interface.
|
||||
- `ansible-workspace-dnd` owns this roadmap, the eventual staged plan, and
|
||||
aggregate status.
|
||||
- All other repositories remain unchanged.
|
||||
|
||||
## Constraints and Settled Decisions
|
||||
|
||||
- The selected release is tag `v0.6.0`, which resolves to commit
|
||||
`77ae132e5609916da40dcd4fcc749c000a63cbac`.
|
||||
- The release declares Go 1.25.5. The suite-standard Go Snap channel remains
|
||||
`1.26/stable` and satisfies that requirement.
|
||||
- The upstream release build uses package `./cmd/notarius`, `CGO_ENABLED=0`,
|
||||
`GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and linker flag
|
||||
`-X gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override=<version>`.
|
||||
- `notarius --version` prints `notarius <version>`. This is test evidence, not
|
||||
an additional production rebuild trigger or post-build convergence task.
|
||||
- Notarius configuration schema version 4 explicitly supports a document
|
||||
containing only `version: 4`, with omitted values supplied by application
|
||||
defaults.
|
||||
- `notarius config validate --config <path>` validates a managed configuration
|
||||
without requiring a pipeline selection. It is used only by tests.
|
||||
- Configuration discovery uses an explicit CLI path, then `NOTARIUS_CONFIG`,
|
||||
then `/usr/local/etc/notarius/config.yml`; the role manages the installed
|
||||
default path.
|
||||
- Configuration is exposed as one complete mapping. The suite role will later
|
||||
supply the full D&D pipeline and operating policy through that boundary.
|
||||
- Configuration contains no secrets by default. Consumers arrange any secret
|
||||
environment variables outside this feature.
|
||||
- Tasks that install dependencies or manage root-owned state use task-level
|
||||
`become: true`.
|
||||
- `community.general` supplies Snap management and is pinned to version
|
||||
`13.3.0` in the role's collection requirements.
|
||||
- Tag `v0.5.0`, commit
|
||||
`61436d7c186af57b06004e090ceac898e83cdb71`, remains buildable with the same
|
||||
Go requirement, package, linker symbol, and configuration schema and may be
|
||||
used for focused checkout-change coverage before restoring `v0.6.0`.
|
||||
|
||||
## Fixed Public Interface
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `notarius_version` | `v0.6.0` | Git revision and release value supplied to the build |
|
||||
| `notarius_repository_url` | `https://gitea.maximumdirect.net/eric/notarius.git` | Source repository |
|
||||
| `notarius_source_dir` | `/usr/local/src/notarius` | Managed source checkout |
|
||||
| `notarius_binary_path` | `/usr/local/bin/notarius` | Installed executable |
|
||||
| `notarius_manage_build_dependencies` | `true` | Whether to install Git and Go |
|
||||
| `notarius_go_snap_channel` | `1.26/stable` | Go Snap channel |
|
||||
| `notarius_go_binary` | `/snap/bin/go` | Go executable used for the build |
|
||||
| `notarius_config_path` | `/usr/local/etc/notarius/config.yml` | Managed configuration file |
|
||||
| `notarius_config` | `{"version": 4}` | Complete versioned configuration mapping |
|
||||
|
||||
The package, build flags, linker symbol, environment values, file ownership,
|
||||
and modes are fixed implementation details. The selected version is both the
|
||||
Git revision and the value supplied to the upstream linker flag.
|
||||
|
||||
## Simplest Viable Implementation
|
||||
|
||||
The expected implementation is approximately nine ordinary tasks in one
|
||||
readable task file:
|
||||
|
||||
1. Assert Ubuntu 26.04 and architecture `x86_64` or `aarch64`.
|
||||
2. Install Git with `ansible.builtin.apt`, including
|
||||
`cache_valid_time: 3600`, when dependency management is enabled.
|
||||
3. Install the classic Go Snap from `notarius_go_snap_channel` with
|
||||
`community.general.snap` when dependency management is enabled.
|
||||
4. Create source, binary, and configuration parent directories with one
|
||||
`ansible.builtin.file` loop.
|
||||
5. Check out `notarius_version` with `ansible.builtin.git`, `force: true`, and
|
||||
register the module result.
|
||||
6. Inspect whether `notarius_binary_path` exists with
|
||||
`ansible.builtin.stat`.
|
||||
7. Run the upstream Go build through `notarius_go_binary` when the checkout
|
||||
changed or the binary is absent.
|
||||
8. Converge recursive source ownership and binary ownership and mode with one
|
||||
item-driven `ansible.builtin.file` loop.
|
||||
9. Serialize `notarius_config` as YAML and manage `notarius_config_path` with
|
||||
`ansible.builtin.copy`.
|
||||
|
||||
Apply task-level privilege escalation only where required. Use `argv` for the
|
||||
build command and put its two conditions directly on the build task. Do not
|
||||
add a rebuild fact, handler, handler flush, executable discovery, compiler or
|
||||
version interrogation, configuration preflight, or post-operation validation
|
||||
to production tasks.
|
||||
|
||||
## Rationale and Alternatives
|
||||
|
||||
Notarius has the same installation mechanics as the completed Seriatim and
|
||||
Audita roles: declarative dependency and checkout management surrounding one
|
||||
imperative build command. Binary existence is the only state probe Ansible
|
||||
needs because it controls whether that command must run.
|
||||
|
||||
A single configuration mapping preserves Notarius's strict native schema and
|
||||
avoids duplicating a large, evolving configuration surface as role variables.
|
||||
The minimal valid document keeps the standalone role useful without embedding
|
||||
D&D policy. The suite role can later provide the maintained pipeline,
|
||||
PromptKit profile selection, concurrency, state paths, and other integrated
|
||||
values as one complete override.
|
||||
|
||||
Managing `/usr/local/etc/notarius/config.yml` follows the application's own
|
||||
configuration discovery contract and aligns locally installed software with
|
||||
its configuration.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Unsupported distributions, Ubuntu releases, and architectures fail before
|
||||
application state is modified.
|
||||
- Default execution on the local Ubuntu 26.04 host installs or confirms Git
|
||||
and Go and checks out tag `v0.6.0` at commit
|
||||
`77ae132e5609916da40dcd4fcc749c000a63cbac`.
|
||||
- The role builds with the fixed upstream contract and installs
|
||||
`/usr/local/bin/notarius` as a regular file owned by `root:root` with mode
|
||||
`0755`.
|
||||
- The managed source checkout is recursively owned by `root:root`.
|
||||
- The default schema-version 4 configuration is installed at
|
||||
`/usr/local/etc/notarius/config.yml` as a regular file owned by `root:root`
|
||||
with mode `0644`.
|
||||
- Repository-local tests receive `notarius v0.6.0` from the installed CLI and
|
||||
successfully validate the managed configuration.
|
||||
- An immediate second role run reports no changes.
|
||||
- A missing binary causes one rebuild followed by an unchanged run.
|
||||
- A changed checkout causes one rebuild followed by an unchanged run.
|
||||
- A configuration change updates only configuration state and does not rebuild
|
||||
the binary.
|
||||
- Dependency opt-out accepts a caller-supplied `notarius_go_binary`.
|
||||
- A play connecting as an ordinary sudo-capable user can apply the role without
|
||||
play-level privilege escalation.
|
||||
- Defaults and argument specifications contain exactly the nine variables in
|
||||
the Fixed Public Interface.
|
||||
- Production tasks contain no CLI validation, fingerprints, checksums, sidecar
|
||||
state, manual Git reset or clean commands, or probes before state already
|
||||
managed by APT, Snap, `file`, `git`, or `copy`.
|
||||
- Syntax checking, production-profile ansible-lint, focused local convergence,
|
||||
CLI verification, configuration validation, and clean repeated runs pass.
|
||||
- Role documentation describes actual behavior, dependency opt-out, the
|
||||
complete configuration mapping, privilege use, and integration-test effects.
|
||||
- No repository other than `ansible-role-notarius` and the workspace control
|
||||
repository is modified.
|
||||
|
||||
## Dependencies and Follow-up Work
|
||||
|
||||
The managed host requires access to the Notarius Git repository, Ubuntu Snap
|
||||
infrastructure, and Go module sources. Actual transcript processing also needs
|
||||
a configured pipeline, input artifacts, PromptKit assets and endpoints, and
|
||||
secret environment variables; those belong to consumers or later suite-level
|
||||
work.
|
||||
|
||||
After this roadmap is approved, replace the pending notice at
|
||||
`docs/roadmap/implementation.md` with a numbered staged Notarius implementation
|
||||
plan. The pipeline role can select concrete `notarius_config` values after the
|
||||
standalone interface is implemented and reviewed.
|
||||
|
||||
## Potential Future Hardening
|
||||
|
||||
- Build into a temporary path before replacing the installed executable.
|
||||
- Verify source signatures or release checksums.
|
||||
- Detect compiler, build-command, or out-of-band binary changes.
|
||||
- Validate configuration during production convergence.
|
||||
- Manage a dedicated runtime account, secret environment, state paths,
|
||||
service, or schedule if later operating requirements select them.
|
||||
- Add dedicated Ubuntu release and architecture test matrices.
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Status: pending
|
||||
|
||||
No implementation plan is currently active. Feature 0002 was completed in
|
||||
`ansible-role-audita` through commit `3a8c21f`; its durable scope and rationale
|
||||
remain in
|
||||
No implementation plan is currently active. The Feature 0002 configuration
|
||||
amendment was completed in `ansible-role-audita` commits `e61f02f` and
|
||||
`847c4c3`. Its durable scope remains in
|
||||
[the Feature 0002 roadmap](features/0002-audita-source-installation-and-configuration.md),
|
||||
and its review history remains in [the remediation record](remediation.md).
|
||||
|
||||
Select and approve the next feature roadmap before replacing this notice with
|
||||
a new staged implementation plan.
|
||||
Feature 0003 is the next proposed unit of work. Review and approve its durable
|
||||
roadmap before replacing this notice with a staged implementation plan.
|
||||
|
||||
@@ -1,134 +1,40 @@
|
||||
# Feature 0002 Remediation Review
|
||||
# Feature 0002A Remediation Review
|
||||
|
||||
Status: resolved
|
||||
|
||||
The Audita production task flow implements the approved architecture and the
|
||||
complete integration suite passes. The following residual issues should be
|
||||
corrected before Feature 0002 is accepted.
|
||||
The field-specific Audita configuration implementation has the intended
|
||||
architecture and its complete integration suite passes.
|
||||
|
||||
## Finding 1: Correct the Declared Role License
|
||||
|
||||
Severity: medium
|
||||
|
||||
`ansible-role-audita/meta/main.yml` declares `BSD-3-Clause`, but the
|
||||
repository's `LICENSE` file is CC0 1.0 Universal. Published role metadata must
|
||||
identify the license actually granted by the repository.
|
||||
|
||||
### Required Remediation
|
||||
|
||||
- Change `galaxy_info.license` to the Galaxy-compatible SPDX identifier
|
||||
`CC0-1.0`.
|
||||
- Do not replace or otherwise alter the existing license text.
|
||||
|
||||
### Validation
|
||||
|
||||
- `meta/main.yml` and `LICENSE` identify the same license.
|
||||
- Production-profile ansible-lint passes.
|
||||
|
||||
## Finding 2: Describe All Integration-Test Host Effects
|
||||
## Finding 2: Synchronize Amendment Progress Tracking
|
||||
|
||||
Severity: low
|
||||
|
||||
`ansible-role-audita/README.md` says that the integration suite mutates only
|
||||
the three Audita paths and its private temporary directory. Default
|
||||
convergence also enables dependency management, so on a fresh supported host
|
||||
the suite may install Git through APT, refresh the APT cache, and install the
|
||||
Go Snap. The statement is therefore incomplete.
|
||||
The configuration amendment was completed in `ansible-role-audita` commits
|
||||
`e61f02f` and `847c4c3`, while the implementation plan and workspace status
|
||||
still described it as awaiting execution.
|
||||
|
||||
### Required Remediation
|
||||
### Resolution
|
||||
|
||||
- State that the suite may install or converge Git and the Go Snap in addition
|
||||
to managing the listed Audita paths.
|
||||
- Retain the statement that temporary test-specific files are confined to the
|
||||
private temporary directory.
|
||||
- Recorded the completed amendment commits in the durable Feature 0002
|
||||
roadmap.
|
||||
- Marked Feature 0002 complete in workspace status.
|
||||
- Replaced the completed fixed-location implementation plan with a pending-plan
|
||||
notice for Feature 0003.
|
||||
- Preserved Feature 0003 as the next proposed unit of work and identified its
|
||||
configuration-interface revision as the next roadmap-review step.
|
||||
|
||||
### Validation
|
||||
## Review Conclusion
|
||||
|
||||
- The README accurately describes package/Snap effects and managed filesystem
|
||||
paths.
|
||||
- The description agrees with `tests/integration` and the role defaults.
|
||||
No code remediation was required. A proposed assertion that the configuration
|
||||
was a regular file was rejected because a successful
|
||||
`ansible.builtin.template` operation already establishes the specified file
|
||||
state. Adding another assertion would re-prove the module's documented
|
||||
postcondition and conflict with the workspace convention to trust Ansible's
|
||||
abstraction boundary.
|
||||
|
||||
## Finding 3: Complete Binary-Type Verification
|
||||
|
||||
Severity: low
|
||||
|
||||
`tests/verify.yml` checks binary ownership, mode, and executability, but does
|
||||
not assert that `/usr/local/bin/audita` is a regular file. Stage 1 explicitly
|
||||
requires baseline verification of binary type and metadata. The production
|
||||
`file` task establishes this invariant, but the focused verification does not
|
||||
provide the planned evidence for it.
|
||||
|
||||
### Required Remediation
|
||||
|
||||
- Add an assertion for `audita_binary_metadata.stat.isreg` to the existing
|
||||
binary metadata check.
|
||||
- Do not add another probe or production task.
|
||||
|
||||
### Validation
|
||||
|
||||
- `tests/verify.yml` confirms regular-file type, ownership, mode, and
|
||||
executability from its existing `stat` result.
|
||||
- The integration suite passes.
|
||||
|
||||
## Finding 4: Synchronize Implementation Progress Tracking
|
||||
|
||||
Severity: low
|
||||
|
||||
Both implementation stages are annotated complete in
|
||||
`docs/roadmap/implementation.md`, at role commits `47f1852` and `d37f590`, but
|
||||
the plan remains `ready`, its progress notes still say execution is ready to
|
||||
begin, and `docs/status.md` still describes execution as the current activity.
|
||||
The recorded state should show that implementation is complete and remediation
|
||||
review is in progress.
|
||||
|
||||
The two workspace commits that added stage-completion annotations also diverge
|
||||
from the plan's instruction that the out-of-band executor leave workspace
|
||||
planning files unchanged. No implementation code was placed in the wrong
|
||||
repository, so this requires tracking cleanup rather than code movement.
|
||||
|
||||
### Required Remediation
|
||||
|
||||
- Set the plan to `in_progress` while findings remain open and replace its
|
||||
stale progress note with both completed stage commits and the current
|
||||
remediation state.
|
||||
- Update workspace status so Feature 0002 is `in_progress`, with implementation
|
||||
complete and remediation pending, and make review/remediation the current
|
||||
focus.
|
||||
- Do not mark Feature 0002 `done` until remediation is implemented and
|
||||
reviewed.
|
||||
|
||||
### Validation
|
||||
|
||||
- The plan's status, stage annotations, and progress notes describe one
|
||||
consistent state.
|
||||
- Workspace status agrees with the implementation and remediation records.
|
||||
- `git diff --check` passes in the workspace repository.
|
||||
|
||||
## Review Validation Evidence
|
||||
|
||||
The review ran the complete `ansible-role-audita/tests/integration` suite on
|
||||
Ubuntu 26.04 with Ansible Core 2.21.3 and ansible-lint 26.8.0. It passed syntax
|
||||
checking, production-profile lint, baseline and repeated convergence,
|
||||
missing-binary rebuilding, dependency opt-out with a caller-supplied Go
|
||||
executable, metadata repair without rebuilding, configuration-only
|
||||
convergence, alternate-checkout rebuilding, default restoration, native
|
||||
configuration validation, and all three platform-rejection cases.
|
||||
|
||||
The final state was default commit
|
||||
`a84941d68168a1ed9ea7423b6477ae8218be73f9`, a `root:root` mode `0755` binary,
|
||||
a `root:root` mode `0644` configuration, and native validation output
|
||||
`config is valid`. `bash -n tests/integration` and `git diff --check` also
|
||||
passed. All nested repository working trees remained clean.
|
||||
|
||||
## Resolution
|
||||
|
||||
All four findings were implemented and validated on 2026-09-08. The role now
|
||||
declares `CC0-1.0`, its README identifies dependency-management effects, and
|
||||
its existing binary `stat` result proves regular-file type. Workspace tracking
|
||||
records the completed and accepted feature. Role remediation was committed as
|
||||
`3a8c21f`.
|
||||
|
||||
Validation passed with the complete `tests/integration` suite,
|
||||
production-profile ansible-lint, `bash -n tests/integration`, and
|
||||
`git diff --check` in both changed repositories. The production task flow was
|
||||
not changed.
|
||||
The review ran the complete `tests/integration` suite on Ubuntu 26.04 with
|
||||
Ansible Core 2.21.3 and ansible-lint 26.8.0. It passed default minimal
|
||||
rendering, representative nested rendering, explicit falsey values, native
|
||||
configuration validation, configuration-only convergence, both rebuild
|
||||
triggers, dependency opt-out, metadata repair, restored default state,
|
||||
repeated convergence, and platform rejection. `git diff --check` also passed.
|
||||
|
||||
Reference in New Issue
Block a user