Record the Notarius implementation plan and review

This commit is contained in:
2026-09-08 23:45:08 +00:00
parent 5dc879ecd7
commit f87962ca13
4 changed files with 471 additions and 50 deletions

View File

@@ -1,6 +1,6 @@
# Feature 0003: Notarius Source Installation and Configuration
Status: proposed
Status: in_progress
## Summary
@@ -327,11 +327,10 @@ a configured pipeline, input artifacts, PromptKit assets and endpoints, and
secret environment variables; those belong to consumers or later suite-level
work.
After this roadmap is approved, replace the pending notice at
`docs/roadmap/implementation.md` with a numbered staged Notarius implementation
plan. The pipeline role can supply its D&D definitions through
`notarius_pipelines` and select the other field-specific values after the
standalone interface is implemented and reviewed.
The approved staged plan is maintained at
`docs/roadmap/implementation.md`. The pipeline role can supply its D&D
definitions through `notarius_pipelines` and select the other field-specific
values after the standalone interface is implemented and reviewed.
## Potential Future Hardening

View File

@@ -1,14 +1,392 @@
# Implementation Plan
# Implementation Plan 0003: Install and Configure Notarius
Status: pending
Status: in_progress
No implementation plan is currently active. The Feature 0002 configuration
amendment was completed in `ansible-role-audita` commits `e61f02f` and
`847c4c3`. Its durable scope remains in
[the Feature 0002 roadmap](features/0002-audita-source-installation-and-configuration.md),
and its review history remains in [the remediation record](remediation.md).
Target executor: GPT-5.6-Terra
Feature 0003 is the next proposed unit of work. Its durable roadmap has been
revised to follow the workspace configuration-interface conventions and awaits
review and approval before this notice is replaced with a staged
implementation plan.
Feature roadmap:
[Feature 0003: Notarius Source Installation and Configuration](features/0003-notarius-source-installation-and-configuration.md)
Active plan location: `docs/roadmap/implementation.md`
## Objective
Implement the small, independently usable `rakestraw.notarius` role defined
by Feature 0003. Install Notarius from its pinned source release, build its
executable on the managed host, and manage its versioned YAML configuration
through the approved nullable field-specific interface.
The feature roadmap remains authoritative for scope, rationale, target end
state, and acceptance criteria.
## 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-notarius`. Treat this workspace, `../notarius`,
`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 0003 simplest viable
implementation. Trust the idempotence, change detection, check-mode
behavior, and error handling of APT, Snap, `file`, `git`, and `template`.
- Inspect only binary existence because that result is independently required
to decide whether the arbitrary build command must run.
- Put the two rebuild conditions directly on the build task. Do not add an
intermediate fact, handler, or handler flush.
- Do not execute Notarius from production role tasks. Executable and
configuration validation belong only in repository-local integration tests.
- Do not add configuration assembly facts, preliminary configuration probes,
fingerprints, checksums, sidecar state, manual Git cleanup, staged
replacement, compiler inspection, version interrogation, or out-of-band
drift detection.
- Render configuration with one template task. Use `is not none` for optional
values, omit empty parent sections, and serialize strings and mappings with
filters rather than hand-written quoting.
- Accept the already composed `notarius_pipelines` mapping. Do not load
pipeline files or implement merging, precedence, or a second configuration
interface inside the role.
- Use fully qualified collection names and `argv` for command execution.
- Run every 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 `/usr/local/src/notarius`, `/usr/local/bin/notarius`, and
`/usr/local/etc/notarius/config.yml` as disposable role-managed test state.
## Starting State and Preconditions
- `ansible-role-notarius` is clean on `main` at initial commit `f8a3e11`,
tracking `origin/main` without divergence.
- This plan and the ready Feature 0003 roadmap are committed before
out-of-band execution begins.
- Feature 0001 established the accepted minimal source-build task flow, and
Feature 0002 established the nullable field-specific configuration and
conditional-template conventions.
- The local controller and managed host are Ubuntu 26.04 `amd64`, with
gathered facts and 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.6.0` resolves to
`77ae132e5609916da40dcd4fcc749c000a63cbac` and declares Go 1.25.5.
- The release build uses package `./cmd/notarius`, `CGO_ENABLED=0`,
`GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and linker flag
`-X gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override=<version>`.
- Configuration schema version 4 accepts a document containing only
`version: 4`. `notarius config validate --config <path>` validates a managed
file without requiring a selected pipeline.
- Tag `v0.5.0`, commit
`61436d7c186af57b06004e090ceac898e83cdb71`, remains available for the
checkout-change test.
## Repository Scope
- `ansible-role-notarius` owns all implementation, public interface, template,
README, dependency, metadata, and repository-local test changes.
- `ansible-workspace-dnd` owns the roadmap, plan, and aggregate status but
remains unchanged during out-of-band implementation.
- `../notarius` is the authoritative read-only build, CLI, and configuration
contract.
- `rakestraw-ansible` is a read-only style and deployment-policy reference.
- Every other repository in `workspace.yml` remains unchanged.
## Fixed Public Interface
Implement exactly the eight installation variables and fourteen
configuration variables in the Feature 0003 roadmap, with matching argument
specifications.
Use these argument-specification types:
- `str`: `notarius_version`, `notarius_repository_url`,
`notarius_go_snap_channel`, `notarius_promptkit_profile_dir`,
`notarius_promptkit_profile_file`,
`notarius_promptkit_local_backend_endpoint`,
`notarius_output_directory`, `notarius_cache_chunk_plans_mode`,
`notarius_cache_chunk_plans_directory`,
`notarius_cache_checkpoints_directory`, and `notarius_debug_directory`;
- `path`: `notarius_source_dir`, `notarius_binary_path`,
`notarius_go_binary`, and `notarius_config_path`;
- `bool`: `notarius_manage_build_dependencies` and
`notarius_cache_checkpoints_enabled`;
- `int`: `notarius_config_version`,
`notarius_promptkit_local_backend_concurrency_limit`,
`notarius_concurrency_total_llm`, and
`notarius_concurrency_stage_workers_extract`;
- `dict`: `notarius_pipelines`.
The eight installation variables and `notarius_config_version` are required
by the argument specification because they have concrete defaults. The other
thirteen configuration variables are optional and default to YAML null. Do not
add `notarius_config`, a template override, a raw-file variable, or hidden
configuration defaults.
## Stage 1: Implement the Complete Minimal Role
### Objective
Create the role contract, concise production task flow, conditional
configuration template, documentation, and baseline integration harness that
install and configure Notarius idempotently.
### Preconditions
- The starting revisions and upstream contracts remain unchanged.
- `ansible-role-notarius` has no uncommitted changes.
- The default managed paths contain no data that must be preserved.
### Owning Repository
`ansible-role-notarius`
### 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/config.yml.j2`,
`collections/requirements.yml`, `ansible.cfg`, and focused files under
`tests/`.
2. Declare role name `notarius`, namespace `rakestraw`, Ubuntu 26.04 support,
Ansible Core 2.18 or newer, an empty role dependency list, and the canonical
issue tracker. Pin `community.general` to version `13.3.0`.
3. Define exactly the twenty-two public variables from the roadmap. Keep all
thirteen optional configuration values explicitly null. Mirror the public
names and the types above in `meta/argument_specs.yml`; do not encode
Notarius's semantic validation rules in Ansible.
4. 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`, when dependency management is enabled;
3. install the classic Go Snap from `notarius_go_snap_channel` with
`community.general.snap` when dependency management is enabled;
4. create the source, binary, and configuration parent directories as
`root:root` mode `0755` with one `ansible.builtin.file` loop;
5. check out `notarius_version` with `ansible.builtin.git`, `force: true`,
and register the module result;
6. inspect only `notarius_binary_path` with `ansible.builtin.stat`;
7. build directly to `notarius_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. render `templates/config.yml.j2` to `notarius_config_path` as
`root:root` mode `0644` with one `ansible.builtin.template` task.
5. Invoke `notarius_go_binary` with `ansible.builtin.command` and `argv` from
`notarius_source_dir`. Use the fixed package, environment, trim-path flag,
linker symbol, selected version, and output path from the upstream build
contract. This build is the only production command; rely on the command
module's ordinary changed result when it runs.
6. Put `notarius_checkout.changed or not notarius_binary.stat.exists`
directly on the build task. Register only the Git and binary results needed
by that expression.
7. Use task-level `become: true` for dependency installation and every task
that manages root-owned state. Do not require play-level privilege
escalation.
8. Make the template always emit `version`. Emit these optional structures
only when their variables are non-null:
- `promptkit`, with direct profile-source fields and nested `local_backend`;
- `pipelines`, serialized from the caller-supplied mapping without
structural rewriting;
- `concurrency`, with nested `stage_workers.extract`;
- `output`;
- `cache`, with independently conditional `chunk_plans` and `checkpoints`;
- `debug`.
9. Preserve explicit false, zero, empty string, and empty mapping values by
testing presence with `is not none`. Serialize scalar values and the
pipeline mapping safely; do not build a configuration dictionary in a fact
or reproduce application defaults.
10. Replace the placeholder README with concise documentation covering the
supported platform, fact and privilege requirements, all public variables,
dependency opt-out, build behavior, rebuild triggers, null-as-omission
behavior, secrets boundary, native `pipelines` mapping, caller-side
`combine` example, and test effects.
11. 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:
- source commit `77ae132e5609916da40dcd4fcc749c000a63cbac` and recursive
`root:root` source ownership;
- binary `root:root` ownership, mode `0755`, and output
`notarius v0.6.0`;
- configuration `root:root` ownership, mode `0644`, and parsed content
exactly equal to `{"version": 4}`;
- native configuration validation succeeds; and
- an immediate repeat reports `changed=0` and `failed=0`.
12. Keep repository paths relative and temporary test artifacts outside the
repository. The integration driver's cleanup must restore the default
release and minimal configuration.
### Validation
From `ansible-role-notarius`, run:
```sh
tests/integration
git diff --check
git status --short
```
Expected result: syntax and lint pass; source resolves to
`77ae132e5609916da40dcd4fcc749c000a63cbac`; the executable reports
`notarius v0.6.0` and is `root:root` mode `0755`; the configuration parses as
exactly `{"version": 4}`, is `root:root` mode `0644`, and passes Notarius's
native validation; the immediate repeat reports `changed=0` and `failed=0`;
only intended Stage 1 changes remain.
### Completion Criteria
- Exactly eight installation defaults and fourteen configuration defaults
exist with matching argument specifications.
- Production tasks follow the nine-operation roadmap flow without unrequested
probes, persisted private state, handlers, or production validation.
- The template implements every public configuration field and the required
omission semantics without a parallel interface.
- README, metadata, dependencies, tasks, template, and baseline tests agree.
- Baseline integration passes and proves default convergence and idempotence.
- No repository outside `ansible-role-notarius` changed.
### Commit
Commit message: `Install and configure Notarius`
## Stage 2: Add Focused Behavioral Coverage
### Objective
Prove the selected rebuild triggers, independent configuration convergence,
inventory-side pipeline composition, falsey-value rendering, dependency
opt-out, metadata repair, platform guard, and restored default state without
expanding production behavior.
### Preconditions
- Stage 1 is committed and `ansible-role-notarius` is otherwise clean.
- Stage 1 integration passes.
- The default and alternate upstream revisions remain available.
### Owning Repository
`ansible-role-notarius`
### Required Changes
1. Extend `tests/integration` using strict shell options,
repository-relative paths, a private temporary directory, and cleanup that
restores `v0.6.0` and the minimal configuration.
2. Retain baseline convergence, verification, native configuration validation,
and clean repeat, then test:
- an absent binary causes one build followed by an unchanged run;
- dependency opt-out with a caller-supplied Go executable causes one build
through that executable followed by an unchanged run;
- binary metadata drift is repaired by `ansible.builtin.file` without
running the build, followed by an unchanged run;
- selecting `v0.5.0` causes one checkout rebuild, installs commit
`61436d7c186af57b06004e090ceac898e83cdb71`, and reaches an unchanged run;
- restoring `v0.6.0` causes one checkout rebuild, restores the default
commit, and reaches an unchanged run;
- unsupported distribution, Ubuntu release, and architecture facts fail
before creating application state at isolated temporary paths.
3. Add configuration verification that parses the YAML and compares native
structures rather than relying on whitespace or key order. Cover:
- the exact minimal document;
- a valid representative configuration spanning `promptkit`, `pipelines`,
`concurrency`, `output`, both cache subsections, and `debug`;
- each PromptKit profile-source field in separate valid scenarios because
Notarius makes them mutually exclusive;
- null omission and parent-section omission;
- explicit false, zero, empty string, and empty mapping rendering, without
requiring semantically invalid falsey examples to pass native validation;
- restoration to the exact minimal document.
4. Exercise caller-side pipeline composition directly. Define at least two
inventory mappings, each keyed by a distinct pipeline ID, assign
`notarius_pipelines` with the ordinary `combine` filter, and prove both
native definitions are rendered without role-side rewriting and pass
`notarius config validate`.
5. Prove each configuration-only transition changes the template task, skips
the build task, and reaches an unchanged immediate repeat. Do not add
production tasks to facilitate testing.
6. Inspect captured task output only where necessary to distinguish build,
metadata, and configuration convergence. Fail on hidden task failures or
unexpected changes in idempotence runs.
7. Limit test mutation to the three declared managed paths and the driver's
private temporary directory. Leave the default release and minimal
configuration installed after successful or failed test execution when
restoration is possible.
8. Add no coverage that implies production support for version interrogation,
fingerprints, checksums, compiler drift, source dirt, staged build failure,
malformed adversarial host state, role-side pipeline merging, or production
configuration preflight.
9. Update the README test section to describe the focused suite, pipeline
composition coverage, and managed-host effects.
### Validation
From `ansible-role-notarius`, run:
```sh
tests/integration
git diff --check
git status --short
```
Then confirm the restored installation:
```sh
sudo git -C /usr/local/src/notarius rev-parse HEAD
sudo stat -c '%U:%G %a' /usr/local/bin/notarius
sudo stat -c '%U:%G %a' /usr/local/etc/notarius/config.yml
/usr/local/bin/notarius --version
/usr/local/bin/notarius config validate --config /usr/local/etc/notarius/config.yml
```
Expected result: all focused and negative cases pass; every required repeat
reports `changed=0` and `failed=0`; source is restored to
`77ae132e5609916da40dcd4fcc749c000a63cbac`; metadata is `root:root 755` for
the binary and `root:root 644` for configuration; the executable reports
`notarius v0.6.0`; and native validation accepts the restored minimal file.
### Completion Criteria
- Every Feature 0003 acceptance criterion has direct static or integration
evidence.
- Configuration coverage proves nullable field rendering, empty-parent
omission, intentional falsey values, and native validity where applicable.
- Inventory-defined pipeline maps compose into the native field without any
role-side merge mechanism.
- Configuration-only convergence demonstrably does not rebuild Notarius.
- Coverage remains limited to the selected operational contract.
- README, interface, tasks, template, and tests agree.
- Default local state is restored and idempotent.
- No repository outside `ansible-role-notarius` changed.
### Commit
Commit message: `Add focused Notarius integration coverage`
## 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, executable version, 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 0003 `done`, or push during
out-of-band execution. Completion requires subsequent review.
## Progress Notes
- Stage 1 completed in `ansible-role-notarius` commit `287fc4a`.
- Stage 2 completed in `ansible-role-notarius` commit `733a194`.
- Post-implementation review passed the complete integration suite and opened
the findings in `docs/roadmap/remediation.md`.

