package config import ( "path/filepath" "strings" ) // NormalizePipelineConfig applies reusable domain canonicalization before // validation. It is deterministic and commits no partial Notarius changes when // canonicalization fails. func NormalizePipelineConfig(cfg *PipelineConfig) error { if cfg == nil || cfg.Notarius == nil || !cfg.Notarius.Enabled { return nil } notarius := *cfg.Notarius notarius.Binary = strings.TrimSpace(notarius.Binary) notarius.ChunkCache = strings.TrimSpace(notarius.ChunkCache) notarius.ConfigPath = cleanNotariusPath(notarius.ConfigPath) notarius.PipelineID = strings.TrimSpace(notarius.PipelineID) notarius.Timeout = strings.TrimSpace(notarius.Timeout) notarius.WorkingDirectory = cleanNotariusPath(notarius.WorkingDirectory) references, err := normalizeNotariusReferences(notarius.References) if err != nil { return err } outputs, err := normalizeNotariusOutputs(notarius.Outputs) if err != nil { return err } notarius.References = references notarius.Outputs = outputs *cfg.Notarius = notarius return nil } func cleanNotariusPath(value string) string { value = strings.TrimSpace(value) if value == "" { return "" } return filepath.Clean(value) }