diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md index 2f50294..66cab1c 100644 --- a/docs/roadmap/configkit.md +++ b/docs/roadmap/configkit.md @@ -140,7 +140,10 @@ file remain terminal. 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. + consumers treat null selections as empty without restoring defaults. Follow its + [Audita preflight boundary](glossary-stages.md#empty-collections-and-audita-preflight--resolved): + permit empty collection configuration and check glossary-stage readiness in + Audita after handoff, before execution. Apply its [optional stage identity and attribution contract](glossary-stages.md#stage-identity-and-attribution--resolved) and complete its required durable decision record. 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 bbb70b4..66e0e7b 100644 --- a/docs/roadmap/glossary-stages.md +++ b/docs/roadmap/glossary-stages.md @@ -6,8 +6,9 @@ the next Audita major release, including named collections and recursive import placement, optional default sources, collection-scoped entry IDs, extensible entry content fields, and optional stage IDs. Active glossary vocabulary takes -precedence over overlapping protection. Empty selected collections remain an -open decision; implementation is pending. The +precedence over overlapping protection. Empty collections are permitted, with +Audita preflight rejecting empty glossary stages. Design decisions are resolved; +implementation is pending. The [master roadmap](library-adoption.md) owns sequencing and release completion. ## Baseline and Target @@ -33,16 +34,17 @@ default import sources, their tier, entry identity, and content fields are also selected. Runtime ordering, deduplication, and active-vocabulary exemptions are selected below; other validation business logic is retained. List clearing and the configuration handoff boundary are resolved, as are optional stage identity -and attribution. The treatment of empty selected collections remains open. +and attribution. Empty collections and preflight readiness checks are resolved +below. ## Glossary Configuration Ownership — Resolved Glossaries are configuration. ConfigKit owns their source loading, parsing, composition, inheritance, collection operations, strict typed decoding, and configuration provenance. Audita supplies the Go schema, collection identity -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. +registrations where applicable, and configuration-contract 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 @@ -52,10 +54,12 @@ off fully resolved configuration; do not add a second resolution pass in Audita' 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 -does not establish domain correctness. Audita's processing code must not reopen -glossary documents or parse arbitrary YAML after this handoff. Remove the separate +configuration and stage selections to Audita. Schema and configuration-consistency +checks use the supported ConfigKit validation lifecycle. Audita then runs an +explicit preflight phase for execution-readiness business logic, including the +nonempty glossary-stage check below. A valid configuration does not by itself +establish that a processing run has useful work. Audita's processing code must not +reopen glossary documents or parse arbitrary YAML after this handoff. Remove the separate glossary decoding/composition path when the new contract lands. All configuration-source path and resolution behavior remains upstream-owned, @@ -383,6 +387,35 @@ logic, including protected-name repetition handling. Integrate the reduced vocabulary without reintroducing protection for exempt active spellings through another contributing entry or a downstream protected-term check. +## Empty Collections and Audita Preflight — Resolved + +Permit glossary collections with no entries. They remain valid configuration +assets, whether imported for reuse, inspected, or selected alongside populated +collections. A nonempty list of selected collection names does not establish +that a stage has entries to process. + +Add an explicit Audita preflight phase after ConfigKit hands off the fully +resolved configuration and before pipeline execution begins. Preflight evaluates +execution-readiness business rules against that resolved data. It does not load +sources, resolve configuration, restore defaults, or change stage inheritance. +Keep the nonempty glossary-stage check in Audita preflight rather than ConfigKit's +configuration-validation callbacks. + +Preflight checks every configured glossary-correction stage. Its combined selected +collections must supply at least one entry. Empty selections, null selections, +and nonempty selections whose collections collectively contain no entries fail +this check. A mixture of empty and populated collections passes when the combined +input contains an entry. An empty protection selection remains valid and supplies +no protected vocabulary. + +Complete preflight for the entire pipeline before executing any stage or making +processing model calls, so an empty later glossary stage cannot fail only after +earlier stages have incurred work. Report a clear readiness error identifying +the stage by position, module, and optional ID, with its selected collections. +Do not silently skip the stage. This is a processing preflight phase, not another +operator-configured pipeline module; ordinary configuration/resource inspection +can still inspect valid empty collections. + ## Root Defaults and Stage Overrides — Resolved Define global stage defaults at the configuration root. Represent the pipeline @@ -541,9 +574,10 @@ A stage can supply a narrower or different `protected_terms` list. Explicit clearing its correction/context inputs or disabling other validators. Explicit `glossaries: []` clears correction/context inputs without changing the protection selection. -A glossary-correction stage requires a nonempty effective glossary selection; -other stages may operate without glossary context where supported. A glossary -selected only by a stage is not automatically added to root protection. +Audita preflight requires a glossary-correction stage's effective selection to +supply at least one entry; other stages may operate without glossary context +where supported. A glossary selected only by a stage is not automatically added +to root protection. Use the active-term exemption for glossary correction and retain the existing module-appropriate allowance for spoken-word cleanup. Carry both selections @@ -598,9 +632,10 @@ explicit null through resolution. Null is not a universal reset operation; 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. +Reject a glossary-correction stage's missing or empty effective input in Audita +preflight after configuration handoff and 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; `[]` and `null` explicitly select no entries. Do not append or union implicitly. @@ -625,10 +660,10 @@ 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. +An empty effective glossary input makes a glossary-correction stage unready to +execute, whether it originated from null, an empty list, absent configuration, +or selected collections with no entries. Enforce that business rule in Audita +preflight after handoff; ConfigKit may successfully resolve those configurations. Use standard CommandKit/parser conventions for CLI list inputs and ConfigKit's native override API for explicit root assignments. Pass the completed parser @@ -725,8 +760,10 @@ 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. +for all derived mutations, and use `Definition.Validate` for configuration-contract +checks on effective settings. The execution-readiness check for an empty glossary +stage belongs to Audita preflight after handoff. Keep stage values independent +when copying compound values. The selected defaulting rules use existing public APIs. Verify the final glossary composition and selection design against the native API before implementation; do not compensate for a mismatch with a private configuration system. @@ -734,8 +771,8 @@ do not compensate for a mismatch with a private configuration system. ### Durable Decision Record Completion requires durable documentation before retiring this roadmap. Record -the glossary-configuration ownership boundary and typed-handoff architecture in -an ADR under the [documentation policy](../policy/documentation.md#architecture-decision-records). +the glossary-configuration ownership boundary, typed handoff, and Audita preflight +responsibility in an ADR under the [documentation policy](../policy/documentation.md#architecture-decision-records). This is an architectural ownership decision; routine scope and clearing choices do not each require an ADR. The roadmap owns implementation status and sequencing. @@ -769,19 +806,22 @@ into feature implementation. 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 + collection identities, validate configuration contracts, and deliver final typed definitions and selections before transcript processing. Remove the redundant standalone YAML parser and local composition path. -3. Derive rich LLM inputs, deduplicated protection vocabulary, and glossary-stage +3. Add Audita preflight after configuration handoff. Reject any glossary stage + whose selected collections supply no entries before any stage executes. + Permit empty collection definitions and preserve inspection access to them. +4. Derive rich LLM inputs, deduplicated protection vocabulary, and glossary-stage exemptions from resolved configuration. Route the appropriate views through proposal generation and validators without mutating configuration or other stages. Preserve source attribution for diagnostics and inspection. -4. Verify native composition and the domain behavior together. Account for all +5. Verify native composition and the domain behavior together. Account for all consumed configuration sources in input handling and output-collision protection. Make repeated stages and their selected collections understandable in inspection, diagnostics, and reports using optional IDs alongside position and module identity. -5. Update configuration, CLI, input contracts, pipeline documentation, maintained +6. Update configuration, CLI, input contracts, pipeline documentation, maintained examples, and hard-cutover guidance as implementation lands. Complete the ADR, durable policy, and future-setting classification guidance above. No runtime compatibility layer for the old glossary file format is required. @@ -849,7 +889,8 @@ and inspection; extension data must not mask invalid known fields. Verify that unrelated extra fields affect neither the LLM projection nor protected vocabulary. Exercise native glossary composition, inheritance, collection identity checks, and supported explicit layering with reusable party/spells fixtures. Cover source -origins, strict decoding failures, and domain validation failures before processing. +origins and configuration validation failures during loading, then business-rule +failures during Audita preflight before processing. Test configured discovery/no-main-file behavior through the supported load path; do not add a secondary glossary-file resolver. Verify that inheritance and application derivations retain traceability to their configuration inputs. @@ -876,13 +917,19 @@ 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. +fail Audita preflight when they leave a glossary-correction stage without input. +Verify ConfigKit can hand off empty collections and empty effective selections +and that ordinary inspection remains available. Cover a selected empty collection, +several collectively empty collections, and mixed empty/populated collections. +Include an empty glossary stage late in the pipeline and verify preflight fails +before any stage executes or processing model calls occur. Check useful stage +and collection attribution in the readiness error, and no silent stage skipping. 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 -history as well as effective values. Verify that explicit CLI flags change root +fails preflight before execution. Check recorded dependencies and retained +clear-input history as well as effective values. Verify that explicit CLI flags change root defaults and inherited stage values while preserving explicit stage settings and clearing. Cover profile fallback after CLI assignment, explicit false/zero/ empty CLI values where valid, and the absence of overrides from parser defaults. @@ -905,23 +952,3 @@ still protects its full selection and that inspection distinguishes configured protection inputs from the glossary stage's effective protected vocabulary. Confirm that the durable policy, configuration contracts, and contributor guidance are in place before declaring this feature complete. - -## Open Decisions - -### Empty Selected Collections - -A nonempty selection such as `glossaries: [party]` can refer to a collection with -no entries. The selected rules reject an empty selection for a glossary-correction -stage, but do not yet settle empty collection definitions or selections whose -combined collections contain no entries. - -**Recommendation:** permit empty collection definitions, but require a glossary -stage's combined selected collections to contain at least one entry. Validate -that requirement through ConfigKit before handoff. This allows reusable assets -and mixtures of empty and populated collections without running a correction -pass that has no vocabulary. - -**Alternative:** allow an empty combined glossary and treat that stage as a no-op. -This supports reusable pipelines when a campaign has no entries for a particular -pass, but can hide an unintentionally empty input and requires explicit reporting -and execution semantics for the skipped stage. This behavior is not selected.