From 5dc879ecd72bceb5e498eebec6e7aece422508fe Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Tue, 8 Sep 2026 17:55:46 +0000 Subject: [PATCH] Define the Notarius configuration interface --- ...s-source-installation-and-configuration.md | 155 ++++++++++++++---- docs/roadmap/implementation.md | 6 +- docs/status.md | 8 +- 3 files changed, 131 insertions(+), 38 deletions(-) diff --git a/docs/roadmap/features/0003-notarius-source-installation-and-configuration.md b/docs/roadmap/features/0003-notarius-source-installation-and-configuration.md index dd65cac..13877e5 100644 --- a/docs/roadmap/features/0003-notarius-source-installation-and-configuration.md +++ b/docs/roadmap/features/0003-notarius-source-installation-and-configuration.md @@ -2,11 +2,6 @@ Status: proposed -Planning note: the installation decisions are ready for review, but the -configuration interface was drafted before the nullable field-specific -convention was adopted. Revise that interface to follow -`docs/conventions.md` before approving this roadmap. - ## Summary Provide a small, independently usable `rakestraw.notarius` role that installs @@ -44,6 +39,9 @@ and build contract differing. `/usr/local/etc/notarius/config.yml`, owned by `root:root` with mode `0644`. - Default the managed configuration to the minimal valid mapping `{"version": 4}`, allowing Notarius's built-in defaults to govern behavior. +- Expose native configuration through field-specific role variables. Give the + required schema version a concrete default and make every optional setting + nullable so omitted settings remain owned by Notarius. - Keep defaults, argument specifications, README, metadata, dependency declaration, and focused local tests consistent with this contract. @@ -51,7 +49,12 @@ and build contract differing. - A D&D pipeline definition, module selection, LLM profile, concurrency policy, output paths, cache policy, or other suite-specific configuration. -- A separate Ansible variable for every Notarius configuration field. +- A raw mapping for the complete configuration document, a template override, + or competing configuration interfaces. +- Role defaults copied from Notarius merely to reproduce the application's + built-in defaults in YAML. +- Decomposing the open-ended `pipelines` map into role variables for every + possible pipeline, step, lane, binding, validator, option, or reference. - API keys, secret values, environment files, or another secret-delivery mechanism. - PromptKit profiles or other externally maintained prompt content. @@ -76,11 +79,21 @@ installs or confirms Git and Go, checks out Notarius `v0.6.0` at stated root ownership and permissions, and the configuration contains `version: 4`. +When a caller sets an optional configuration variable, the corresponding +native field appears in the correct YAML section. Null fields are absent, as +are parent sections with no selected descendants. Explicit false, zero, empty +string, empty collection, and other non-null values are rendered and left to +Notarius's native validation. `notarius_pipelines` represents the native +open-ended `pipelines` field as one mapping rather than attempting to mirror +its extensible internal schema in Ansible variables. Callers may define +pipeline-map fragments in separate inventory files and compose them into the +final value with ordinary Ansible/Jinja expressions. + An immediate second application reports no changes. A changed Git checkout or missing binary causes one build; configuration changes converge independently -through the ordinary file-management module. Repository-local tests execute -the installed CLI to verify the selected build and validate the managed -configuration. +through the ordinary `ansible.builtin.template` operation. Repository-local +tests execute the installed CLI to verify the selected build and validate the +managed configuration. ## Repository Ownership @@ -91,7 +104,7 @@ configuration. contracts. - `rakestraw-ansible` is a read-only style and deployment-policy reference. - `ansible-role-dnd-pipeline` will later own the D&D-specific configuration - supplied through the standalone role's mapping interface. + supplied through the standalone role's field-specific variables. - `ansible-workspace-dnd` owns this roadmap, the eventual staged plan, and aggregate status. - All other repositories remain unchanged. @@ -110,13 +123,28 @@ configuration. - Notarius configuration schema version 4 explicitly supports a document containing only `version: 4`, with omitted values supplied by application defaults. +- `notarius_config_version` names the schema version so `notarius_version` + remains unambiguously the selected application release. +- Optional configuration variables are declared with YAML null defaults. + Template conditions use `is not none`, and parent mappings are emitted only + when at least one descendant is non-null. +- The native `pipelines` field is exposed as the nullable + `notarius_pipelines` mapping. It is one field-specific variable, not a raw + mapping for the complete document; the role serializes its value without + defining a parallel schema for pipeline internals. +- Pipeline composition belongs to the caller. For example, inventory may + define `notarius_pipeline_group_one` and `notarius_pipeline_group_two` as + mappings and set `notarius_pipelines` to + `{{ notarius_pipeline_group_one | combine(notarius_pipeline_group_two) }}`. + The role accepts and renders the resulting mapping without its own merge or + precedence mechanism. +- Strings and mappings are serialized with Ansible or Jinja filters rather + than hand-written YAML quoting. - `notarius config validate --config ` validates a managed configuration without requiring a pipeline selection. It is used only by tests. - Configuration discovery uses an explicit CLI path, then `NOTARIUS_CONFIG`, then `/usr/local/etc/notarius/config.yml`; the role manages the installed default path. -- Configuration is exposed as one complete mapping. The suite role will later - supply the full D&D pipeline and operating policy through that boundary. - Configuration contains no secrets by default. Consumers arrange any secret environment variables outside this feature. - Tasks that install dependencies or manage root-owned state use task-level @@ -130,6 +158,8 @@ configuration. ## Fixed Public Interface +Provide these installation variables: + | Variable | Default | Purpose | | --- | --- | --- | | `notarius_version` | `v0.6.0` | Git revision and release value supplied to the build | @@ -140,12 +170,37 @@ configuration. | `notarius_go_snap_channel` | `1.26/stable` | Go Snap channel | | `notarius_go_binary` | `/snap/bin/go` | Go executable used for the build | | `notarius_config_path` | `/usr/local/etc/notarius/config.yml` | Managed configuration file | -| `notarius_config` | `{"version": 4}` | Complete versioned configuration mapping | + +Provide these configuration variables: + +| Variable | Default | Native field | +| --- | --- | --- | +| `notarius_config_version` | `4` | `version` | +| `notarius_promptkit_profile_dir` | `null` | `promptkit.profile_dir` | +| `notarius_promptkit_profile_file` | `null` | `promptkit.profile_file` | +| `notarius_promptkit_local_backend_endpoint` | `null` | `promptkit.local_backend.endpoint` | +| `notarius_promptkit_local_backend_concurrency_limit` | `null` | `promptkit.local_backend.concurrency_limit` | +| `notarius_pipelines` | `null` | `pipelines` | +| `notarius_concurrency_total_llm` | `null` | `concurrency.total_llm` | +| `notarius_concurrency_stage_workers_extract` | `null` | `concurrency.stage_workers.extract` | +| `notarius_output_directory` | `null` | `output.directory` | +| `notarius_cache_chunk_plans_mode` | `null` | `cache.chunk_plans.mode` | +| `notarius_cache_chunk_plans_directory` | `null` | `cache.chunk_plans.directory` | +| `notarius_cache_checkpoints_enabled` | `null` | `cache.checkpoints.enabled` | +| `notarius_cache_checkpoints_directory` | `null` | `cache.checkpoints.directory` | +| `notarius_debug_directory` | `null` | `debug.directory` | The package, build flags, linker symbol, environment values, file ownership, and modes are fixed implementation details. The selected version is both the Git revision and the value supplied to the upstream linker flag. +Argument specifications type each value according to its native shape. The +role does not reproduce semantic relationships such as the mutual exclusion +of PromptKit profile sources or the requirement for a local-backend endpoint; +Notarius owns those constraints. The `notarius_pipelines` value is a mapping +whose nested structure is governed by Notarius's versioned configuration +contract. + ## Simplest Viable Implementation The expected implementation is approximately nine ordinary tasks in one @@ -166,14 +221,15 @@ readable task file: changed or the binary is absent. 8. Converge recursive source ownership and binary ownership and mode with one item-driven `ansible.builtin.file` loop. -9. Serialize `notarius_config` as YAML and manage `notarius_config_path` with - `ansible.builtin.copy`. +9. Render the field-specific configuration with one + `ansible.builtin.template` task, conditionally emitting optional fields and + parent sections at `notarius_config_path`. Apply task-level privilege escalation only where required. Use `argv` for the build command and put its two conditions directly on the build task. Do not add a rebuild fact, handler, handler flush, executable discovery, compiler or -version interrogation, configuration preflight, or post-operation validation -to production tasks. +version interrogation, configuration assembly facts, preliminary +configuration probes, or post-operation validation to production tasks. ## Rationale and Alternatives @@ -182,12 +238,33 @@ Audita roles: declarative dependency and checkout management surrounding one imperative build command. Binary existence is the only state probe Ansible needs because it controls whether that command must run. -A single configuration mapping preserves Notarius's strict native schema and -avoids duplicating a large, evolving configuration surface as role variables. -The minimal valid document keeps the standalone role useful without embedding -D&D policy. The suite role can later provide the maintained pipeline, -PromptKit profile selection, concurrency, state paths, and other integrated -values as one complete override. +Field-specific variables are the ordinary ergonomic interface for inventory +and composing roles. Nullable defaults expose and type that interface without +freezing Notarius's built-in defaults into Ansible. Conditional rendering +preserves the distinction between omission and an intentionally falsey value. + +The pipeline definitions are the deliberate exception to leaf-level +variables. `pipelines` is itself an open-ended map whose nested keys depend on +registered modules and evolve with the application's native schema. Exposing +that native field as one nullable mapping keeps the interface practical while +still avoiding a raw complete-document mapping or merge semantics. The suite +role can later supply its maintained D&D pipeline through +`notarius_pipelines` and supply operating policy through the other variables. + +This boundary also supports modular inventory. A consumer can keep one or +more pipeline mappings in separate `host_vars`, `group_vars`, or included +variable files and combine them when assigning `notarius_pipelines`. Because +the native value is a mapping keyed by pipeline ID, dictionary composition +uses Ansible's `combine` filter; list concatenation with `+` applies only to +list-valued data. The role receives the already composed native mapping and +does not need custom loading, merging, or precedence behavior. + +Leaving optional variables undefined would produce the same minimal file but +would weaken interface documentation and argument validation. Section-level +dictionaries would be less ergonomic for ordinary inventory values. A raw +complete configuration mapping would force consumers to replace the required +version and unrelated sections together and would conflict with the workspace +convention of one field-specific interface. Managing `/usr/local/etc/notarius/config.yml` follows the application's own configuration discovery contract and aligns locally installed software with @@ -204,9 +281,14 @@ its configuration. `/usr/local/bin/notarius` as a regular file owned by `root:root` with mode `0755`. - The managed source checkout is recursively owned by `root:root`. -- The default schema-version 4 configuration is installed at - `/usr/local/etc/notarius/config.yml` as a regular file owned by `root:root` - with mode `0644`. +- The default configuration contains exactly `version: 4` and is installed at + `/usr/local/etc/notarius/config.yml`, owned by `root:root` with mode `0644`. +- Every optional field is absent when its variable is null, including parent + sections with no selected descendants. +- A representative configuration exercises every top-level section and + validates successfully with `notarius config validate`. +- Explicit falsey non-null values, including zero and false, are rendered + rather than omitted; semantic validity remains Notarius's responsibility. - Repository-local tests receive `notarius v0.6.0` from the installed CLI and successfully validate the managed configuration. - An immediate second role run reports no changes. @@ -217,15 +299,23 @@ its configuration. - Dependency opt-out accepts a caller-supplied `notarius_go_binary`. - A play connecting as an ordinary sudo-capable user can apply the role without play-level privilege escalation. -- Defaults and argument specifications contain exactly the nine variables in - the Fixed Public Interface. +- Defaults and argument specifications contain exactly the eight installation + variables and fourteen configuration variables in the Fixed Public + Interface. +- No raw `notarius_config` compatibility variable, template override, or + parallel configuration interface exists. +- Independently defined inventory mappings can be combined into + `notarius_pipelines`, and the resulting pipeline IDs and definitions are + rendered without structural rewriting by the role. - Production tasks contain no CLI validation, fingerprints, checksums, sidecar state, manual Git reset or clean commands, or probes before state already - managed by APT, Snap, `file`, `git`, or `copy`. + managed by APT, Snap, `file`, `git`, or `template`. - Syntax checking, production-profile ansible-lint, focused local convergence, CLI verification, configuration validation, and clean repeated runs pass. -- Role documentation describes actual behavior, dependency opt-out, the - complete configuration mapping, privilege use, and integration-test effects. +- Role documentation describes actual behavior, dependency opt-out, every + public configuration variable, null-as-omission behavior, the native + `pipelines` boundary and caller-side composition example, privilege use, and + integration-test effects. - No repository other than `ansible-role-notarius` and the workspace control repository is modified. @@ -239,7 +329,8 @@ 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 select concrete `notarius_config` values after the +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. ## Potential Future Hardening diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index d8424b5..69a9394 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -8,5 +8,7 @@ amendment was completed in `ansible-role-audita` commits `e61f02f` and [the Feature 0002 roadmap](features/0002-audita-source-installation-and-configuration.md), and its review history remains in [the remediation record](remediation.md). -Feature 0003 is the next proposed unit of work. Review and approve its durable -roadmap before replacing this notice with a staged implementation plan. +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. diff --git a/docs/status.md b/docs/status.md index 34e36c8..250904d 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: Resume review of the proposed Feature 0003 Notarius roadmap. +Current focus: Review the revised Feature 0003 Notarius roadmap. | ID | Deliverable | Owner | State | Evidence or next step | | --- | --- | --- | --- | --- | @@ -13,13 +13,13 @@ Current focus: Resume review of the proposed 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 | Resolve the Notarius configuration interface during roadmap review | -| M1-02 | Standalone application roles | role repositories | in_progress | Review and approve the Notarius feature roadmap | +| 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-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 | Align its configuration interface with `docs/conventions.md`, then approve the roadmap | +| F0003 | Install and configure Notarius | ansible-role-notarius | proposed | Review and approve the convention-aligned feature roadmap | ## Updating This File