Add Notarius reference configuration vocabulary
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifactmodel"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/notariusref"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/pathsafe"
|
||||
)
|
||||
|
||||
@@ -39,7 +40,7 @@ func Validate(cfg *Config) error {
|
||||
if err := validateSession(cfg.Session); err != nil {
|
||||
return fmt.Errorf("session config %q invalid: %w", shortName(cfg.SessionPath, "session.yml"), err)
|
||||
}
|
||||
if err := validateCrossConfig(cfg.Pipeline, cfg.Session); err != nil {
|
||||
if err := validateCrossConfig(cfg.Pipeline, cfg.Session, cfg.StableInputs); err != nil {
|
||||
return fmt.Errorf("pipeline/session config invalid: %w", err)
|
||||
}
|
||||
|
||||
@@ -71,6 +72,9 @@ func validateCampaign(cfg *CampaignConfig) error {
|
||||
if strings.TrimSpace(cfg.Inputs.PartyFile) == "" {
|
||||
return fmt.Errorf("campaign.inputs.party_file is required")
|
||||
}
|
||||
if cfg.Inputs.SpellCatalogFile != "" && strings.TrimSpace(cfg.Inputs.SpellCatalogFile) == "" {
|
||||
return fmt.Errorf("campaign.inputs.spell_catalog_file must be non-empty when provided")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -547,6 +551,39 @@ func validateNotarius(cfg *NotariusConfig, scriptorium *ScriptoriumConfig) error
|
||||
if strings.TrimSpace(cfg.WorkingDirectory) == "" {
|
||||
return fmt.Errorf("pipeline.notarius.working_directory is required when pipeline.notarius.enabled is true")
|
||||
}
|
||||
if len(cfg.References) > MaxNotariusReferenceBindings {
|
||||
return fmt.Errorf("pipeline.notarius.references must contain at most %d bindings", MaxNotariusReferenceBindings)
|
||||
}
|
||||
|
||||
referenceKeys := make([]string, 0, len(cfg.References))
|
||||
for selector := range cfg.References {
|
||||
referenceKeys = append(referenceKeys, selector)
|
||||
}
|
||||
sort.Strings(referenceKeys)
|
||||
var normalizedReferences map[string]string
|
||||
if cfg.References != nil {
|
||||
normalizedReferences = make(map[string]string, len(cfg.References))
|
||||
}
|
||||
referenceOwners := make(map[string]string, len(cfg.References))
|
||||
for _, rawSelector := range referenceKeys {
|
||||
selector, err := notariusref.NormalizeSelector(rawSelector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pipeline.notarius.references selector %q is invalid: %w", rawSelector, err)
|
||||
}
|
||||
if previous, ok := referenceOwners[selector]; ok {
|
||||
return fmt.Errorf("pipeline.notarius.references selectors %q and %q normalize to %q", previous, rawSelector, selector)
|
||||
}
|
||||
referenceOwners[selector] = rawSelector
|
||||
|
||||
source := strings.TrimSpace(cfg.References[rawSelector])
|
||||
if source == "" {
|
||||
return fmt.Errorf("pipeline.notarius.references.%s source is required", selector)
|
||||
}
|
||||
if _, ok := artifactpolicy.DescribePreparedInputSource(source); !ok {
|
||||
return fmt.Errorf("pipeline.notarius.references.%s source %q is not a supported prepared input source", selector, source)
|
||||
}
|
||||
normalizedReferences[selector] = source
|
||||
}
|
||||
|
||||
reservedSources := map[string]string{}
|
||||
for _, spec := range artifactmodel.RuntimeTranscriptArtifacts() {
|
||||
@@ -613,6 +650,7 @@ func validateNotarius(cfg *NotariusConfig, scriptorium *ScriptoriumConfig) error
|
||||
cfg.PipelineID = strings.TrimSpace(cfg.PipelineID)
|
||||
cfg.Timeout = strings.TrimSpace(cfg.Timeout)
|
||||
cfg.WorkingDirectory = filepath.Clean(cfg.WorkingDirectory)
|
||||
cfg.References = normalizedReferences
|
||||
cfg.Outputs = normalizedOutputs
|
||||
return nil
|
||||
}
|
||||
@@ -762,6 +800,9 @@ func validateSession(cfg *SessionConfig) error {
|
||||
if strings.TrimSpace(cfg.Inputs.PartyFile) == "" {
|
||||
return fmt.Errorf("session.inputs.party_file is required")
|
||||
}
|
||||
if cfg.Inputs.SpellCatalogFile != "" && strings.TrimSpace(cfg.Inputs.SpellCatalogFile) == "" {
|
||||
return fmt.Errorf("session.inputs.spell_catalog_file must be non-empty when provided")
|
||||
}
|
||||
|
||||
hasAudioDir := strings.TrimSpace(cfg.Inputs.AudioDir) != ""
|
||||
hasAudioFiles := len(cfg.Inputs.AudioFiles) > 0
|
||||
@@ -797,10 +838,17 @@ func validateSessionIdentifier(fieldName, value string, required bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateCrossConfig(pipeline *PipelineConfig, session *SessionConfig) error {
|
||||
func validateCrossConfig(pipeline *PipelineConfig, session *SessionConfig, stableInputs ResolvedStableInputs) error {
|
||||
if pipeline == nil || session == nil {
|
||||
return nil
|
||||
}
|
||||
if pipeline.Notarius != nil && pipeline.Notarius.Enabled {
|
||||
for selector, source := range pipeline.Notarius.References {
|
||||
if source == artifactpolicy.SourceInputSpellCatalog && strings.TrimSpace(stableInputs.SpellCatalogFile.Path) == "" {
|
||||
return fmt.Errorf("pipeline.notarius.references.%s requires campaign.inputs.spell_catalog_file or session.inputs.spell_catalog_file", selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
audioS3Enabled := session.Inputs.AudioS3 != nil
|
||||
publishUploadEnabled := publishUploadConfiguredForS3(pipeline)
|
||||
|
||||
Reference in New Issue
Block a user