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

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

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

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

With no configuration overrides, the role writes the minimal valid document:

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

  • 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

Retain these installation variables:

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

Retain the existing nine-task installation flow. Make only these production changes:

  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.

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

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.

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

  • 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 existing Audita role through commit 3a8c21f is the implementation baseline. The managed host and test prerequisites are unchanged.

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

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