Avoid repeated glossary selection and membership work

This commit is contained in:
2026-11-10 20:39:00 +00:00
parent 1fd95abe95
commit 8ad27e8368
6 changed files with 39 additions and 22 deletions

View File

@@ -1,6 +1,10 @@
package config
import ck "go.maximumdirect.net/configkit"
import (
"slices"
ck "go.maximumdirect.net/configkit"
)
func cloneSelection(value *string) *string {
if value == nil {
@@ -10,26 +14,25 @@ func cloneSelection(value *string) *string {
return &copied
}
func cloneNames(value []string) []string {
if value == nil {
return nil
func defaultNames(r *ck.Resolution, path ck.Path, target *[]string, inherited []string, reason string, source ck.Path) {
if !r.IsExplicit(path) {
ck.Default(r, path, target, slices.Clone(inherited), reason, source)
}
return append([]string{}, value...)
}
// resolveSettings records root-derived defaults after all explicit assignments.
func resolveSettings(c *Config, r *ck.Resolution) error {
glossaries := ck.Keys("glossaries")
protection := ck.Keys("protected_terms")
ck.Default(r, protection, &c.ProtectedTerms, cloneNames(c.Glossaries), "protection defaults to selected glossaries", glossaries)
defaultNames(r, protection, &c.ProtectedTerms, c.Glossaries, "protection defaults to selected glossaries", glossaries)
rootValidation := ck.Keys("llm", "validation_profile")
rootValidationInfo, _ := r.EntryInfo(rootValidation)
inheritedValidation := r.IsExplicit(rootValidation) && !rootValidationInfo.Null && c.LLM.ValidationProfile != nil
for i := range c.Pipeline.Stages {
item := &c.Pipeline.Stages[i]
base := ck.Keys("pipeline", "stages").Index(i)
ck.Default(r, base.Key("glossaries"), &item.Glossaries, cloneNames(c.Glossaries), "inherit root glossaries", glossaries)
ck.Default(r, base.Key("protected_terms"), &item.ProtectedTerms, cloneNames(c.ProtectedTerms), "inherit root protection", protection)
defaultNames(r, base.Key("glossaries"), &item.Glossaries, c.Glossaries, "inherit root glossaries", glossaries)
defaultNames(r, base.Key("protected_terms"), &item.ProtectedTerms, c.ProtectedTerms, "inherit root protection", protection)
threshold := ck.Keys("thresholds", item.Module)
var value float64
switch item.Module {

View File

@@ -18,9 +18,14 @@ type identity struct{ collection, id string }
// Select retains the first occurrence of each selected collection entry.
func Select(collections map[string]config.GlossaryCollection, names []string) []Entry {
visited := make(map[string]struct{})
seen := make(map[identity]struct{})
var selected []Entry
for _, name := range names {
if _, exists := visited[name]; exists {
continue
}
visited[name] = struct{}{}
for _, item := range collections[name].Entries {
key := identity{collection: name, id: item.ID}
if _, exists := seen[key]; exists {

View File

@@ -29,6 +29,11 @@ func Vocabulary(entries, excluded []Entry) []Term {
}
}
}
type contribution struct {
spelling string
identity Identity
}
seen := make(map[contribution]struct{})
indices := make(map[string]int)
var terms []Term
for _, entry := range entries {
@@ -38,23 +43,18 @@ func Vocabulary(entries, excluded []Entry) []Term {
if _, excluded := exclusions[key]; excluded {
continue
}
member := contribution{spelling: key, identity: id}
if _, exists := seen[member]; exists {
continue
}
seen[member] = struct{}{}
index, exists := indices[key]
if !exists {
index = len(terms)
indices[key] = index
terms = append(terms, Term{Spelling: spelling})
}
identities := terms[index].Identities
found := false
for _, existing := range identities {
if existing == id {
found = true
break
}
}
if !found {
terms[index].Identities = append(identities, id)
}
terms[index].Identities = append(terms[index].Identities, id)
}
}
return append(terms, exempt...)

View File

@@ -10,7 +10,8 @@ func TestVocabularyKeepsContributorsAndExemptsOnlyActiveSpellings(t *testing.T)
active := []Entry{{Collection: "spells", ID: "shield", Name: "Shield", Aliases: []string{"Ward"}}}
protected := []Entry{
active[0],
{Collection: "items", ID: "shield", Name: "shield", Aliases: []string{"Aegis"}, Plural: &plural},
{Collection: "items", ID: "shield", Name: "shield", Aliases: []string{"Aegis", "SHIELD"}, Plural: &plural},
active[0],
}
full := Vocabulary(protected, nil)
if !reflect.DeepEqual(full[0].Identities, []Identity{{Collection: "spells", ID: "shield"}, {Collection: "items", ID: "shield"}}) {

View File

@@ -4,10 +4,10 @@ package preflight
import (
"context"
"fmt"
"slices"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/config"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/diagnostics"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/glossary"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/modulecatalog"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/schema"
)
@@ -105,7 +105,13 @@ func CheckReadiness(ctx context.Context, cfg *config.Config, inspectProfile func
return fmt.Sprintf("stage %d (%s)", index+1, item.Module)
}
for index, item := range cfg.Pipeline.Stages {
if item.Module == modulecatalog.KeyGlossary && len(glossary.Select(cfg.GlossaryCollections, item.Glossaries)) == 0 {
if item.Module != modulecatalog.KeyGlossary {
continue
}
hasEntries := slices.ContainsFunc(item.Glossaries, func(name string) bool {
return len(cfg.GlossaryCollections[name].Entries) > 0
})
if !hasEntries {
return fmt.Errorf("%s has no glossary entries in selected collections %q", label(index, item), item.Glossaries)
}
}