Files
ansible-workspace-dnd/docs/roadmap/features/0002-audita-source-installation-and-configuration.md

13 KiB

Feature 0002: Audita Source Installation and Configuration

Status: done

Summary

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.

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.

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.

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.

Non-goals

  • 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.

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.

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.

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.
  • 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.

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

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.

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

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.

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.

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.

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.

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.

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.

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.