Add Scriptorium configuration contract

This commit is contained in:
2026-05-06 21:12:22 +00:00
parent ce01ca7619
commit 84b0f6fe0e
6 changed files with 344 additions and 1 deletions

View File

@@ -42,6 +42,9 @@ func validatePipeline(cfg *PipelineConfig) error {
if err := validateAudita(cfg.Audita); err != nil {
return err
}
if err := validateScriptorium(cfg.Scriptorium); err != nil {
return err
}
if err := validateDuration("pipeline.analyzer.timeout", cfg.Analyzer.Timeout); err != nil {
return err
}
@@ -170,6 +173,58 @@ func validateAudita(cfg AuditaConfig) error {
return nil
}
func validateScriptorium(cfg *ScriptoriumConfig) error {
if cfg == nil {
return nil
}
if strings.TrimSpace(cfg.Binary) == "" {
return fmt.Errorf("pipeline.scriptorium.binary is required when pipeline.scriptorium is configured")
}
if cfg.ConfigPath != "" && strings.TrimSpace(cfg.ConfigPath) == "" {
return fmt.Errorf("pipeline.scriptorium.config_path must be non-empty when provided")
}
if err := validateDuration("pipeline.scriptorium.timeout", cfg.Timeout); err != nil {
return err
}
for artifactName, artifactCfg := range cfg.Artifacts {
trimmedArtifactName := strings.TrimSpace(artifactName)
if trimmedArtifactName == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts keys must be non-empty")
}
if artifactCfg.Enabled && strings.TrimSpace(artifactCfg.PromptID) == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.prompt_id is required when enabled", artifactName)
}
if artifactCfg.Enabled && strings.TrimSpace(artifactCfg.OutputPath) == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.output_path is required when enabled", artifactName)
}
if err := validateDuration("pipeline.scriptorium.artifacts."+artifactName+".timeout", artifactCfg.Timeout); err != nil {
return err
}
for inputName, inputCfg := range artifactCfg.Inputs {
trimmedInputName := strings.TrimSpace(inputName)
if trimmedInputName == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.inputs keys must be non-empty", artifactName)
}
if strings.TrimSpace(inputCfg.Source) == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.inputs.%s.source is required", artifactName, inputName)
}
}
for varName, varValue := range artifactCfg.Vars {
if strings.TrimSpace(varName) == "" {
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.vars keys must be non-empty", artifactName)
}
switch varValue.(type) {
case bool, string:
default:
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.vars.%s must be a string or boolean", artifactName, varName)
}
}
}
return nil
}
func validateSession(cfg *SessionConfig) error {
if strings.TrimSpace(cfg.SessionID) == "" {
return fmt.Errorf("session.session_id is required")