# Stage-Specific Glossary Inputs **Updated:** 2026-11-08 **Status:** Accepted feature scope, ownership, and stage-selection semantics for the next Audita major release, including named collections and recursive import placement, optional default sources, and collection-scoped entry IDs. Rich fields, remaining design decisions, and implementation are pending. The [master roadmap](library-adoption.md) owns sequencing and release completion. ## Baseline and Target The current [CLI](../cli.md) accepts one glossary input for a processing run. The [pipeline configuration](../config.md) supports repeated glossary stages, but does not select different glossary inputs for each occurrence. Glossary files currently have a separate [YAML input contract](../integrations/transcript-glossary-files.md#glossary-yaml-contract). Make glossaries and glossary collections reusable, composable configuration assets loaded and composed by ConfigKit. Allow ordered stages to select different resolved vocabulary within one processing run: for example, a focused party pass, a focused spell pass, and grammar cleanup using both. Each stage processes the transcript resulting from earlier stages. Operators need not maintain one manually combined glossary or run Audita separately for each pass. The major-release policy permits a hard cutover. The current single-glossary CLI, standalone parser, and file schema do not constrain the target design. Finalize the glossary representation with the agreed [version-3 application schema](configkit.md#application-schema-version--resolved) so operators migrate once. Collection placement and named selection are selected; default import sources, their tier, and entry identity are also selected. Rich fields, runtime ambiguity, and remaining selection details are open 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. 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 glossary decoding/composition path when the new contract lands. All configuration-source path and resolution behavior remains upstream-owned, including glossary documents, imports, overlays, and source resource contexts. Retain native source attribution through application resolution. A glossary filename is a configuration source, not an application-data file for a second post-handoff loader. Choose the source arrangement through ConfigKit's public composition APIs; a string in an application field does not automatically cause ConfigKit to load another document. Use the selected import placement and application-supplied underlay below. ### Named Collections and Recursive Imports — Resolved Define `glossary_collections` as a typed mapping of collection names to collection objects. Each object contains an `entries` collection. Root and stage `glossaries` and `protected_terms` are ordered lists selecting those names, not filenames. An omitted stage selection inherits the root selection; an explicit list replaces it, and `[]` selects none. Report unknown collection names during configuration validation. Selection order determines runtime traversal, not source precedence. Mount glossary inputs at `glossary_collections`, with each imported file declaring its collection name. The default underlay below supplies native file and recursive directory imports, keeping the main configuration focused on selection and stages: ```yaml version: 3 glossaries: [party, spells] pipeline: stages: - module: glossary glossaries: [party] - module: glossary glossaries: [spells] - module: grammar ``` An imported `party.yml` declares the collection directly, without repeating the application's `glossary_collections` wrapper: ```yaml party: entries: - id: merrin name: Merrin category: character summary: The party's wizard. ``` The `party`/`entries` nesting and explicit `id` are selected. The rich fields in this illustration remain provisional pending the content-field decision below. Keep collection identity in document keys. ConfigKit does not infer keys from filenames or subdirectories; all matches of the declaration receive the same destination. Moving a file within the imported tree therefore need not change stage selections. A file can define multiple collections, and multiple sources can contribute to one collection under native composition and identity rules. Repeated membership and runtime entry ordering remain domain decisions below. Use native mapping placement, discovery, composition, and provenance. Do not add a directory walker, filename-to-key conversion, or YAML preprocessing in Audita. Imports in the same tier are strict peers; their discovery order does not create an override priority. Intentional overrides use upstream layering semantics. ### Entry Identity — Resolved Represent each collection's `entries` as an ordered identified list. Each entry has an explicit, stable, nonempty string `id`, unique within that collection. Its configuration identity is the pair of collection name and entry ID. Keep identity independent of the displayed term, category, and descriptive text so those fields can change without changing the record being addressed. Register `id` through ConfigKit's application sequence-identity API at every `glossary_collections..entries` destination, using a native mapping wildcard registration. Authors do not need to repeat identity declarations in every file. ConfigKit owns duplicate-identity checks, inheritance lookup, and cross-layer matching, including final typed-result identity validation. Audita's domain validation requires nonempty string IDs; comparisons use ConfigKit's native exact matching, without case folding or a custom normalization scheme. Recommend readable IDs such as `shield` or `mordenkainens-magnificent-mansion`; do not require generated UUIDs or impose a slug syntax. The same ID may occur in different collections and identifies distinct configuration records there. Two entries with different IDs may also share a displayed name. Neither matching IDs across collections nor matching text implicitly establishes semantic identity. Runtime protection may still deduplicate their recognized spellings. A higher-priority definition targets an existing record by retaining its ID in the same collection. Apply native collection operations: duplicate identities among strict peers fail, while upsert at a precedence boundary replaces the whole matching record. Do not treat an identified list as a mapping that merges individual fields of matching records. The selected ordinary stage-selection lists remain separate from these definition collections. ### Default Sources and Explicit Configuration — Resolved Audita supplies one glossary underlay with two optional native imports: ```yaml config: imports: - path: glossary.yml required: false destination: [glossary_collections] - dir: glossary required: false recursive: true pattern: ["*.yml", "*.yaml"] destination: [glossary_collections] ``` Both locations are relative to the invocation's working directory: `./glossary.yml` and recursively `./glossary/`. Supply the appropriate host filesystem context for the underlay declaration through ConfigKit's public input APIs. This base is independent of the main configuration file's location and also applies when no main file is found. Do not attempt host discovery through an unrelated embedded filesystem or add an application-owned directory walker. Load both sources when present; this is composition, not first-match discovery. Missing optional sources contribute nothing. Present sources retain ConfigKit's normal parse, access, and composition errors; absence does not remove the domain requirement for a glossary-correction stage to select usable vocabulary. The file and directory contributions compose as strict peers in the same underlay tier. Neither overrides the other by declaration or discovery order. Main configuration and its imports have higher priority and can supplement or replace definitions according to native mapping and collection policies. An identified-list upsert replaces the whole matched record; details depend on the selected entry identity and native collection policy. Operators can put small inline collections in `glossary.yml`, organize larger libraries below `glossary/`, or use both. Nested imports retain native relative path and destination inheritance. A nested import from mounted `glossary.yml` inherits the `glossary_collections` destination unless it explicitly extends it. Do not repeat that destination unnecessarily in a manifest. With both defaults enabled, use the file for inline collections or imports of other sources, rather than a manifest that also imports the files discovered under `glossary/`. Repeated inclusion within the tier retains ConfigKit's native error; Audita does not silently deduplicate the import graph. Explicit main-file imports supplement the underlay's sources; they do not cancel its import declarations. In particular, main-file `config.imports: []` does not disable default loading. An underlay does not set a universal destination for unrelated explicit imports. Changing or disabling default discovery, if added later, would require a load-time choice before ConfigKit processes the underlay; ordinary resolved application values cannot retroactively change those imports. ### Shared Libraries and Campaign Vocabulary — Resolved As a campaign maintainer, I can compose a reusable, versioned D&D glossary library with campaign-specific vocabulary without editing the shared definitions. I can select different combinations for focused correction passes while protecting the selected vocabulary throughout the pipeline. Use stable, descriptive collection names independent of filenames. For example: | Shared collections | Campaign collections | | --- | --- | | `dnd5e.spells` | `campaign.party` | | `forgotten_realms.places` | `campaign.npcs` | | `dnd5e.creatures` | `campaign.places` | These are literal mapping keys. Dots are a naming convention, not nested lookup or another reference language; this convention does not restrict other valid collection names. A shared document declares the same key wherever it is used. One practical project layout is: ```text campaign/ audita.yml glossary.yml glossary/ shared/ dnd5e/ spells.yml creatures.yml forgotten-realms/ places.yml campaign/ party.yml npcs.yml places.yml ``` Run from the campaign directory to use the default sources. `glossary.yml` can contain small inline collections; the default recursive directory import discovers the shared and campaign subtrees through ConfigKit. A vendored library release or pinned checkout inside the configuration tree lets each campaign adopt shared updates deliberately and independently. Library distribution and revision management remain outside Audita; it consumes local configuration sources through native imports. This layout fits the native import-root model without adding cross-directory discovery conventions. Importing collections makes them available; selections determine their use. For example, the campaign can select the following vocabulary and focused passes: ```yaml glossaries: - dnd5e.spells - forgotten_realms.places - campaign.party - campaign.npcs - campaign.places pipeline: stages: - module: glossary glossaries: [campaign.party, campaign.npcs] - module: glossary glossaries: [dnd5e.spells] - module: glossary glossaries: [forgotten_realms.places, campaign.places] - module: grammar ``` With `protected_terms` omitted, root protection derives from that selection. Each glossary stage exempts its active vocabulary; grammar protects the complete selection. An available but unselected collection such as `dnd5e.creatures` does not automatically enter prompt inputs or protected vocabulary. Imported sources still undergo normal ConfigKit composition and validation. Add new campaign vocabulary in campaign collections and select it alongside the shared collections. Intentional adaptations of shared definitions use native ConfigKit inheritance or explicit layering, without changing the shared source. Use the selected collection-scoped entry identity when adapting definitions; directory order must never silently choose which definition wins. ### Derived Runtime Representations — Resolved Keep the resolved configuration intact. Audita derives separate runtime views for its consumers, preserving traceability to configured entries and selections: | Consumer | Derived representation | | --- | --- | | Glossary module LLM | Rich entries with terms, categories, descriptive comments/context when present, and other relevant configured fields. | | Protected-term validator | Deduplicated recognized vocabulary prepared for deterministic matching. | | Glossary-stage protection | Selected protected vocabulary minus the active glossary vocabulary. | | Diagnostics and inspection | Resolved definitions and selections with their configuration origins, distinguished from derived runtime views. | ConfigKit's identity and composition rules govern which configuration records coexist or replace one another. Runtime vocabulary deduplication governs whether multiple valid records contribute the same recognized spelling. Do not use the latter to suppress configuration conflicts or rewrite the resolved definitions. Rich prompt data need not lose distinct definitions merely because their text matches in the protection view. Audita owns matching, transcript-specific validation, and the selected stage-specific transformations. Detailed handling of ambiguous identities and rich-entry payloads remains open below. ## Root Defaults and Stage Overrides — Resolved Define global stage defaults at the configuration root. Represent the pipeline as an ordered `pipeline.stages` list of objects, each selecting a `module` and optionally overriding stage settings. Resolve every stage independently against the root settings. Omitted stage settings inherit; explicit stage values override. Preserve meaningful false, zero, and empty values under each setting's validation rules rather than treating them as omission. A stage override does not alter root settings or defaults seen by later stages. `glossaries` and `protected_terms` select named definitions from the resolved `glossary_collections` mapping. Keep file organization in the import declarations and collection names in stage settings. This is domain selection over typed data, not a general variable-substitution language. For the party/spells use case, the root selects both collections, the first stage selects party vocabulary, the second selects spell vocabulary, and grammar inherits both. All stages inherit the root protection selection by default; glossary stages exempt their active vocabulary as described below. Transcript changes carry forward; configuration overrides do not. Each consumer receives the appropriate view of its stage's effective settings. Invocation-wide concerns such as configuration discovery, output destinations, and reporting mode remain global. Preserve stage order, repeated modules, and explicit empty-pipeline behavior. Use native ConfigKit presence and provenance; Audita owns the domain meaning of stage scope. ## Configuration Scope — Resolved Settings governing an individual stage's requests, acceptance, or model-operation budget support root defaults and stage overrides. Settings governing preprocessing, the invocation's shared resources, or its final outputs remain global. Classify by the setting's meaning and consumer lifecycle, not by where current code stores it. The inventory below records the selected scopes; version-3 field representation must preserve these decisions. | Setting | Scope and rationale | | --- | --- | | `glossaries` selection | Stage: resolved glossary collections supplying correction and context vocabulary. | | `protected_terms` selection | Stage: independently selected glossary collections supplying protected vocabulary; defaults from root `glossaries` before stage inheritance. | | Glossary definitions and collection composition | Global: typed definitions composed through ConfigKit; runtime views are derived per consumer. | | Applicable confidence threshold | Stage: acceptance of that stage's proposals. | | Proposal and validation profile selection | Stage: models and generation settings appropriate to each role. | | `context.description` | Stage: prompt context shared by proposals and validators. | | `validation.max_prompt_tokens` | Stage: batching budget for that stage's validators. | | `llm.operation_timeout` | Stage: deadline for each logical model operation. | | `llm.repair_attempts` | Stage: structural-repair budget for its requests. | | `llm.transient_retries` | Stage: native transient-retry budget for its requests. | | All `normalization.*` settings | Global: establish transcript segments before stage execution. | | All `chunking.*` settings | Global: establish common section boundaries and identities across stages. | | Transcript input, output destination, and `output.schema` | Global: input and final product of the whole run. | | Reporting, debug capture, and artifact directories | Global: invocation reporting and retained evidence. | | Configuration discovery, imports, and resource-source locations | Global: construct the configuration and catalog shared by stages. | | Backend definitions, credentials, concurrency, and queue capacity | Global native PromptKit resources and shared backend admission. | | Pipeline ordering and application schema version | Global: define the overall processing configuration. | Stages may select different profiles and thereby different configured models or backends. Model parameters remain in native PromptKit profiles rather than a duplicated Audita settings system. Apply stage request budgets through native request controls and operation contexts while retaining the shared engine and backend admission. Do not rebuild or mutate shared backend configuration for each stage. Per-stage validation batching does not change transcript chunking; per-stage rechunking would be a separate feature decision. ### Glossary Selection and Protected Vocabulary — Resolved Select correction/context vocabulary and protection vocabulary independently at root and stage scopes. A glossary stage without an override uses the entire root glossary selection; an explicit stage selection supports a focused pass. An explicit protection selection is complete, not an additive set of extra vocabulary. Do not implicitly union it with correction inputs or collections selected by other stages. The named mapping and ordered name selections are selected above. Entry identity, repeated membership, and rich-input order remain open. Configuration composition must follow ConfigKit's contracts rather than a local rule to concatenate independently parsed files. Resolve these settings in this order: 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 `[]`. 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. 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. Non-glossary stages use their selected protection vocabulary without this subtraction. Protection therefore defaults at the root before stage inheritance. It does not fall back to a focused stage's glossary list. In the party/spells scenario, no operator protection configuration is needed: | Stage | Glossary input | Protection selection | Effective protected vocabulary | | --- | --- | --- | --- | | Party glossary pass | Party | Party + spells | Spells | | Spell glossary pass | Spells | Party + spells | Party | | Grammar | Party + spells | Party + spells | Party + spells | The table assumes distinct party and spell vocabulary. The subtraction applies after resolving both stage selections, including explicit protection overrides. It operates on recognized terms using the protection matcher's rules, including names, aliases, and supported plural forms, rather than subtracting configuration source files or collection names. Terms shared across collections participate in the same operation; shared spellings associated with different identities remain part of the overlap decision below. Keep the configured protection selection intact and construct the reduced vocabulary separately for that stage. Do not mutate root settings, loaded glossary entries, or another stage's protection. A glossary stage selecting all of its protected vocabulary as active input has no glossary-derived protection from those terms; its other validators still assess proposed corrections. A stage can supply a narrower or different `protected_terms` list. Explicit `protected_terms: []` disables glossary-derived protection for that stage without 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. Use the active-term exemption for glossary correction and retain the existing module-appropriate allowance for spoken-word cleanup. Carry both selections through execution and validation rather than passing a single combined glossary to every consumer. Runtime overlap and payload details remain open below. ### Validation-Profile Fallback — Resolved 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 | 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, with derived defaults applied at the scope specified for each setting. Root protection defaulting precedes stage inheritance; validation-profile fallback follows the combination of root and stage selections. 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. | | `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. | | `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. 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. 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. 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. ### CLI Overrides and Stage Precedence — Resolved Ordinary CLI setting flags override the corresponding root settings through ConfigKit's native CLI override API. Resolve stage inheritance afterward: omitted stage fields inherit the effective root values, while explicit stage values and clearing remain authoritative for that stage. Apply validation-profile fallback after combining these selections. This preserves deliberate differences between stages while allowing invocation-specific changes to their defaults. For the party/spells scenario, a CLI assignment changing the root glossary 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. 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 override configuration. Keep CLI functionality within ConfigKit's native capabilities. ConfigKit v1.1.0 does not support sequence-index paths in its CLI override API, so targeted-stage CLI overrides are not part of this plan. Operators supply stage-specific values in configuration files. Do not implement a parallel override system, custom merge machinery, or a workaround for addressing stage-list entries. Any future targeted-stage CLI support should depend on suitable native ConfigKit support. The open stage-identity decision concerns reporting and diagnostics; stage IDs do not imply CLI targeting. Audita's domain-specific inheritance and fallback rules remain within ConfigKit's supported application-resolution lifecycle. ### 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. Use the native [collection and inheritance contracts](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/config.md#strict-document-composition) for glossary definitions. For identified lists, register identity constraints in Audita's ConfigKit definition so native final validation also covers values from defaults, CLI, and recorded resolution. YAML-only declarations do not provide that final-result guarantee. Apply the selected collection-scoped `id` identity through `SequenceIdentityMatching` with literal mapping keys and an any-mapping-key segment for the collection name. Compose sources in the scope where cross-source identity and inheritance are intended to apply. Loading files separately and concatenating afterward does not provide those upstream guarantees. Strict peers reject duplicate identities, including identical records; higher layers follow native collection operations, and upsert replaces a whole matching record. Empty identified collections follow their native mode (`[]` does not clear an append/upsert collection). These rules are distinct from Audita's whole-list replacement of ordinary stage selections. Do not extend native inheritance beyond its supported sibling scope or treat inherited entries as abstract templates exempt from normal validation. 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. Implement root protection defaulting in the same `Definition.Resolve` callback: 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. Leave `protected_terms` absent from the bundled configuration underlay. ConfigKit does not express this live list-to-list dependency as a declarative underlay reference: native `extends` concerns sibling mappings and runs before CLI assignment. Use the public recorded-resolution lifecycle, which sees final CLI assignments, rather than static duplicated lists or custom reference machinery. 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. 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. ### 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). This is an architectural ownership decision; routine scope and clearing choices do not each require an ADR. The roadmap owns implementation status and sequencing. Put enduring scope classification and ownership rules in the [architecture policy](../policy/architecture.md) and the implemented collection, selection, defaulting, and clearing contracts in the [configuration reference](../config.md). Update the glossary input contract and consumer internals as the redesign lands, removing obsolete standalone-parser instructions. Document the distinction between configuration identity and derived runtime vocabulary without copying the native ConfigKit reference into Audita. Update the [configuration change guide](../internal/cli-config.md) to require classifying each new setting by consumer lifecycle, specifying its inheritance and presence behavior, and documenting its scope in the configuration reference. New settings should follow the established stage/global distinction; deliberate exceptions need a domain rationale. Link to the durable policy rather than copy the field inventory into multiple developer documents. This documentation work is part of feature acceptance, not an optional follow-up. ## Sequencing and Work Outline Implement after ConfigKit, PromptKit, CommandKit, and ReleaseKit adoption, and before final release validation and preparation. This lets the feature use the 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 named collection selection, default file/directory underlay imports, and recursive placement. Settle entry schema, CLI selection syntax, and remaining domain decisions 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 standalone YAML parser and local composition path. 3. 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 consumed configuration sources in input handling and output-collision protection. Make repeated stages and their selected collections understandable in inspection, diagnostics, and reports. 5. 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. ## Acceptance Direction Include a shared-library scenario with two campaigns consuming the same reusable library and maintaining different local party, NPC, and place collections. Verify independent selections and focused stages, inherited protection and active-term exemptions, and provenance identifying shared versus campaign definitions. Demonstrate an intentional adaptation through the selected native inheritance/layering contract without modifying the shared source or the other campaign's configuration. Cover an imported but unselected collection remaining absent from prompt/protection views. Maintained examples should show deliberate library revision adoption without introducing package-management code in Audita. Use distinct party and spell fixtures with controlled model responses to show that each stage receives its intended correction and protection selections, that overrides do not leak into other stages, and that the second stage sees the first stage's accepted transcript changes. Verify meaningful errors for invalid selections or inputs, and retain the selected domain validation and partial-success behavior. Exact test cases follow the design; live provider calls are unnecessary. Verify root fallback, per-stage override isolation, and explicit-value presence for the selected stage settings. Include the grammar stage after the overridden glossary stage to establish that it inherits both root glossary inputs. Verify that all three stages inherit root protection derived from those inputs despite the focused correction selections. Cover explicit root and stage protection lists, independent empty-list clearing, a glossary stage with no override using both inputs, and a collection selected only on a stage not entering root protection. Verify that modules and validators receive their respective effective selections and recorded source origins. Cover repeated modules and an empty stage list. Cover default-source loading with only `glossary.yml`, only `glossary/`, both, and neither present. Verify invocation-directory resolution even with a main file elsewhere or no main file, optional absence, and normal errors for invalid present sources. Verify strict-peer conflicts within the underlay, higher-priority main configuration additions/replacements under the selected native policies, nested import destination inheritance, and repeated inclusion within the default tier. Confirm that an empty main-file import list does not cancel the underlay imports. Exercise recursive directory imports with nested files, both YAML extensions, explicit collection names, and native placement/source attribution. Verify that file relocation within the imported tree preserves collection selection, and unknown collection names fail configuration validation. Cover multiple collections in one file and contributions from multiple files under the selected identity rules. Do not derive collection keys from filenames or discovery order. Verify that missing, null, or empty entry IDs fail, and duplicate IDs in a collection's strict peer sources retain native errors. Cover native matching of IDs across layers, including whole-record upsert, and final-result validation. Allow the same ID in different collections and the same displayed name on distinct records. Verify that changing a term or description while retaining its ID targets the same collection record, and that runtime spelling deduplication does not collapse distinct configuration identities. Cover exact case-sensitive ID matching. 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. 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. Verify that distinct valid definitions can contribute to a deduplicated runtime vocabulary without rewriting rich configured entries. Check that rich LLM input contains the selected descriptive fields, and that deriving or using any runtime view leaves configuration and other consumers' views unchanged. Verify the selected rules for repeated membership, entry ordering, and ambiguous spellings. 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. 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. Cover root protection defaulting after CLI assignment, explicit root protection surviving glossary overrides, and recorded root-to-stage protection dependencies. Verify module-appropriate protection using terminology from both collections, including legitimate corrections and cleanup; test the selected overlap/conflict behavior. For glossary stages, verify that active terms are exempt while remaining selected terms stay protected, including when protection was explicitly configured. Cover names, aliases, supported plurals, and vocabulary shared across collections. Verify the all-active case produces an empty effective protected vocabulary without disabling other validators. Confirm that a later non-glossary stage 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 The recommendations below are proposals, not selected contracts. ### Entry Content Fields **Recommendation:** retain `name`, `category`, `summary`, `aliases`, and `plural` as the rich entry fields, with required name/category and optional descriptive summary, aliases, and explicit plural. This keeps descriptive context available without requiring filler text for obvious terms. Confirm field validation and how each consumer uses optional values; the optional-summary contract would be a deliberate change from the current glossary format. Identity is already settled independently through `id`. **Alternative:** rename the descriptive field to `comment` (or another selected name) and revise requiredness as part of the major-release schema. This can align the field with optional operator guidance rather than a formal definition, but requires agreeing on its meaning and updating all authoring examples. Avoid parallel interchangeable fields or an unnecessary legacy alias; compatibility with the old format is not a constraint on the choice. ### Runtime Vocabulary and Identity Ambiguity **Recommendation:** deduplicate recognized spellings for protection using the same matching rules as active-term subtraction, while retaining distinct resolved entry identities and rich data. Repeated membership must not multiply protection. For checks that depend on identity, do not infer equivalence or grant a relaxation solely because entries share an alias; define conservative behavior for ambiguous matches. Specify deterministic rich-input ordering and whether repeated selection of the same resolved entry appears once. This preserves useful context without turning runtime deduplication into configuration conflict resolution, but requires focused decisions and tests around identity-dependent cleanup. **Alternative:** reject ambiguous names or aliases at domain validation time. This simplifies deterministic identity checks, but disallows legitimate shared spellings and burdens authors of reusable collections. Native ConfigKit record identity checks remain authoritative in either case; they do not determine which meaning a transcript occurrence has. The active-glossary exemption itself is already selected and is not reopened by this decision. ### 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 position and module identity. Use them for readable reports and diagnostics when supplied, and show each stage's effective inputs and source origins. This helps distinguish repeated modules and survives reordering, but introduces ID validation rules that must be specified. CLI targeting is outside this decision under the resolved precedence and native-support boundary above. **Alternative:** identify stages only by position and module. This avoids another configuration field, but positional references in reports and diagnostics change when stages are reordered. In either case, retain ordered execution and repeated modules rather than treating the pipeline as a set. The capability and its inclusion in the next major release are settled. These questions refine the design; they do not reopen whether to deliver the feature.