View File

@@ -1,40 +1,84 @@
# Feature 0002A Remediation Review
# Feature 0003 Remediation Review
Status: resolved
Status: open
The field-specific Audita configuration implementation has the intended
architecture and its complete integration suite passes.
Reviewed implementation commits:
## Finding 2: Synchronize Amendment Progress Tracking
- `287fc4a Install and configure Notarius`
- `733a194 Add focused Notarius integration coverage`
The role's complete integration suite passes. The production architecture is
substantially complete and follows the selected nine-operation flow, but the
following issues should be corrected before Feature 0003 is marked done.
## Finding 1: Correct the Galaxy License Metadata
Severity: medium
`ansible-role-notarius/meta/main.yml` declares `license: BSD-3-Clause`, while
the repository's retained `LICENSE` file is CC0 1.0 Universal. Package metadata
must not misstate the terms under which the repository is distributed.
### Required Remediation
- Change the Galaxy license identifier to `CC0-1.0`, consistent with the
repository license and the other standalone roles that use the same license.
- Run metadata lint as part of the complete integration suite.
## Finding 2: Remove the Redundant Build Change Override
Severity: low
The configuration amendment was completed in `ansible-role-audita` commits
`e61f02f` and `847c4c3`, while the implementation plan and workspace status
still described it as awaiting execution.
The `Build Notarius` task sets `changed_when: true`. The
`ansible.builtin.command` module already reports a successful executed command
as changed, and the task's `when` expression already determines exactly when a
build occurs. The override adds no behavior and conflicts with the convention
to trust module behavior and require a reason for every additional directive.
### Resolution
### Required Remediation
- Recorded the completed amendment commits in the durable Feature 0002
roadmap.
- Marked Feature 0002 complete in workspace status.
- Replaced the completed fixed-location implementation plan with a pending-plan
notice for Feature 0003.
- Preserved Feature 0003 as the next proposed unit of work and identified its
configuration-interface revision as the next roadmap-review step.
- Remove `changed_when: true` from the production build task.
- Retain the existing rebuild expression unchanged:
`notarius_checkout.changed or not notarius_binary.stat.exists`.
- Run the complete integration suite to confirm that build runs still report
changed and immediate repeats remain clean.
## Review Conclusion
## Finding 3: Make the Dependency-Opt-Out Test Prove the Selected Go Binary
No code remediation was required. A proposed assertion that the configuration
was a regular file was rejected because a successful
`ansible.builtin.template` operation already establishes the specified file
state. Adding another assertion would re-prove the module's documented
postcondition and conflict with the workspace convention to trust Ansible's
abstraction boundary.
Severity: low
The review ran the complete `tests/integration` suite on Ubuntu 26.04 with
Ansible Core 2.21.3 and ansible-lint 26.8.0. It passed default minimal
rendering, representative nested rendering, explicit falsey values, native
configuration validation, configuration-only convergence, both rebuild
triggers, dependency opt-out, metadata repair, restored default state,
repeated convergence, and platform rejection. `git diff --check` also passed.
The integration suite sets `notarius_go_binary` to a symlink whose target is
`/snap/bin/go`. The test succeeds with the current implementation, but it would
also succeed if the build task ignored `notarius_go_binary` and hard-coded
`/snap/bin/go`. It therefore does not establish the acceptance criterion that
a caller-supplied Go executable is actually used.
### Required Remediation
- Replace the symlink with a small executable wrapper in the suite's private
temporary directory.
- Have the wrapper record its invocation and then delegate to `/snap/bin/go`.
- Assert that the invocation record was written during the dependency-opt-out
build, while retaining the existing clean-repeat assertion.
- Keep the wrapper and its record in the existing private temporary directory;
do not add production behavior.
## Review Evidence
The review ran from `ansible-role-notarius`:
```sh
tests/integration
git diff --check
```
The complete suite passed with Ansible Core 2.21.3 and ansible-lint 26.8.0. It
covered default convergence, the selected source commit, executable version,
native configuration validation, clean repeats, missing-binary and checkout
rebuilds, metadata repair without rebuilding, nullable field rendering,
PromptKit source alternatives, intentional falsey values, caller-side
pipeline-map composition, dependency opt-out, and platform rejection. The
suite restored Notarius `v0.6.0` and the minimal `version: 4` configuration.
No additional production tasks, configuration probes, runtime validation,
private state, or unrequested hardening were found.

View File

@@ -4,7 +4,7 @@ Last updated: 2026-09-08
Current milestone: MVP standalone application roles
Current focus: Review the revised Feature 0003 Notarius roadmap.
Current focus: Remediate the Feature 0003 post-implementation review findings.
| ID | Deliverable | Owner | State | Evidence or next step |
| --- | --- | --- | --- | --- |
@@ -13,13 +13,13 @@ Current focus: Review the revised Feature 0003 Notarius roadmap.
| 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 | Approve the revised Notarius configuration interface |
| M1-02 | Standalone application roles | role repositories | in_progress | Review and approve the revised Notarius feature roadmap |
| 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 | Resolve the Feature 0003 remediation findings |
| 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 | proposed | Review and approve the convention-aligned feature roadmap |
| F0003 | Install and configure Notarius | ansible-role-notarius | in_progress | Resolve the findings in `docs/roadmap/remediation.md` |
## Updating This File