# Ansible Role: Audita Installs and configures [Audita](https://gitea.maximumdirect.net/eric/audita) from source on Ubuntu 26.04 (`x86_64` or `aarch64`). The role requires gathered facts and uses privilege escalation on tasks that install dependencies or manage root-owned application state. ## Variables Every invocation requires caller-supplied `audita_backends` and `audita_llm_proposal_profile`. Neither has a role default. ```yaml audita_version: v2.0.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 audita_config_owner: root audita_config_group: root audita_config_directory_mode: "0755" audita_config_file_mode: "0644" audita_config_version: 2 audita_profiles_dir: null audita_pipeline_modules: null audita_output_schema: null audita_llm_validation_profile: null audita_llm_transient_retries: null audita_llm_repair_attempts: null audita_llm_operation_timeout: null audita_validation_max_prompt_tokens: null audita_chunking_target_sections: null audita_chunking_max_section_tokens: null audita_chunking_min_section_tokens: null audita_normalization_max_segment_gap: null audita_normalization_ellipsis_gap: null audita_normalization_max_segment_duration: null audita_normalization_max_segment_tokens: null audita_thresholds_glossary: null audita_thresholds_homophones: null audita_thresholds_spoken_word: null audita_thresholds_grammar: null audita_context_description: null audita_reporting_enabled: null audita_reporting_stdout_dir: null audita_diagnostics_debug: null audita_diagnostics_work_dir: null ``` When `audita_manage_build_dependencies` is `false`, Git and the executable selected by `audita_go_binary` must already be available. Otherwise, the role installs Git with APT and the classic Go Snap from `audita_go_snap_channel`. The checkout is authoritative: local source changes are discarded while selecting `audita_version`. The role builds Audita directly to `audita_binary_path` using `audita_go_binary`, `CGO_ENABLED=0`, `GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and release linker metadata. It rebuilds when the checkout changes or the binary is absent. The source tree is recursively owned by `root:root`; the binary is `root:root` mode `0755`. The configuration variables map directly to Audita's version-2 YAML fields. `audita_backends` and `audita_llm_proposal_profile` are required caller inputs; the role has no defaults for them. Callers own the selected PromptKit profile files. Every optional variable defaults to `null`; null values and their empty parent sections are omitted, allowing Audita to retain ownership of its built-in defaults. `audita_config_version` always renders as `version` and defaults to `2`. The role manages `audita_config_path | dirname` and the resulting file with the `audita_config_owner`, `audita_config_group`, `audita_config_directory_mode`, and `audita_config_file_mode` inputs. The standalone defaults are `root:root`, directory mode `0755`, and file mode `0644`. Composing roles may override these generic configuration inputs for their own deployment policy. Backend `credential` values are explicit environment-variable reference names, not secret values. Every surviving reference must resolve to a nonempty value when Audita loads configuration, including references on unselected backends. An omitted or null credential permits unauthenticated local use. The role does not supply secret values, start a service, or probe profiles during convergence. ## Migrating from the version-1 role This revision renders version-2 configuration only. Existing version-1 users can retain the previous role revision while planning a coordinated migration. The old fields have no compatibility aliases: | Previous role inputs | Version-2 destination | | --- | --- | | `audita_llm_{proposal,validation}_base_url` | `audita_backends..endpoint`; both selections may share one backend. | | `audita_llm_{proposal,validation}_api_key_env` | `audita_backends..credential`, an explicit environment-variable name. | | `audita_concurrency_{total_llm,proposal_llm,validation_llm}` | `audita_backends..concurrency` and optional `queue_capacity`; capacity is shared by roles using that backend. | | `audita_llm_{proposal,validation}_model` | Model in caller-owned PromptKit profile files, selected by `audita_llm_proposal_profile` and optional `audita_llm_validation_profile`. | | `audita_llm_{proposal,validation}_timeout` | Per-attempt `timeout_seconds` in profile files; `audita_llm_operation_timeout` separately bounds a logical call. | | `audita_llm_{proposal,validation}_max_retries` | `audita_llm_transient_retries` and `audita_llm_repair_attempts` are separate native budgets; old values do not map directly. | | Three `audita_normalization_*` gap/duration values | Same role variables, now numeric seconds rather than duration strings. | | `audita_diagnostics_retention` | Removed; use `audita_diagnostics_debug` and `audita_diagnostics_work_dir` for v2 debug behavior. Reporting uses `audita_reporting_enabled` and `audita_reporting_stdout_dir`. | Omitting `audita_llm_validation_profile` lets Audita inherit the proposal selection. `audita_llm_operation_timeout` is a Go duration string, while normalization times are numbers. See the tagged [v2 migration guide](https://gitea.maximumdirect.net/eric/audita/src/tag/v2.0.1/docs/migrations/v2.md) and [configuration reference](https://gitea.maximumdirect.net/eric/audita/src/tag/v2.0.1/docs/config.md) for exact validation and precedence rules. ## Example Inventory can supply the required choices for a local backend: ```yaml # host_vars/audita_host.yml (caller-owned) audita_backends: local: endpoint: http://127.0.0.1:11434/v1 credential: null audita_llm_proposal_profile: local-proposal ``` The caller also supplies `profiles/local-proposal.yaml` beside the managed configuration, or selects another directory with `audita_profiles_dir`: ```yaml # profiles/local-proposal.yaml (caller-owned) id: local-proposal backend: local model: replace-with-an-available-local-model timeout_seconds: 30 ``` Choose a model available at the selected endpoint. These profile files must exist before invoking Audita, but need not exist before applying the role. The role neither deploys them nor selects a ConfigKit overlay. ```yaml - hosts: audita_hosts roles: - role: ansible-role-audita ``` ## Validation The integration driver installs pinned collection dependencies, runs syntax checking and ansible-lint, and applies the role with local fixture backends and caller-owned profiles. It checks the temporary configuration with native `config validate` and the effective settings and profiles views, then requires clean repeated convergence. It also tests a caller-supplied Go executable with dependency management disabled after removing the managed binary. The fixture configuration and sibling `profiles/` directory live under the script's private temporary root, which cleanup removes. The role still mutates the local managed source checkout and binary; an existing system configuration is not replaced. These offline checks do not establish provider connectivity, runtime report behavior, or compatibility with the unchanged D&D suite: ```sh tests/integration ```