Files
ansible-workspace-dnd/docs/roadmap/implementation.md

18 KiB

Implementation Plan 0003: Install and Configure Notarius

Status: in_progress

Target executor: GPT-5.6-Terra

Feature roadmap: Feature 0003: Notarius Source Installation and Configuration

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:

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:

tests/integration
git diff --check
git status --short

Then confirm the restored installation:

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:

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.