diff --git a/docs/roadmap/features/0005-narratio-source-installation-and-configuration.md b/docs/roadmap/features/0005-narratio-source-installation-and-configuration.md index 2876594..ab57213 100644 --- a/docs/roadmap/features/0005-narratio-source-installation-and-configuration.md +++ b/docs/roadmap/features/0005-narratio-source-installation-and-configuration.md @@ -1,6 +1,6 @@ # Feature 0005: Narratio Source Installation and Configuration -Status: ready +Status: done ## Summary @@ -441,11 +441,15 @@ their configuration, campaign and session inputs, prompt content, and any selected object-storage or model credentials. Those remain caller responsibilities for this standalone feature. -After this feature, all five standalone application roles will have stable +With this feature complete, all five standalone application roles have stable public interfaces. The next unit can design the suite-level pipeline role, including dependency composition, compatible version selection, D&D pipeline policy, campaign and prompt deployment, secrets, and operator group membership. +The role was implemented in `ansible-role-narratio` commits `3be78d8` and +`0e8ad9f`, then finalized after independent review by remediation commit +`7feff47`. Its complete integration suite passes. + ## Potential Future Hardening - Build into a temporary path before replacing the installed executable. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 2fc9075..f97dfeb 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,416 +1,14 @@ -# Implementation Plan 0005: Install and Configure Narratio +# Implementation Plan -Status: ready +Status: pending -Target executor: GPT-5.6-Terra +No implementation plan is currently active. Feature 0005 was implemented in +`ansible-role-narratio` commits `3be78d8` and `0e8ad9f`, independently +reviewed, and finalized by remediation commit `7feff47`. -Feature roadmap: -[Feature 0005: Narratio Source Installation and Configuration](features/0005-narratio-source-installation-and-configuration.md) +Its durable scope and rationale remain in +[the Feature 0005 roadmap](features/0005-narratio-source-installation-and-configuration.md), +and its final review record remains in [the remediation record](remediation.md). -Active plan location: `docs/roadmap/implementation.md` - -## Objective - -Implement the independently usable `rakestraw.narratio` role defined by -Feature 0005. Install Narratio from its pinned source release, build its -executable on the managed host, create its application account and managed -filesystem roots, and render its native root pipeline configuration through -the approved field-specific interface. - -The feature roadmap remains authoritative for scope, rationale, target end -state, public variables, ownership, modes, and acceptance criteria. - -## Execution Rules - -- Execute Stage 1 and Stage 2 in numeric order. -- Immediately before each stage, read every document in that stage's Required - Policy Review, then confirm its preconditions and the owning repository's - working-tree state. -- Modify only `ansible-role-narratio`. Treat this workspace, `../narratio`, - `rakestraw-ansible`, and every other repository as read-only during - out-of-band implementation. -- Preserve unrelated changes. Stop if the role repository is unexpectedly - dirty at a stage boundary. -- Start from the feature roadmap's ten-step module-driven task flow. Trust - `apt`, Snap, `group`, `user`, `file`, `git`, and `template` to inspect and - converge the state they own. -- Inspect only whether the binary exists because that result is independently - required to decide whether the imperative build command must run. -- Put checkout change and binary absence directly on the build task. Do not - introduce another fact, handler, fingerprint, checksum, manifest, or - role-private state. -- Do not execute Narratio from production role tasks. Native version and - configuration verification belong only in the integration suite. -- Render configuration with one template task. Use `is not none`, omit empty - parent sections, preserve falsey non-null values, and serialize values with - filters rather than manual YAML quoting. -- Treat each roadmap-designated open-ended collection as one caller-supplied - native value. Do not define variables for caller-selected keys or implement - role-side loading, merging, or precedence. -- Require a WhisperX transcription URL. Do not invent a default endpoint or - weaken the upstream requirement. -- Exercise the role through public variables and native application outcomes. - Do not assert current default values, task traces, or state already - guaranteed by trusted modules. -- Use fully qualified collection names and `argv` for command execution. -- Run each stage's validation before committing it. Do not begin Stage 2 if - Stage 1 fails validation. -- Commit each completed stage with its specified plain-English message. Do not - push. -- Treat the currently absent managed source, binary, pipeline file, account, - and default directory roots as disposable integration state. Never delete - caller content under those roots during testing. Restore the baseline role - deployment through test cleanup. - -## Starting State and Preconditions - -- `ansible-role-narratio` is clean on `main` at - `b97a317f9ec9f15675e81c65af3f4a1ad8176886`, tracking `origin/main` without - divergence. -- This plan, the ready Feature 0005 roadmap, and the corresponding MVP/status - updates are committed before out-of-band execution begins. -- `/usr/local/src/narratio`, `/usr/local/bin/narratio`, - `/usr/local/etc/narratio/pipeline.yml`, `/var/lib/narratio`, - `/var/spool/narratio`, `/var/cache/narratio`, and - `/usr/local/share/narratio/campaigns` are absent before initial execution and - contain no user data that must be preserved. -- The local controller and managed-host proxy are Ubuntu 26.04 `x86_64`, with - gathered facts and passwordless task-level 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 lightweight tag `v2.0.0` resolves to - `ed4623bc415901134c765fe9cf06d59aa7891500` and declares Go 1.26.0. -- The native build uses package `./cmd/narratio`, `CGO_ENABLED=0`, - `GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and linker flags - `-s -w -X gitea.maximumdirect.net/eric/narratio/internal/buildinfo.Version=`. -- `narratio version` reports the embedded release, and - `narratio config validate --config ` validates the root pipeline - without loading a session or contacting WhisperX when the configuration - contains no credential references or campaign-driven artifact families. -- A pipeline requires an absolute HTTP or HTTPS WhisperX transcription URL. - All other values needed by a baseline pipeline are supplied by Narratio's - native defaults. - -## Repository Scope - -Repository that changes: - -- `ansible-role-narratio`: role implementation, public interface, account and - filesystem management, configuration template, metadata, dependency - declaration, README, and repository-local integration suite. - -Repositories that may be inspected but must remain unchanged: - -- `ansible-workspace-dnd`: authoritative roadmap, plan, policies, and status. -- `../narratio`: authoritative release, build, CLI, configuration, filesystem, - and integration contracts. -- `rakestraw-ansible`: historical style and deployment reference. -- Every other repository in `workspace.yml`. - -## Stage 1: Implement the Complete Minimal Role - -### Objective - -Create a complete standalone role that installs Narratio, creates its account -and managed directories, renders the baseline native pipeline, documents its -fixed public interface, and demonstrates native validity and clean repeated -convergence. - -### Required Policy Review - -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/ansible.md` -- `docs/testing.md` - -### Preconditions - -- The starting revisions and upstream contracts above remain unchanged. -- `ansible-role-narratio` has no uncommitted changes. -- The workspace planning commit containing this plan exists. -- The managed paths listed in Starting State remain free of data that must be - preserved. - -### Owning Repository - -`ansible-role-narratio` - -### Required Changes - -1. Retain the existing license and add the conventional role structure: - `defaults/main.yml`, `meta/main.yml`, `meta/argument_specs.yml`, - `tasks/main.yml`, `templates/pipeline.yml.j2`, - `collections/requirements.yml`, `ansible.cfg`, and focused files under - `tests/`. -2. Declare role name `narratio`, namespace `rakestraw`, author Eric Rakestraw, - license `CC0-1.0`, Ubuntu 26.04 support, Ansible Core 2.18 or newer, an empty - dependency list, and the repository's canonical issue tracker. Pin - `community.general` to `13.3.0`. -3. Define every variable in the Feature 0005 Fixed Public Interface exactly - once in role defaults, except the required - `narratio_whisperx_transcribe_url`, which has no invented default. Keep the - fourteen installation, account, and managed-filesystem defaults concrete. - Give every other optional pipeline field the YAML value `null`. -4. Mirror the complete public interface in `meta/argument_specs.yml`: - - mark `narratio_whisperx_transcribe_url` as a required string; - - use `path` for source, binary, Go executable, configuration, and managed - root paths; - - use `bool`, `int`, `float`, `str`, `list`, and `dict` according to each - native field's documented shape; - - require every concrete installation, account, and filesystem variable; - and - - leave nullable application settings optional. - Do not duplicate Narratio's semantic validation rules or deeply restate its - schemas for caller-supplied collections. -5. Implement one readable `tasks/main.yml` with 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`, and install the classic Go Snap from - `narratio_go_snap_channel` when dependency management is enabled; - 3. create `narratio_group` as a system group and `narratio_user` as a system - account in that group, with `narratio_workspace_root` as its home, - `create_home: false`, and `/usr/sbin/nologin` as its shell; - 4. create source, binary, configuration, runtime, and campaign parent/root - directories with the roadmap's ownership and modes using the smallest - clear number of `ansible.builtin.file` tasks and item loops; - 5. check out `narratio_version` with `ansible.builtin.git`, `force: true`, - and register its module result; - 6. inspect only `narratio_binary_path` with `ansible.builtin.stat`; - 7. build directly to `narratio_binary_path` when the checkout changed or - the binary is absent; - 8. converge recursive root ownership of the source tree and root ownership - plus mode `0755` on the binary with `ansible.builtin.file`; and - 9. render `templates/pipeline.yml.j2` to `narratio_config_path` as - `root:{{ narratio_group }}` mode `0640` with one - `ansible.builtin.template` task. -6. Invoke `narratio_go_binary` with `ansible.builtin.command` and `argv` from - `narratio_source_dir`. Supply `build`, `-trimpath`, the exact version linker - flags, the configured output path, and package `./cmd/narratio`. Set - `CGO_ENABLED=0`, `GOWORK=off`, and `GOTOOLCHAIN=local`. Mark the executed - mutation changed as required for an imperative command. -7. Put - `narratio_checkout.changed or not narratio_binary.stat.exists` directly on - the build task. Register only the Git and binary results needed by that - expression. -8. Use task-level `become: true` for dependency installation, account changes, - and tasks that manage privileged state. Do not require play-level privilege - escalation. -9. Make the template always render the required WhisperX URL and the four - role-owned filesystem roots. Conditionally emit all other fields from the - roadmap interface. Use `is not none` for every optional field, omit parent - sections with no selected descendants, preserve non-null falsey values, and - serialize strings and collections safely. Do not assemble a configuration - dictionary in facts. -10. Treat ConfigKit imports, publish outputs, Notarius references and outputs, - and Scriptorium artifacts and artifact families as complete native caller - values. Render them without structural rewriting. Do not load external - files or implement merge behavior. -11. Replace the placeholder README with concise documentation covering the - supported platform, fact and privilege requirements, every public variable, - required WhisperX URL, dependency opt-out, build triggers, application - account, managed directory ownership, configuration discovery path, - null-as-omission behavior, falsey values, caller-side composition of native - collections, credential-name boundary, externally managed imports and - profiles, suite-role boundary, and actual integration-test effects. -12. Add a baseline integration harness with one `tests/integration` entry - point. Use strict shell options, repository-relative paths, a private - temporary directory, pinned collection installation, syntax checking, - production-profile ansible-lint, and a best-effort cleanup trap that - reapplies the baseline role inputs and removes only its private temporary - directory. -13. In the baseline scenario, explicitly supply - `narratio_whisperx_transcribe_url` with a syntactically valid local test URL - that is never contacted. Converge without play-level escalation, run - `narratio config validate --config ` as `narratio_user`, and - immediately apply the same role again with aggregate `changed=0` and - `failed=0`. -14. Do not inspect account records, directory or file metadata, source commits, - package state, the template task result, or the complete rendered document - in tests. Those are postconditions of the modules that manage them, not - additional role-authored behavior. - -### Validation - -From `ansible-role-narratio`, run: - -```text -tests/integration -git diff --check -git status --short -``` - -Expected result: syntax and lint pass; baseline convergence succeeds; Narratio -validates the managed pipeline while running as its application account; the -immediate repeat reports `changed=0` and `failed=0`; cleanup leaves a usable -baseline deployment; and only intended Stage 1 files are modified. - -### Completion Criteria - -- The fixed public interface is present in defaults and matching argument - specifications, with only the deployment-specific WhisperX URL required. -- Production tasks follow the roadmap flow without additional probes, private - state, handlers, or production self-validation. -- Account and directory management implements the fixed ownership and access - boundary without selecting human operators. -- The template expresses every native root-pipeline field, omits null values - and empty optional parents, and preserves non-null falsey values. -- README, metadata, dependency declaration, task flow, template, and baseline - test description agree. -- Baseline native configuration validation and clean repeated convergence pass. -- No repository outside `ansible-role-narratio` changes. - -### Commit - -Commit intent: `Install and configure Narratio` - -## Stage 2: Add Focused Behavioral Coverage - -### Objective - -Add representative coverage for caller-selected release identity, -missing-binary recovery through caller-owned build tooling, and the complete -configuration interface's omission, falsey-value, and composition behavior. - -### Required Policy Review - -Before beginning this stage, read: - -- `AGENTS.md` -- `docs/orientation.md` -- `docs/conventions.md` -- `docs/ansible.md` -- `docs/testing.md` - -### Preconditions - -- Stage 1 is committed and `ansible-role-narratio` is otherwise clean. -- Stage 1's complete integration entry point passes. -- The baseline managed deployment can be restored by applying the role with - the test WhisperX URL and no optional application overrides. - -### Owning Repository - -`ansible-role-narratio` - -### Required Changes - -1. Retain the baseline native validation and immediate clean repeat. Extend the - existing driver rather than introducing another integration framework or - shared cross-role test helper. -2. Make the selected-version behavior explicit in one convergence by setting - `narratio_version: v2.0.0`, then execute `narratio version` and require - `narratio v2.0.0`. Do not assert or parse the role's default value and do not - inspect the Git checkout. -3. Add one recovery scenario that combines the two related public behaviors: - - create an executable temporary wrapper that records its invocation and - then delegates to `/snap/bin/go`; - - remove `/usr/local/bin/narratio`; - - apply the role with `narratio_manage_build_dependencies: false` and - `narratio_go_binary` set to that wrapper; - - confirm the supplied executable was used; - - exercise the installed Narratio with `version` and native configuration - validation; and - - immediately repeat with the same inputs and require aggregate - `changed=0` and `failed=0`. -4. Add one representative configuration scenario using a small valid subset - spanning direct and nested fields. Include selected zero, false, empty - string, empty list, or empty mapping values where Narratio accepts them, - selected null fields that must remain absent, and at least one open-ended - collection assembled from independently defined inventory/play variables - before assignment. -5. Keep the representative pipeline independent of external services, - credentials, imported files, profile overlays, sessions, and campaigns. - Choose collection entries valid under the upstream `v2.0.0` contract and - avoid artifact families, which require campaign-owned party input during - native validation. -6. Parse the rendered authoring YAML and assert only representative - role-authored mappings: selected fields are present at their correct native - paths, selected null fields and their otherwise-empty parents are absent, - intentional falsey values survive, and the composed collection retains its - caller-supplied entries. Place any decoded-document expression directly in - the assertion task's `vars`; do not add a separate assembly or verification - fact. -7. Run `narratio config validate --config ` as `narratio_user` - for native acceptance without a network request. Immediately repeat the - representative convergence with identical public inputs and require - aggregate `changed=0` and `failed=0`. -8. Keep the cleanup trap responsible for restoring the baseline deployment on - success or failure when possible. Test mutation is limited to the declared - role-managed paths and the driver's private temporary directory; do not - delete or replace content below a runtime or campaign root. -9. Do not add a second release, task-name grep, change-count requirement for - mutating runs, metadata-repair scenario, unsupported-platform matrix, - service invocation, full configuration snapshot, or exhaustive case for - every variable. -10. Update the README validation section so it describes only the implemented - static checks, baseline native validation and clean repeat, - selected-version assertion, combined recovery case, and representative - configuration case. - -### Validation - -From `ansible-role-narratio`, run: - -```text -tests/integration -git diff --check -git status --short -``` - -Expected result: static validation and all behavioral paths pass; the selected -release reports `v2.0.0`; the supplied Go wrapper is observed during -missing-binary recovery; Narratio natively accepts both baseline and -representative managed pipelines as its application account; the specified -repeat runs report `changed=0` and `failed=0`; cleanup restores a usable -baseline deployment; and only intended Stage 2 test and documentation changes -remain. - -### Completion Criteria - -- One explicitly selected-version case proves caller-controlled source release - installation through Narratio's native version output. -- One recovery scenario proves both missing-binary rebuilding and use of the - caller-selected Go executable, followed by clean convergence. -- One representative configuration proves selected field mapping, null - omission, falsey-value preservation, caller-side collection composition, - native acceptance, application-account access, and clean convergence. -- No test snapshots mutable defaults, inspects task traces, or rechecks - postconditions owned by trusted modules. -- The complete integration entry point passes and its README description is - accurate. -- No repository outside `ansible-role-narratio` changes. - -### Commit - -Commit intent: `Add focused Narratio integration coverage` - -## Final Validation and Handoff - -After Stage 2, from `ansible-role-narratio`, run: - -```text -tests/integration -git log --oneline -2 -git status --short --branch -cd .. -./scripts/status -``` - -Report both role commit hashes, static and behavioral validation results, -clean-repeat evidence, the restored baseline deployment, any deviation or -remaining concern, and any complexity beyond the planned task flow with the -acceptance criterion that required it. - -Do not edit workspace planning files, mark Feature 0005 `done`, or push during -out-of-band implementation. Completion requires subsequent independent review. - -## Progress Notes - -- [x] Stage 1 complete — `ansible-role-narratio` commit `3be78d8`; full - `tests/integration` passed. No deviations. -- [x] Stage 2 complete — `ansible-role-narratio` commit `0e8ad9f`; full - `tests/integration` passed. No deviations. +Select and approve the next unit of work before replacing this notice with a +new staged implementation plan. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index 217bb69..255bd8c 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -1,63 +1,71 @@ -# Feature 0004 Remediation Review +# Feature 0005 Remediation Review Status: resolved Reviewed implementation commits: -- `90d7f45 Install and configure Scriptorium` -- `5944eac Add focused Scriptorium integration coverage` +- `3be78d8 Install and configure Narratio` +- `0e8ad9f Add focused Narratio integration coverage` Remediation commit: -- `8f47aa8 Clean up Scriptorium review findings` +- `7feff47 Clean up Narratio review findings` -The production role implements the targeted architecture. The complete -integration suite, independent syntax and lint checks, Bash syntax validation, -native default-configuration inspection, and clean-repeat scenarios pass. No -production behavior or architectural gap requires remediation. +The production role implements the targeted architecture, and the complete +integration suite passes. The findings were limited to residual documentation +and test-quality issues; no production task, template, default, argument +specification, metadata, or dependency required a change. ## Finding 1: Remove the Retained Placeholder README Sentence Severity: low -`ansible-role-scriptorium/README.md` ends with the original placeholder text, -“Ansible role to install the Scriptorium application.” The rewritten README -already provides a complete description, so this trailing sentence is an -accidental duplicate left by the initial replacement. +`ansible-role-narratio/README.md` ended with the original placeholder sentence, +“Ansible role to install the Narratio D&D transcript and session report +generation suite.” The rewritten README already provided the complete role +description, so this was accidental residue from the initial repository. ### Resolution -The trailing placeholder sentence was deleted without changing the completed -role or validation documentation. +The retained placeholder sentence was removed without changing the substantive +role documentation. -## Finding 2: Simplify Representative Test Data Flow +## Finding 2: Make the Composition Test Non-vacuous Severity: low -`ansible-role-scriptorium/tests/integration` repeats the same long -representative extra-vars document for the initial convergence and its clean -repeat. This makes the requirement that both runs use identical inputs harder -to see and creates two values that can drift independently. - -`ansible-role-scriptorium/tests/verify-config.yml` also persists the parsed -configuration with a separate `ansible.builtin.set_fact` task even though the -value is needed only by the following assertion. This adds a task and mutable -test state without adding behavior. +`ansible-role-narratio/tests/representative.yml` claimed to exercise +caller-side composition, but both secondary fragments were empty. The verifier +consequently proved only that one original entry survived serialization. ### Resolution -The shell driver now defines the representative extra-variable arguments once -and passes the same array to both convergence calls. The verifier parses the -slurped configuration through a variable local to its assertion task, and the -standalone `set_fact` task was removed. Existing assertions, native inspection, -and clean-repeat coverage remain unchanged. +The Scriptorium artifact map now combines two nonempty caller-defined +fragments, and the verifier checks one entry from each. Publish outputs use one +direct value so the suite retains only one representative composition case. +Native validation and the immediate clean repeat remain in place. + +## Finding 3: Use Ansible Privilege Escalation Directly in Verifiers + +Severity: low + +Both configuration verifiers escalated to root and then executed +`/usr/bin/sudo -u narratio` inside `ansible.builtin.command`, creating a +redundant second privilege transition. + +### Resolution + +Both verifier tasks now use `become_user: narratio` and invoke Narratio +directly. The integration driver enables pipelining and uses `/tmp` for +Ansible's transient module area, avoiding the local controller's otherwise +unmet temporary-file ACL requirement without adding a nested sudo command. ## Final Validation `bash -n tests/integration`, the complete `tests/integration` suite, and -`git diff --check` passed after remediation. Production-profile lint and -Ansible syntax checks passed within the integration entry point. Default, -missing-binary recovery, and representative-configuration scenarios all -passed their native inspections and immediate clean repeats, and cleanup -restored the usable `{}` default configuration. No unresolved Feature 0004 -findings remain. +`git diff --check` passed after remediation. Syntax checking and +production-profile lint passed within the integration entry point. Baseline, +missing-binary recovery, and representative-configuration scenarios passed +their native Narratio checks as the application account, every required +immediate repeat reported `changed=0` and `failed=0`, and cleanup restored the +usable baseline deployment. No unresolved Feature 0005 findings remain. diff --git a/docs/status.md b/docs/status.md index 22907b0..c992aed 100644 --- a/docs/status.md +++ b/docs/status.md @@ -2,9 +2,9 @@ Last updated: 2026-09-09 -Current milestone: MVP standalone application roles +Current milestone: Select the next MVP unit of work -Current focus: Implement Feature 0005 for the standalone Narratio role. +Current focus: Select the next unit of work. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -14,14 +14,14 @@ Current focus: Implement Feature 0005 for the standalone Narratio role. | 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 | done | Feature 0003 roadmap fixes the Notarius configuration interface | -| M1-02 | Standalone application roles | role repositories | in_progress | Implement and review Feature 0005 | +| M1-02 | Standalone application roles | role repositories | done | All five standalone roles implemented and independently reviewed | | 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 | done | Field-specific configuration completed in `e61f02f` and `847c4c3`; full suite passed | | F0003 | Install and configure Notarius | ansible-role-notarius | done | Implemented and validated through remediation commit `eb4f511` | | F0004 | Install and configure Scriptorium | ansible-role-scriptorium | done | Implemented and validated through remediation commit `8f47aa8` | -| F0005 | Install and configure Narratio | ansible-role-narratio | ready | Execute `docs/roadmap/implementation.md` | +| F0005 | Install and configure Narratio | ansible-role-narratio | done | Implemented and validated through remediation commit `7feff47` | | A0001 | Audit completed standalone-role test suites | workspace and standalone roles | done | Findings recorded in `docs/roadmap/test-suite-audit-findings.md` | | R0001 | Simplify completed standalone-role test suites | workspace and standalone roles | done | Role commits `e08c63c`, `d2d0b9d`, and `cfecf37` passed implementation and independent review |