diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md index 7ae4119..136ff47 100644 --- a/docs/roadmap/configkit.md +++ b/docs/roadmap/configkit.md @@ -137,11 +137,13 @@ file remain terminal. Register its [collection-scoped entry IDs](glossary-stages.md#entry-identity--resolved) through native sequence identity registration. Apply its [extensible entry content contract](glossary-stages.md#entry-content-fields--resolved) - using native typed fields and inline extension data. + using native typed fields and inline extension data. Honor its + [list-input and handoff contract](glossary-stages.md#list-inputs-and-configuration-handoff--resolved): + complete configuration resolution through ConfigKit before handoff; runtime + consumers treat null selections as empty without restoring defaults. Complete its required durable decision record. The glossary roadmap owns - the remaining selection-input and attribution decisions. This - application scope model does not change native source composition or - sibling-inheritance semantics. + the remaining stage-identity and attribution decision. This application scope + model does not change native source composition or sibling-inheritance semantics. ## Documentation and Acceptance diff --git a/docs/roadmap/glossary-stages.md b/docs/roadmap/glossary-stages.md index 0e478ce..3d414f7 100644 --- a/docs/roadmap/glossary-stages.md +++ b/docs/roadmap/glossary-stages.md @@ -29,7 +29,8 @@ Finalize the glossary representation with the agreed so operators migrate once. Collection placement and named selection are selected; default import sources, their tier, entry identity, and content fields are also selected. Runtime ordering and deduplication are selected below, with existing -business logic retained. Remaining selection and attribution details are open. +business logic retained. List clearing and the configuration handoff boundary +are resolved; stage identity and attribution remain open. ## Glossary Configuration Ownership — Resolved @@ -40,6 +41,13 @@ registrations where applicable, and domain validation through supported public APIs. Use native imports and layering rather than an Audita YAML loader or private glossary merge engine. +ConfigKit owns the entire configuration-resolution lifecycle up to handoff, +including explicit CLI assignment, presence tracking, defaults, and stage +inheritance. Audita supplies its domain-specific resolution rules through +ConfigKit's supported application lifecycle. Complete those rules before handing +off fully resolved configuration; do not add a second resolution pass in Audita's +processing code. + Before transcript processing, hand off fully resolved, typed Go glossary configuration and stage selections to Audita. Configuration-level domain checks belong in the supported ConfigKit validation lifecycle; structural decoding alone @@ -439,16 +447,17 @@ and rich-input order are selected above. Configuration composition must follow ConfigKit's contracts rather than a local rule to concatenate independently parsed files. -Resolve these settings in this order: +Resolve these settings through ConfigKit before deriving runtime views: 1. Load and compose glossary configuration and apply explicit CLI assignments through ConfigKit. 2. If root `protected_terms` is omitted, derive it from a copy of the effective root `glossaries`. Preserve any explicit root protection selection, including - `[]`. + `[]` or `null`. 3. Independently inherit the effective root `glossaries` and `protected_terms` into each stage wherever that stage omits the corresponding setting. A stage - override replaces only its own selected list. + override replaces only its own selected list; explicit `[]` or `null` suppresses + inheritance for that setting. 4. After the configuration handoff, derive runtime views. For a glossary module stage, construct its effective protected vocabulary by subtracting its active glossary terms from its selected protected terms. @@ -529,8 +538,8 @@ zero repairs is valid, while a zero operation timeout is invalid. | Explicit input | Meaning | | --- | --- | | `context.description: ""` | Clear the inherited description. | -| `glossaries: []` | Clear correction/context inputs; a glossary-correction stage then lacks its required input. | -| `protected_terms: []` | Disable glossary-derived protection without changing correction/context inputs. | +| `glossaries: []` or `glossaries: null` | Clear correction/context inputs; a glossary-correction stage then lacks its required input. | +| `protected_terms: []` or `protected_terms: null` | Disable glossary-derived protection without changing correction/context inputs. | | `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. | @@ -538,19 +547,50 @@ zero repairs is valid, while a zero operation timeout is invalid. 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. Preserve explicit empty selection semantics -(`[]` for list selectors) in the final glossary schema; null handling remains open -below. This concerns stage selections, not ConfigKit-owned definition collections. +settings groups are not nullable. For glossary and protection selection lists, +apply the resolved null-as-empty contract below. This concerns stage selections, +not ConfigKit-owned definition collections. Reject a glossary-correction stage's missing or empty effective input before execution. Other stages may operate without glossary context where their operation supports it, independently of their protection selection. Lists replace the entire inherited list where list-valued stage settings apply; -`[]` explicitly selects an empty list. Do not append or union implicitly. +`[]` and `null` explicitly select no entries. 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. +### List Inputs and Configuration Handoff — Resolved + +Use ConfigKit's native nullable-list decoding and explicit-presence tracking for +`glossaries` and `protected_terms`. Omission can trigger the agreed root defaults +or stage inheritance within ConfigKit's application-resolution lifecycle; +explicit `null` and `[]` both suppress that defaulting or inheritance. Resolve +all effective selections before handoff. + +Once Audita receives the fully resolved configuration, treat a null selection +as equivalent to an empty set. Do not restore defaults, inherit another value, +or run a second configuration-resolution pass because a received list is nil. +Nonempty selections retain their agreed ordering. ConfigKit may preserve the +input distinction between `null` and `[]` in provenance and inspection without +that distinction affecting processing; no normalization of the resolved +configuration is required solely to erase it. + +An empty effective protection selection contributes no protected vocabulary. +An empty effective glossary selection is invalid for a glossary-correction +stage, whether it originated from null, an empty list, or absent configuration. +Enforce that domain requirement through ConfigKit's supported validation +lifecycle before processing. + +Use standard CommandKit/parser conventions for CLI list inputs and ConfigKit's +native override API for explicit root assignments. Pass the completed parser +selection as one override for its root field; let ConfigKit apply it and resolve +the resulting configuration. Exact flag spelling is an implementation detail +within that boundary. Do not introduce custom clearing syntax or merge machinery. +Explicit stage selections remain authoritative under the resolved precedence +rules. Use `[]` as the usual configuration example for clearing while accepting +native null values. + ### CLI Overrides and Stage Precedence — Resolved Ordinary CLI setting flags override the corresponding root settings through @@ -565,7 +605,8 @@ selection changes grammar's inherited input and, with root `protected_terms` omitted, the derived protection inherited by all three stages. The explicit party and spell correction selections stay unchanged. An explicit root protection list is not changed by a root glossary assignment; -an explicit stage protection list or `[]` remains authoritative for that stage. +an explicit stage protection list, `[]`, or `null` remains authoritative for that +stage. Apply this precedence consistently to all stage-capable settings. Submit only explicitly supplied CLI values to ConfigKit; preserve false, zero, and empty values under their per-field rules rather than allowing parser defaults to @@ -621,7 +662,8 @@ use `configkit.Default` for root `protected_terms`, copying effective root `glossaries` and recording that path as its dependency. Then default each omitted stage protection list from the effective root protection list, even when that root value was derived. Preserve source context through both steps and avoid -shared mutable list storage. Explicit empty lists must suppress defaulting. +shared mutable list storage. Explicit empty lists and nulls must suppress +defaulting. Leave `protected_terms` absent from the bundled configuration underlay. ConfigKit does not express this live list-to-list dependency as a declarative underlay @@ -674,9 +716,9 @@ requirement visible during library design without expanding those migrations into feature implementation. 1. Apply named collection selection, default file/directory underlay imports, - recursive placement, and the extensible entry content contract. Settle CLI - selection syntax and remaining domain decisions below. Preserve the selected - scope, clearing, CLI precedence, and fallback semantics in version 3. + recursive placement, and the extensible entry content contract. Apply native + CLI list conventions and settle stage identity and attribution below. Preserve + the selected scope, clearing, CLI precedence, and fallback semantics in version 3. 2. Adopt ConfigKit loading for glossary configuration. Register the selected collection identities, supply domain validation, and deliver final typed definitions and selections before transcript processing. Remove the redundant @@ -772,6 +814,14 @@ 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. +For glossary and protection selections, cover omitted, null, empty, and nonempty +root and stage inputs through ConfigKit resolution. Confirm explicit null and +empty lists suppress defaulting and inheritance while inspection preserves native +provenance. Verify equivalent null/empty behavior in runtime consumers, with no +post-handoff default restoration or configuration resolution. Both forms must +fail domain validation when they leave a glossary-correction stage without input. +Exercise CLI list assignment through the standard parser and ConfigKit override +path, including explicit empty selections and unchanged explicit stage settings. 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 @@ -798,22 +848,6 @@ guidance are in place before declaring this feature complete. The recommendations below are proposals, not selected contracts. -### List Inputs and CLI Representation - -**Recommendation:** accept explicit null as an empty selection, preserving native -ConfigKit slice decoding and presence without an additional rejection rule. Keep -`[]` as the primary documented clearing form. This requires documenting a second -clearing form and ensuring null suppresses protection defaulting just as `[]` -does. Select CLI syntax for whole root name selections using native ConfigKit -overrides. These are ordinary selection lists, -not entry collections governed by native identity/operation policies. - -**Alternative:** reject null for the two selection lists and require `[]` for -clearing. This offers one explicit empty-list spelling but adds application -validation beyond ConfigKit's nullable slice decoding. CLI spelling remains to -be selected; it does not reopen root-versus-stage precedence or imply -targeted-stage overrides. - ### Stage Identity and Attribution **Recommendation:** support optional operator-chosen stage IDs alongside execution