diff --git a/docs/roadmap/features/0002-audita-source-installation-and-configuration.md b/docs/roadmap/features/0002-audita-source-installation-and-configuration.md index ad9268e..7ef2c33 100644 --- a/docs/roadmap/features/0002-audita-source-installation-and-configuration.md +++ b/docs/roadmap/features/0002-audita-source-installation-and-configuration.md @@ -1,6 +1,6 @@ # Feature 0002: Audita Source Installation and Configuration -Status: ready +Status: done ## Summary @@ -232,9 +232,10 @@ glossary, transcript inputs, LLM endpoints, and secret environment variables; those are consumers' or later suite-level features, not installation dependencies. -The approved staged plan is maintained at `docs/roadmap/implementation.md`. -The D&D pipeline role can select concrete `audita_config` values after the -standalone interface is implemented and reviewed. +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 diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 8add066..1c6f231 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,298 +1,12 @@ -# Implementation Plan 0002: Install and Configure Audita +# Implementation Plan -Status: ready +Status: pending -Target executor: GPT-5.6-Terra +No implementation plan is currently active. Feature 0002 was completed in +`ansible-role-audita` through commit `3a8c21f`; its durable scope and rationale +remain in +[the Feature 0002 roadmap](features/0002-audita-source-installation-and-configuration.md), +and its review history remains in [the remediation record](remediation.md). -Feature roadmap: -[Feature 0002: Audita Source Installation and Configuration](features/0002-audita-source-installation-and-configuration.md) - -## Objective - -Implement the small, independently usable `rakestraw.audita` role defined by -Feature 0002. Install Audita from its pinned source release, build its -executable on the managed host, and manage its complete versioned -configuration mapping using the minimal module-driven Seriatim pattern. - -## Execution Rules - -- Execute Stage 1 and Stage 2 in numeric order. -- Before each stage, confirm its preconditions and the owning repository's - working-tree state. -- Modify only `ansible-role-audita`. Treat this workspace, `../audita`, - `rakestraw-ansible`, and every other repository as read-only. -- Preserve unrelated changes. Stop if the role repository is unexpectedly - dirty at a stage boundary. -- Follow `docs/conventions.md` and the Feature 0002 task flow. Trust the - idempotence and change detection of APT, Snap, `file`, `git`, and `copy`. -- Put the two rebuild conditions directly on the build task. Do not add an - intermediate fact, handler, or handler flush. -- Do not execute Audita from production role tasks. Executable and - configuration validation belong only in integration tests. -- Do not add fingerprints, checksums, sidecar state, manual Git cleanup, - staged replacement, compiler inspection, configuration preflight, or - out-of-band drift detection. -- Use fully qualified collection names and `argv` for command execution. -- Run each stage's validation before committing. Do not begin Stage 2 if Stage - 1 fails. -- Commit each completed stage with its specified plain-English message. Do not - push. -- Treat `/usr/local/src/audita`, `/usr/local/bin/audita`, and - `/usr/local/etc/audita/config.yml` as disposable role-managed test state. - -## Starting State and Preconditions - -- `ansible-role-audita` is clean on `main` at initial commit `793e6d3`, tracking - `origin/main` without divergence. -- This plan and the approved Feature 0002 roadmap are committed before - out-of-band execution begins. -- The local controller and managed host are Ubuntu 26.04 `amd64`, with - passwordless privilege escalation available. -- Workspace tooling is available in `../.venv/bin` from the role repository: - Ansible Core 2.21.3 and ansible-lint 26.8.0. -- `community.general` 13.3.0 and Go Snap channel `1.26/stable` are available. -- Upstream tag `v0.9.1` resolves to - `a84941d68168a1ed9ea7423b6477ae8218be73f9` and uses Go 1.24.0. -- The 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=`. -- Configuration schema version 1 accepts `{"version": 1}`. The command - `audita config validate --config ` emits `config is valid` for it. -- Buildable commit `46b7356a3b54a2771ce9a617e4fa3e8d13728cac` is available for the - checkout-change test. Do not use `v0.9.0` for that test because it resolves - to the same commit as `v0.9.1`. - -## Repository Scope - -- `ansible-role-audita` owns all implementation, interface, README, - dependency, and repository-local test changes. -- `ansible-workspace-dnd` owns the roadmap, plan, and aggregate status but - remains unchanged during out-of-band implementation. -- `../audita` is the authoritative read-only application contract. -- `rakestraw-ansible` is a read-only style and configuration-policy reference. -- Every other repository in `workspace.yml` remains unchanged. - -## Fixed Public Interface - -Implement exactly these defaults and matching argument specifications: - -| 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` | -| `audita_config` | `{"version": 1}` | - -The build details, ownership, and modes are fixed implementation details. -`audita_config` is the complete document, not an overlay onto hidden defaults. - -## Stage 1: Implement the Complete Minimal Role - -### Objective - -Create the role contract, concise production task flow, documentation, and -baseline test harness that install and configure Audita idempotently. - -### Preconditions - -- The starting revisions and upstream contracts remain unchanged. -- `ansible-role-audita` has no uncommitted changes. -- The default managed paths contain no data that must be preserved. - -### Owning Repository - -`ansible-role-audita` - -### Required Changes - -1. Add conventional role structure: defaults, metadata, argument - specifications, one task file, collection requirements, and focused local - tests. Retain the existing license and declare Ubuntu 26.04 support and - Ansible Core 2.18 or newer in Galaxy metadata. -2. Define exactly the nine variables above. Mirror their names and appropriate - scalar, boolean, and dictionary types in the argument specification; do not - duplicate Audita's configuration schema there. -3. Implement one readable `tasks/main.yml` with approximately this flow: - 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 source, binary, and configuration parent directories as - `root:root` mode `0755` with one `ansible.builtin.file` loop; - 5. check out `audita_version` with `ansible.builtin.git`, `force: true`, and - register its result; - 6. inspect `audita_binary_path` with `ansible.builtin.stat`; - 7. build directly to `audita_binary_path` when the checkout changed or the - binary is absent; - 8. converge recursive `root:root` source ownership and binary `root:root` - mode `0755` with one item-driven `ansible.builtin.file` loop; - 9. serialize `audita_config` as YAML at `audita_config_path` with - `ansible.builtin.copy`, `root:root` ownership, and mode `0644`. -4. Put the rebuild expression directly on the build command. Register only the - Git and binary results it needs. Invoke `audita_go_binary` with `argv`, the - fixed upstream build contract, output path, and source working directory. -5. Use task-level `become: true` for dependency installation and tasks that - manage root-owned state. Do not require play-level privilege escalation. -6. Pin `community.general` 13.3.0. Do not add handlers or abstractions for the - linear task flow. -7. Write a concise README covering the nine-variable interface, supported - platform, privilege and fact requirements, dependency opt-out, build and - configuration behavior, metadata, rebuild triggers, and test commands. -8. Add a baseline integration driver that installs the pinned collection into - a private temporary location, runs syntax checking and production-profile - ansible-lint, converges without play-level `become`, and verifies the - selected commit, recursive source ownership, binary metadata and execution, - configuration metadata, and exact native validation output - `config is valid`. -9. Require an immediate repeat role application to report `changed=0` and - `failed=0`. Keep paths repository-relative and temporary test artifacts out - of the repository. - -### Validation - -From `ansible-role-audita`, run: - -```sh -tests/integration -git diff --check -git status --short -``` - -Expected result: syntax and lint pass; source resolves to -`a84941d68168a1ed9ea7423b6477ae8218be73f9`; the executable runs and is -`root:root` mode `0755`; configuration is schema version 1 and `root:root` -mode `0644`; native validation reports `config is valid`; the immediate repeat -reports `changed=0` and `failed=0`; only intended Stage 1 changes remain. - -### Completion Criteria - -- Exactly nine defaults and matching argument specifications exist. -- Production flow matches the roadmap without unrequested probes, persisted - private state, or production validation commands. -- README, metadata, dependencies, tasks, and baseline tests agree. -- Baseline integration passes and proves default idempotence. -- No repository outside `ansible-role-audita` changed. - -### Commit - -Commit message: `Install and configure Audita` - -**Completion:** Complete (`ansible-role-audita` commit `47f1852`). - -## Stage 2: Add Focused Behavioral Coverage - -### Objective - -Prove the selected rebuild triggers, independent configuration convergence, -dependency opt-out, metadata repair, platform guard, and restored default -state without expanding production behavior. - -### Preconditions - -- Stage 1 is committed and the role repository is otherwise clean. -- Stage 1 integration passes. -- The default release and alternate buildable commit remain available. - -### Owning Repository - -`ansible-role-audita` - -### Required Changes - -1. Extend `tests/integration` using strict shell options, repository-relative - paths, a private temporary directory, and cleanup that restores `v0.9.1`. -2. Retain baseline convergence, verification, and clean repeat, then test: - - an absent binary causes one rebuild followed by an unchanged run; - - dependency opt-out with a caller-supplied Go executable causes one build - followed by an unchanged run; - - binary metadata drift is repaired by `file` without running the build, - followed by an unchanged run; - - changing `audita_config` updates only configuration state, passes native - validation, and reaches an unchanged repeat; - - selecting `46b7356a3b54a2771ce9a617e4fa3e8d13728cac` causes one checkout - rebuild followed by an unchanged run; - - restoring `v0.9.1` confirms its commit, causes one rebuild, and reaches a - final unchanged repeat; - - unsupported distribution, Ubuntu release, and architecture facts fail - before creating application state at isolated temporary paths. -3. Inspect captured task output only where needed to distinguish a build from - metadata or configuration convergence. Fail on hidden task failures or - unexpected changes in idempotence runs. -4. Limit test mutation to the three declared managed paths and the driver's - private temporary directory. -5. Add no tests for version interrogation, fingerprints, checksums, compiler - changes, source dirt, staged failures, malformed host state, production - configuration preflight, or other non-goals. -6. Update the README test section to describe the focused suite and its host - effects. - -### Validation - -From `ansible-role-audita`, run: - -```sh -tests/integration -git diff --check -git status --short -``` - -Then confirm the restored installation: - -```sh -sudo git -C /usr/local/src/audita rev-parse HEAD -sudo stat -c '%U:%G %a' /usr/local/bin/audita -sudo stat -c '%U:%G %a' /usr/local/etc/audita/config.yml -/usr/local/bin/audita config validate --config /usr/local/etc/audita/config.yml -``` - -Expected result: the focused suite and negative cases pass; the final repeat -reports `changed=0` and `failed=0`; source is restored to -`a84941d68168a1ed9ea7423b6477ae8218be73f9`; metadata is `root:root 755` for -the binary and `root:root 644` for configuration; validation reports -`config is valid`. - -### Completion Criteria - -- Every Feature 0002 acceptance criterion has direct static or test evidence. -- Coverage remains limited to the selected operational contract. -- Configuration-only convergence demonstrably does not rebuild Audita. -- README, interface, tasks, and tests agree. -- Default local state is restored and idempotent. -- No repository outside `ansible-role-audita` changed. - -### Commit - -Commit message: `Add focused Audita integration coverage` - -**Completion:** Complete (`ansible-role-audita` commit `d37f590`). - -## Final Validation and Handoff - -After Stage 2, run: - -```sh -tests/integration -git log --oneline -2 -git status --short --branch -cd .. -./scripts/status -``` - -Report the two commit hashes, final integration and repeat results, restored -source commit, file metadata, native configuration-validation result, any -deviation or remaining concern, and any complexity beyond this task flow with -the acceptance criterion that required it. - -Do not edit workspace planning files, mark Feature 0002 `done`, or push during -out-of-band execution. Completion requires subsequent review. - -## Progress Notes - -- Plan approved and ready for out-of-band execution on 2026-09-08. +Select and approve the next feature roadmap before replacing this notice with +a new staged implementation plan. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index e8a8b9b..f964411 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -1,137 +1,134 @@ -# Feature 0001 Remediation Review +# Feature 0002 Remediation Review Status: resolved -## Finding 1: Synchronize Implementation Progress Tracking +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. + +## 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 Severity: low -The two implementation stages are marked complete in -`docs/roadmap/implementation.md`, with commits `325a5c7` and `718030e`, but the -same document still has status `proposed` and says that no stages have been -executed. `docs/status.md` likewise still describes plan review as the current -focus and Feature 0001 as `ready` rather than reflecting the completed -implementation and pending review outcome. +`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. ### Required Remediation -- Update the implementation plan status and progress notes to agree with its - two recorded stage completions. -- Update workspace status to reflect that implementation is complete and the - feature is awaiting review acceptance. -- Preserve the prior remediation history in Git rather than carrying its - superseded contents in the active remediation document. +- 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. ### Validation -- The implementation plan's status, stage completion annotations, and progress - notes describe one consistent state. -- Workspace status names implementation review as the current activity and - uses the corresponding feature state. -- `git diff --check` passes. +- The README accurately describes package/Snap effects and managed filesystem + paths. +- The description agrees with `tests/integration` and the role defaults. -## Finding 2: Remove Production Version Interrogation +## Finding 3: Complete Binary-Type Verification -Severity: medium +Severity: low -`ansible-role-seriatim/tasks/main.yml` runs the installed binary before a build -to detect unexpected version output and again after a build to validate the -result. Neither operation is part of the required production convergence -contract. The first adds unrequested drift detection, while the second turns a -role task into a test of the role's own build implementation. +`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 -- Remove the pre-build `--version` command and its registered result. -- Rebuild only when the Git checkout changed or the binary is absent. -- Retain the binary `ansible.builtin.stat`, because its result is independently - needed to decide whether the imperative build must run. -- Remove the post-build `--version` command, its registered build result, and - the associated lint suppression. -- Continue verifying the installed version in repository-local integration - tests. +- Add an assertion for `audita_binary_metadata.stat.isreg` to the existing + binary metadata check. +- Do not add another probe or production task. ### Validation -- The role contains no production invocation of `seriatim --version`. -- The build task has exactly the two required triggers: changed checkout or - absent binary. -- Missing-binary and changed-checkout integration cases each cause a build and - then converge to an unchanged repeat. -- The integration suite verifies the built binary's exact version output. +- `tests/verify.yml` confirms regular-file type, ownership, mode, and + executability from its existing `stat` result. +- The integration suite passes. -## Finding 3: Complete the Declarative Dependency and Privilege Contract +## Finding 4: Synchronize Implementation Progress Tracking -Severity: medium +Severity: low -The build command hard-codes `/snap/bin/go`, which makes dependency opt-out -unnecessarily dependent on the Snap installation path. The Git package task -also refreshes the APT cache without a validity interval, and tasks that modify -system-owned paths or install system dependencies currently rely on privilege -escalation supplied by the calling play. +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 -- Add `seriatim_go_binary`, defaulting to `/snap/bin/go`, to the public defaults - and argument specification, and use it as the build command executable. -- Add `cache_valid_time: 3600` to the Git `ansible.builtin.apt` task. -- Set `become: true` directly on tasks that install dependencies or modify - root-owned application state. Do not add privilege escalation to the - platform assertion or binary inspection merely for uniformity. -- Update the README's variable table, dependency opt-out description, and - privilege behavior to match the implemented contract. +- 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 -- Dependency opt-out can use a caller-supplied Go executable. -- The APT task retains declarative cache management without refreshing a valid - cache. -- A play connecting as an ordinary sudo-capable user can apply the role without - play-level `become: true`. -- Defaults, argument specifications, tasks, and README agree on the seven - public variables. +- 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. -## Finding 4: Align the Feature Record and Focused Tests +## Review Validation Evidence -Severity: medium +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 active feature roadmap and completed implementation plan still require -wrong-version drift detection, post-build validation as a production task, a -hard-coded Go executable, and a six-variable interface. The integration driver -also contains a wrong-version rebuild case that would preserve the superseded -contract. - -### Required Remediation - -- Revise the feature roadmap to record the two rebuild triggers, the - seven-variable interface, and the approximately eight-task target flow. -- Annotate or revise the completed implementation plan so it does not remain an - apparently authoritative description of the superseded target. -- Remove the wrong-version rebuild case from the integration driver. -- Retain focused coverage of default convergence and idempotence, a missing - binary, binary metadata convergence without a build, a changed selected - version, platform rejection, and final version output. -- Update the README to describe only the revised behavior. - -### Validation - -- Workspace roadmap, implementation record, role implementation, README, and - integration suite describe the same final architecture. -- No active document claims that unexpected version output triggers a rebuild - or that the production role validates a newly built executable by running - it. -- `tests/integration`, `bash -n tests/integration`, and `git diff --check` pass. +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 resolved in `ansible-role-seriatim` commit `fb8dc41` on -2026-09-08. The role now uses an eight-task flow with two rebuild triggers, a -caller-selectable Go executable, bounded APT cache refreshes, and task-level -privilege escalation. Production tasks do not execute the installed -application; repository-local verification retains the version assertion. The -active roadmap, implementation record, status, README, interface, and focused -tests describe the same architecture. +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 completed successfully with `tests/integration`, -`bash -n tests/integration`, and `git diff --check` in both changed -repositories. +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. diff --git a/docs/status.md b/docs/status.md index 7466194..73a29e2 100644 --- a/docs/status.md +++ b/docs/status.md @@ -4,7 +4,7 @@ Last updated: 2026-09-08 Current milestone: MVP standalone application roles -Current focus: Execute the staged Feature 0002 Audita implementation plan. +Current focus: Select and define the next unit of work. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -13,12 +13,12 @@ Current focus: Execute the staged Feature 0002 Audita implementation plan. | M0-03 | Tracked MVP roadmap | workspace | done | `docs/roadmap/mvp.md` established | | M0-04 | Aggregate repository status | workspace | done | `scripts/status` created | | 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 | ready | Continue after the Audita role interface stabilizes | -| M1-02 | Standalone application roles | role repositories | in_progress | Implement Audita from the approved staged plan | +| M1-01 | Remaining MVP design decisions | workspace | ready | Select the next design topic or application role | +| M1-02 | Standalone application roles | role repositories | in_progress | Select the next standalone application role | | M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | proposed | Begin after standalone role interfaces stabilize | | M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism | | 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 | ready | Execute `docs/roadmap/implementation.md` in two ordered stages | +| F0002 | Install and configure Audita | ansible-role-audita | done | Implementation and remediation completed through `3a8c21f`; full integration suite passed | ## Updating This File