From 943152d1d5eca11e9c15cbb66cd95d60920ad286 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 8 Nov 2026 15:27:39 +0000 Subject: [PATCH] Resolve compound stage settings and explicit clearing rules --- docs/roadmap/configkit.md | 3 +- docs/roadmap/glossary-stages.md | 105 ++++++++++++++++++++++++-------- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md index c7e2cc5..c3c7371 100644 --- a/docs/roadmap/configkit.md +++ b/docs/roadmap/configkit.md @@ -122,8 +122,9 @@ file remain terminal. after library adoption. Each stage resolves independently with explicit-value presence and source provenance, and its module and validators receive consistent effective settings. Apply its [selected scope and fallback rules](glossary-stages.md#configuration-scope--resolved) + and [compound-value and clearing rules](glossary-stages.md#compound-values-and-explicit-clearing--resolved), and complete its required durable decision record. The glossary roadmap owns - the remaining clearing, precedence, path, and attribution decisions. This + the remaining precedence, path, and attribution decisions. This application scope model does not change native source composition or sibling-inheritance semantics. diff --git a/docs/roadmap/glossary-stages.md b/docs/roadmap/glossary-stages.md index 3c80e6b..50c38e7 100644 --- a/docs/roadmap/glossary-stages.md +++ b/docs/roadmap/glossary-stages.md @@ -100,29 +100,92 @@ per-stage rechunking would be a separate feature decision. ### Validation-Profile Fallback — Resolved -Combine explicit root and stage settings before deriving the validation-profile -fallback. If no validation profile was explicitly selected at either scope, use -the stage's effective proposal profile. An explicit root validation profile is -inherited unless the stage supplies its own validation profile. Preserve presence -so a value previously derived at the root is not mistaken for an explicit choice. +Combine root and stage selections, including explicit clearing, before deriving +the validation-profile fallback. If no validation selection remains, use the +stage's effective proposal profile. An explicit root validation profile is +inherited unless the stage replaces or clears it. Preserve presence so a value +previously derived at the root is not mistaken for an explicit choice. | Root selection | Stage selection | Effective validation profile | | --- | --- | --- | | Proposal A; validation omitted | Proposal B; validation omitted | B | | Proposal A; validation V | Proposal B; validation omitted | V | +| Proposal A; validation V | Proposal B; validation null | B | +| Proposal A; validation null | Proposal B; validation omitted | B | | Proposal A; validation V or omitted | Validation W | W | | Proposal A; validation omitted | Both omitted | A | -This rule does not invent a proposal selection when none is available. Explicit -empty/null values must retain their presence; their clearing or validation -semantics remain part of the open decision below. +Clearing the validation-profile selection does not disable validation. This rule +does not invent a proposal selection when none is available; a stage requiring +model execution must have a valid effective proposal profile. + +### Compound Values and Explicit Clearing — Resolved + +Resolve eligible settings field by field. A partial settings group overrides +only its supplied children; an empty mapping such as `llm: {}` contributes no +overrides. For example, a stage setting `llm.repair_attempts: 0` inherits the +root proposal profile and operation timeout while explicitly selecting no repairs. +Omitted fields inherit root settings and then receive any applicable fallback. +False, zero, and empty values remain explicit and follow per-field validation: +zero repairs is valid, while a zero operation timeout is invalid. + +| Explicit input | Meaning | +| --- | --- | +| `context.description: ""` | Clear the inherited description. | +| `glossary: null` | Clear the inherited glossary selection. | +| `glossary: ""` | Error: an empty string is not a valid glossary path. | +| `llm.validation_profile: null` | Clear the inherited selection, then use the effective proposal profile. | +| `llm.validation_profile: ""` | Error: use null to clear the selection deliberately. | +| Empty or null proposal profile | Invalid for a stage requiring model execution. | +| `llm: null` | Error: a settings group cannot be cleared as a whole. | + +Declare genuinely optional selectors nullable and preserve omission versus +explicit null through resolution. Null is not a universal reset operation; +settings groups are not nullable. A glossary-correction stage requires a glossary +and rejects a missing selection before execution. Other stages may operate +without glossary context where their operation supports it. The separate +protected-vocabulary decision below still governs its consumers. + +Lists replace the entire inherited list where list-valued stage settings apply; +`[]` explicitly selects an empty list. Do not append or union implicitly. +Preserve the owning library's semantics for library-owned resources and +identified collections. These scope rules do not introduce a custom merge +language or change ConfigKit source composition. + +### ConfigKit Support + +Use the selected ConfigKit v1.1.0 public lifecycle for this work. Its +[typed decoding contract](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/config.md#defaults-and-typed-decoding) +already preserves explicit false, zero, empty, and permitted null values, +recurses through partial mappings, and replaces ordinary sequences. Represent +nullable selectors with nullable typed fields and settings groups with +non-nullable structs. Use native decoding and validation rather than a parallel +parser or generic deep-merge implementation. + +Root-to-stage inheritance remains an Audita application rule: ConfigKit does not +automatically copy root fields into new sequence elements. Implement that rule +in `Definition.Resolve`, using `Resolution.IsExplicit` for presence and +`Resolution.EntryInfo` for the fixed pre-resolution metadata. Use +`configkit.Default` for omitted stage fields and record root-field dependencies. +Do not treat a derived root validation fallback as an explicit selection. + +An explicitly null validation selection needs deliberate application fallback: +`configkit.Default` correctly leaves explicit null alone. Apply the chosen +fallback and use `Resolution.RecordDerivedDefault` to record the assignment and +its effective proposal-profile dependency, retaining the original explicitness +and history. Follow the native +[recorded-resolution contract](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/config.md#recorded-application-resolution) +for all derived mutations, and use `Definition.Validate` for domain checks on +effective settings. Keep stage values independent when copying compound values. +No upstream feature request is presently needed for these rules. ### Durable Decision Record Completion requires recording the scope model in durable documentation before retiring this roadmap. Put the enduring classification rule and its rationale in the [architecture policy](../policy/architecture.md); keep the implemented -per-field scope and fallback contracts in the [configuration reference](../config.md). +per-field scope, compound-value, clearing, and fallback contracts in the +[configuration reference](../config.md). These configuration design decisions do not require an ADR. Reserve ADRs for major architectural decisions under the [documentation policy](../policy/documentation.md#architecture-decision-records). @@ -144,8 +207,8 @@ adopted configuration and CLI conventions and avoids adapting it twice. Keep the requirement visible during library design without expanding those migrations into feature implementation. -1. Apply the selected scope inventory and validation-profile fallback. Finalize - compound-value and clearing rules, path resolution, and CLI precedence. Incorporate +1. Apply the selected scope, compound-value, clearing, and validation-profile + fallback rules. Finalize path resolution and CLI precedence. Incorporate these into the version-3 schema rather than retain the old module-name list. 2. Resolve effective stage settings and carry them through stage execution, proposal generation, and validation. Carry selected glossary inputs through @@ -177,6 +240,12 @@ Exercise the selected request and validation overrides through stage consumers, including independent budgets without changing shared backend admission or the initial transcript sections. Cover all validation-profile fallback cases above and preserve the distinction between explicit and derived values in inspection. +Cover partial and empty settings groups, explicit zero and false, nullable +selectors, empty-list replacement, and invalid empty strings or group nulls. +Verify that clearing a validation selection follows the effective proposal +profile without disabling validation, and that clearing a required glossary +fails before execution. Check recorded dependencies and retained clear-input +history as well as effective values. Confirm that the durable policy, configuration contracts, and contributor guidance are in place before declaring this feature complete. @@ -184,20 +253,6 @@ guidance are in place before declaring this feature complete. The recommendations below are proposals, not selected contracts. -### Compound Values and Explicit Clearing - -**Recommendation:** resolve eligible settings by field, preserving explicit -presence and following the owning library's semantics for compound values. -Define omission, null, and empty behavior for each selected field; for glossary -input, distinguish inheriting a default from an intentional absence if that is -supported. Reuse native mechanisms rather than introducing a custom generic -deep-merge engine. This keeps partial stage settings useful and defaults visible. - -**Alternative:** replace an entire settings group whenever that group appears -on a stage. This gives simple replacement semantics, but changing one value may -require repeating unrelated global settings. The choice must respect upstream -contracts for any library-owned resource rather than redefine their merging. - ### CLI Overrides and Stage Precedence **Recommendation:** an ordinary setting flag changes the root default; explicit