From 1b76a426cc8b69edb2d3129cbf8604d934e5cd21 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 9 Nov 2026 02:45:50 +0000 Subject: [PATCH] Resolve collection-scoped glossary entry identities --- docs/roadmap/configkit.md | 4 +- docs/roadmap/glossary-stages.md | 89 ++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md index 8bc5182..ff47a22 100644 --- a/docs/roadmap/configkit.md +++ b/docs/roadmap/configkit.md @@ -134,8 +134,10 @@ file remain terminal. retaining native discovery, source context, and tier semantics. Supply its [optional default glossary sources](glossary-stages.md#default-sources-and-explicit-configuration--resolved) in one underlay, with higher-priority explicit main configuration. + Register its [collection-scoped entry IDs](glossary-stages.md#entry-identity--resolved) + through native sequence identity registration. Complete its required durable decision record. The glossary roadmap owns - the remaining entry schema, identity, runtime-view, + the remaining rich-field, runtime-view, selection-input, and attribution decisions. This application scope model does not change native source composition or sibling-inheritance semantics. diff --git a/docs/roadmap/glossary-stages.md b/docs/roadmap/glossary-stages.md index 263a559..a752bcb 100644 --- a/docs/roadmap/glossary-stages.md +++ b/docs/roadmap/glossary-stages.md @@ -4,8 +4,8 @@ **Status:** Accepted feature scope, ownership, and stage-selection semantics for the next Audita major release, including named collections and recursive import -placement and optional default sources. Entry schema, remaining design decisions, -and implementation are pending. The +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 @@ -27,8 +27,8 @@ 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 and their tier are also selected. Entry identity, rich -fields, and remaining selection details are open below. +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 @@ -93,8 +93,8 @@ party: summary: The party's wizard. ``` -The `party`/`entries` nesting is selected. Entry identity and rich fields in this -illustration remain provisional pending the entry-schema decision below. +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 @@ -108,6 +108,36 @@ 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: @@ -142,7 +172,7 @@ 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 -entry identity and collection policy selected below. +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 @@ -240,8 +270,8 @@ 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. -The precise entry-identity and adaptation contracts remain open below; directory -order must never silently choose which definition wins. +Use the selected collection-scoped entry identity when adapting definitions; +directory order must never silently choose which definition wins. ### Derived Runtime Representations — Resolved @@ -395,7 +425,7 @@ 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. -Collection identity, runtime overlap, and payload details remain open below. +Runtime overlap and payload details remain open below. ### Validation-Profile Fallback — Resolved @@ -499,7 +529,9 @@ Use the native [collection and inheritance contracts](https://forge.maximumdirec 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. Decide identity fields and scope below. +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 @@ -638,6 +670,13 @@ 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. @@ -682,22 +721,22 @@ guidance are in place before declaring this feature complete. The recommendations below are proposals, not selected contracts. -### Entry Identity and Rich Fields +### Entry Content Fields -**Recommendation:** use explicit stable entry IDs independent of displayed terms, -with application-registered identity on identified lists. Choose whether identity -is global or scoped by collection and how a shared entry belongs to multiple -collections before fixing the schema. Distinct meanings can then share a spelling -without being the same record. Retain rich semantic fields for model context; -settle their names and required/optional status, including the relationship of -current `summary` to optional comment/context data. Explicit IDs add authoring -work and require clear identity scope, but survive changes to displayed terms. +**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:** use a natural key such as term plus category, or a keyed mapping -whose keys provide identity. This can reduce record ceremony and fits native -ConfigKit mechanisms, but natural keys can conflate meanings and change on rename; -mapping keys still need an intentional identity convention. Do not silently -infer semantic identity from matching text or inherit first-match lookup behavior. +**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