Plan separate glossary and protection lists with root defaulting

This commit is contained in:
2026-11-08 16:11:32 +00:00
parent 760a7cecc0
commit 4019f57eaa
2 changed files with 153 additions and 49 deletions

View File

@@ -124,8 +124,10 @@ file remain terminal.
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),
together with its [CLI precedence and native-support boundary](glossary-stages.md#cli-overrides-and-stage-precedence--resolved).
Use its [separate glossary and protection selections](glossary-stages.md#glossary-selection-and-protected-vocabulary--resolved),
including root protection defaulting through recorded application resolution.
Complete its required durable decision record. The glossary roadmap owns
the remaining path and attribution decisions. This
the remaining path, list-input, combined-entry, and attribution decisions. This
application scope model does not change native source composition or
sibling-inheritance semantics.

View File

@@ -15,7 +15,7 @@ but does not select a different glossary input for each occurrence.
Allow operators to run ordered glossary stages against different glossary inputs
within one processing run. For a D&D transcript, the first glossary stage can
use `party.yml` and the second can use `spells.yml`. Each stage uses its selected
glossary and processes the transcript resulting from earlier stages. Operators
glossaries and processes the transcript resulting from earlier stages. Operators
need not combine those inputs into one glossary or run Audita separately for
each pass.
@@ -34,12 +34,17 @@ separate variable-substitution language. The selected glossary configuration is:
```yaml
version: 3
glossary: party.yml
glossaries:
- party.yml
- spells.yml
pipeline:
stages:
- module: glossary
glossaries:
- party.yml
- module: glossary
glossary: spells.yml
glossaries:
- spells.yml
- module: grammar
```
@@ -49,12 +54,13 @@ Preserve meaningful false, zero, and empty values under each setting's validatio
rules rather than treating them as omission. A stage override does not alter
the root settings or the defaults seen by later stages.
In this example, the first glossary stage uses `party.yml`, the second uses
`spells.yml`, and grammar inherits `party.yml` wherever it or its validators
consume the glossary. Transcript changes carry forward between stages;
configuration overrides do not. A stage's module and associated validators
receive its effective stage settings consistently. Whether protected vocabulary
needs a broader selection remains an open domain decision below.
In this example, the first glossary stage uses `party.yml` as its correction
input, the second uses `spells.yml`, and grammar inherits both glossary inputs.
All three stages inherit protection from both files through the root default
described below. Transcript changes carry forward between stages; configuration
overrides do not. Each consumer receives the appropriate selection from the
stage's effective settings, keeping correction/context inputs and protection
inputs distinct.
Apply this model to settings governing stage processing. Invocation-wide
concerns such as configuration discovery, output destinations, and reporting
@@ -74,7 +80,8 @@ must preserve these scope decisions.
| Setting | Scope and rationale |
| --- | --- |
| Glossary input | Stage: vocabulary supplied to the module and its validators. |
| `glossaries` | Stage: ordered glossary files supplying correction and context vocabulary. |
| `protected_terms` | Stage: independently selected glossary files supplying protected vocabulary; defaults from root `glossaries` before stage inheritance. |
| 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. |
@@ -98,6 +105,54 @@ 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
Use `glossaries` at the root and on stages for an ordered sequence of glossary
file paths, including when only one file is selected. Combine the entries from
the selected files in declared order for the stage's glossary input. A glossary
module stage without an override receives the combined root selection; an
explicit stage list selects the files for a focused pass. Paths are direct file
selections, with no named catalog or variable-reference language.
Use `protected_terms` at both scopes for a separate ordered sequence of glossary
file paths, not literal term strings. Its entries supply the protected vocabulary.
Each list specifies the complete selection and replaces the inherited list;
`protected_terms` is not an additive list of extra glossaries. Do not implicitly
union it with correction inputs or with files selected by other stages.
Resolve these settings in this order:
1. Load 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.
Protection therefore defaults at the root before stage inheritance. It does not
fall back to a focused stage's glossary list. In the example above, no operator
protection configuration is needed:
| Stage | Glossary input | Protected vocabulary |
| --- | --- | --- |
| Party glossary pass | Party | Party + spells |
| Spell glossary pass | Spells | Party + spells |
| Grammar | Party + spells | Party + spells |
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 protection.
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.
Protection must retain module-appropriate allowances for legitimate glossary
corrections and spoken-word cleanup. Carry both selections through execution and
validation rather than passing a single combined glossary to every consumer.
Combined-entry conflicts and overlapping protected identities remain open below.
### Validation-Profile Fallback — Resolved
Combine root and stage selections, including explicit clearing, before deriving
@@ -125,15 +180,18 @@ 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.
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. |
| `glossary: null` | Clear the inherited glossary selection. |
| `glossary: ""` | Error: an empty string is not a valid glossary path. |
| `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. |
| Empty file-path entry in either list | 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. |
@@ -141,10 +199,11 @@ 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. 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.
settings groups are not nullable. The glossary settings are sequences with `[]`
as their explicit-clearing form; list-null handling remains open below.
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.
@@ -161,12 +220,15 @@ values and clearing remain authoritative for that stage. Apply validation-profil
fallback after combining these selections. This preserves deliberate differences
between stages while allowing invocation-specific changes to their defaults.
For the pipeline example above, `--glossary revised-party.yml` changes the
effective glossary for the first glossary stage and the grammar stage to
`revised-party.yml`; the second glossary stage still uses `spells.yml`. A stage
with `glossary: null` remains cleared. 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
For the pipeline example above, a CLI assignment replacing root `glossaries`
with `[revised-party.yml, spells.yml]` 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
@@ -196,6 +258,19 @@ in `Definition.Resolve`, using `Resolution.IsExplicit` for presence and
`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
@@ -234,12 +309,13 @@ 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, compound-value, clearing, CLI precedence, and
validation-profile fallback rules. Finalize path resolution. Incorporate
1. Apply the selected scope, glossary/protection selection, compound-value,
clearing, CLI precedence, and validation-profile fallback rules. Finalize path
resolution and remaining list-input details. 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
loading and settle the protected-vocabulary behavior for all consumers.
proposal generation, and validation. Load correction/context and protection
selections separately and settle combined-entry and identity conflicts.
3. Make repeated stages and their selected inputs understandable in inspection,
diagnostics, and reports. Account for all consumed glossary files in input
handling and output-collision protection.
@@ -251,17 +327,22 @@ into feature implementation.
## Acceptance Direction
Use distinct party and spell fixtures with controlled model responses to show
that each stage receives the intended glossary, that one stage's input does not
leak into another, 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
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 the root glossary. Verify that each
stage's module and validators receive consistent effective settings, including
their recorded source origins. Cover repeated modules and an empty stage list.
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 file 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.
Exercise the selected request and validation overrides through stage consumers,
including independent budgets without changing shared backend admission or the
@@ -276,6 +357,10 @@ 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 files, including
legitimate corrections and cleanup; test the selected overlap/conflict behavior.
Confirm that the durable policy, configuration contracts, and contributor
guidance are in place before declaring this feature complete.
@@ -287,28 +372,45 @@ The recommendations below are proposals, not selected contracts.
**Recommendation:** use ConfigKit's supported source context to resolve a
configuration path relative to the document supplying that value, and resolve
CLI paths relative to the working directory. A stage inheriting a root glossary
also inherits that value's source context. This supports reusable imported
configuration; verify the native facilities before selecting implementation.
CLI paths relative to the working directory. Each inherited glossary or protection
path retains its source context, including protection derived from root glossary
paths. This supports reusable imported configuration; verify the native
facilities before selecting implementation.
**Alternative:** resolve all relative glossary paths from the working directory.
This has one simple base and suits invocation-local inputs, but makes reusable
configuration dependent on where Audita is launched. Decide the base explicitly
for no-main-file operation as well.
### Glossary Selection and Protected Vocabulary
### Combined Entries and Protected Identities
**Recommendation:** start from each stage's effective glossary for its module
and validators, with no implicit carryover or union of other stage inputs. This
matches the selected scope model and keeps each stage understandable in isolation.
Review whether protecting terms corrected by earlier stages requires a separate,
explicit protected-vocabulary selection; overlapping terms need deliberate rules.
**Recommendation:** preserve declared file and entry order, coalesce identical
entries, and diagnose conflicting definitions rather than silently choosing by
file order. Define identity handling for overlapping names, aliases, and plurals
across the correction and protection selections, including legitimate glossary
corrections. This keeps protection explainable but requires distinguishing true
conflicts from harmless repetition or legitimate shared spellings.
**Alternative:** protect vocabulary from all configured glossary inputs while
using the effective stage glossary for proposal generation. This could preserve
party names during later spell or grammar work, but makes stage behavior depend
on other stages' inputs and requires conflict and overlap semantics. Ordinary
input selection alone does not decide this protection policy.
**Alternative:** use documented ordered precedence for conflicting entries. This
supports intentional local overrides and is straightforward to apply, but can
hide disagreements and make protection depend on list order. Neither approach
should accidentally inherit the existing single-glossary lookup's first-match
behavior as a new multi-file contract.
### 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 supplying each complete root list using native
ConfigKit overrides.
**Alternative:** reject null for the two glossary-file 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