Adopt Notarius configuration overlays
This commit is contained in:
@@ -146,7 +146,7 @@ func (extractStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (re
|
||||
chunkCache = "refresh"
|
||||
}
|
||||
request := notarius.RunRequest{
|
||||
Binary: resolvedBinary, Credentials: notariusConfig.Credentials, ConfigProfile: notariusConfig.ConfigProfile,
|
||||
Binary: resolvedBinary, Credentials: notariusConfig.Credentials, ConfigOverlay: notariusConfig.ConfigOverlay,
|
||||
ConfigPath: configPath, PipelineID: notariusConfig.PipelineID,
|
||||
InputPath: inputPath, OutputRoot: outputRoot, WorkingDirectory: workingDirectory,
|
||||
ReceiptPath: receiptPath, LogPath: logPath, Timeout: timeout, Resume: resume, ChunkCache: chunkCache, References: referenceBindings,
|
||||
@@ -451,7 +451,7 @@ type fingerprintOutput struct {
|
||||
|
||||
type fingerprintDocument struct {
|
||||
PipelineID string `json:"pipeline_id"`
|
||||
ConfigProfile string `json:"config_profile,omitempty"`
|
||||
ConfigOverlay string `json:"config_overlay,omitempty"`
|
||||
Input artifacts.ExtractionInputIdentity `json:"input"`
|
||||
References []extractReferenceIdentity `json:"references"`
|
||||
Outputs []fingerprintOutput `json:"outputs"`
|
||||
@@ -486,7 +486,7 @@ func extractionFingerprint(
|
||||
return sortedReferences[i].Path < sortedReferences[j].Path
|
||||
})
|
||||
payload, err := json.Marshal(fingerprintDocument{
|
||||
PipelineID: cfg.PipelineID, ConfigProfile: notariusConfigProfileReuseIdentity(cfg.ConfigProfile),
|
||||
PipelineID: cfg.PipelineID, ConfigOverlay: notariusConfigOverlayReuseIdentity(cfg.ConfigOverlay),
|
||||
Input: input, References: sortedReferences, Outputs: outputs,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -72,8 +72,8 @@ notarius:
|
||||
|
||||
env, m, fake := setupExtractEnv(t)
|
||||
env.Config.Pipeline.Notarius.Credentials = loadedPipeline.Notarius.Credentials
|
||||
configProfile := "inexpensive"
|
||||
env.Config.Pipeline.Notarius.ConfigProfile = &configProfile
|
||||
configOverlay := "inexpensive"
|
||||
env.Config.Pipeline.Notarius.ConfigOverlay = &configOverlay
|
||||
result, err := (extractStage{}).Run(context.Background(), env, m)
|
||||
if err != nil {
|
||||
t.Fatalf("Run() error = %v", err)
|
||||
@@ -106,8 +106,8 @@ notarius:
|
||||
if len(req.Credentials) != 1 || req.Credentials[0].EnvName() != credentialName || !req.Credentials[0].IsResolved() {
|
||||
t.Fatal("request did not retain the loaded Notarius credential reference")
|
||||
}
|
||||
if req.ConfigProfile == nil || *req.ConfigProfile != configProfile {
|
||||
t.Fatalf("request config profile = %#v, want %q", req.ConfigProfile, configProfile)
|
||||
if req.ConfigOverlay == nil || *req.ConfigOverlay != configOverlay {
|
||||
t.Fatalf("request config overlay = %#v, want %q", req.ConfigOverlay, configOverlay)
|
||||
}
|
||||
if result.Metadata["reference_count"] != 0 || len(result.Metadata["references"].([]map[string]any)) != 0 {
|
||||
t.Fatalf("reference metadata = count %#v references %#v", result.Metadata["reference_count"], result.Metadata["references"])
|
||||
@@ -141,8 +141,8 @@ func TestExtractStageAppliesNotariusCacheControlsAndForcePrecedence(t *testing.T
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
env, m, fake := setupExtractEnv(t)
|
||||
configProfile := "inexpensive"
|
||||
env.Config.Pipeline.Notarius.ConfigProfile = &configProfile
|
||||
configOverlay := "inexpensive"
|
||||
env.Config.Pipeline.Notarius.ConfigOverlay = &configOverlay
|
||||
env.Config.Pipeline.Notarius.Resume = test.configuredResume
|
||||
env.Config.Pipeline.Notarius.ChunkCache = test.configuredMode
|
||||
env.Force = test.force
|
||||
@@ -157,8 +157,8 @@ func TestExtractStageAppliesNotariusCacheControlsAndForcePrecedence(t *testing.T
|
||||
if request.Resume != test.wantResume || request.ChunkCache != test.wantMode {
|
||||
t.Fatalf("cache controls = resume %v, mode %q; want resume %v, mode %q", request.Resume, request.ChunkCache, test.wantResume, test.wantMode)
|
||||
}
|
||||
if request.ConfigProfile == nil || *request.ConfigProfile != configProfile {
|
||||
t.Fatalf("config profile = %#v, want %q", request.ConfigProfile, configProfile)
|
||||
if request.ConfigOverlay == nil || *request.ConfigOverlay != configOverlay {
|
||||
t.Fatalf("config overlay = %#v, want %q", request.ConfigOverlay, configOverlay)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1018,7 +1018,7 @@ func TestExtractionFingerprintBaseSelectorsPreservePriorPayloadShape(t *testing.
|
||||
legacyDigest := sha256.Sum256(legacyPayload)
|
||||
want := hex.EncodeToString(legacyDigest[:])
|
||||
for _, profile := range []*string{nil, stringPointerForExtractTest(""), stringPointerForExtractTest("default")} {
|
||||
cfg.ConfigProfile = profile
|
||||
cfg.ConfigOverlay = profile
|
||||
got, err := extractionFingerprint(cfg, input, references)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1027,7 +1027,7 @@ func TestExtractionFingerprintBaseSelectorsPreservePriorPayloadShape(t *testing.
|
||||
t.Fatalf("base selection fingerprint = %q, want prior no-profile payload digest %q", got, want)
|
||||
}
|
||||
}
|
||||
cfg.ConfigProfile = stringPointerForExtractTest("inexpensive")
|
||||
cfg.ConfigOverlay = stringPointerForExtractTest("inexpensive")
|
||||
named, err := extractionFingerprint(cfg, input, references)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1055,10 +1055,10 @@ func TestExtractStageResumeValidationAcceptsCurrentImmutableResult(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractStageResumeValidationTracksConfigProfile(t *testing.T) {
|
||||
func TestExtractStageResumeValidationTracksConfigOverlay(t *testing.T) {
|
||||
env, m, _ := setupExtractEnv(t)
|
||||
selected := "inexpensive"
|
||||
env.Config.Pipeline.Notarius.ConfigProfile = &selected
|
||||
env.Config.Pipeline.Notarius.ConfigOverlay = &selected
|
||||
seedSucceededExtractResult(t, env, m)
|
||||
|
||||
validation, err := (extractStage{}).ValidateResume(context.Background(), env, m)
|
||||
@@ -1070,7 +1070,7 @@ func TestExtractStageResumeValidationTracksConfigProfile(t *testing.T) {
|
||||
}
|
||||
|
||||
changed := "experimental"
|
||||
env.Config.Pipeline.Notarius.ConfigProfile = &changed
|
||||
env.Config.Pipeline.Notarius.ConfigOverlay = &changed
|
||||
validation, err = (extractStage{}).ValidateResume(context.Background(), env, m)
|
||||
if err != nil {
|
||||
t.Fatalf("ValidateResume(changed selection) error = %v", err)
|
||||
|
||||
@@ -27,7 +27,7 @@ const notariusIntegrationBinaryEnv = "NARRATIO_TEST_NOTARIUS_BINARY"
|
||||
func TestNotariusCacheReuseIntegration(t *testing.T) {
|
||||
binary := strings.TrimSpace(os.Getenv(notariusIntegrationBinaryEnv))
|
||||
if binary == "" {
|
||||
t.Skipf("set %s to an absolute Notarius v0.7.0-compatible executable to run this integration test", notariusIntegrationBinaryEnv)
|
||||
t.Skipf("set %s to an absolute Notarius v0.8.1-compatible executable to run this integration test", notariusIntegrationBinaryEnv)
|
||||
}
|
||||
if !filepath.IsAbs(binary) {
|
||||
t.Fatalf("%s = %q, want an absolute path", notariusIntegrationBinaryEnv, binary)
|
||||
@@ -235,6 +235,16 @@ pipelines:
|
||||
if err := os.WriteFile(configPath, []byte(content), 0o600); err != nil {
|
||||
t.Fatalf("write Notarius integration config: %v", err)
|
||||
}
|
||||
// Select a real downstream overlay. Disable provider retries so the controlled
|
||||
// failure below tests checkpoint recovery rather than transient HTTP recovery.
|
||||
overlay := "integration"
|
||||
overlayDir := filepath.Join(root, "overlays")
|
||||
if err := os.MkdirAll(overlayDir, 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(overlayDir, overlay+".yml"), []byte("promptkit:\n transient_retries: 0\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
transcriptPath := filepath.Join(sessionPathsForEnv(env, runManifest.SessionID).ArtifactsDir, "trimmed.from-manifest.json")
|
||||
setNotariusIntegrationTranscript(t, runManifest, transcriptPath, notariusIntegrationTranscript("session-cache", "Aria casts Cure Wounds."))
|
||||
@@ -242,7 +252,8 @@ pipelines:
|
||||
env.Notarius = notarius.NewSubprocessRunner()
|
||||
env.Config.Pipeline.Notarius = &config.NotariusConfig{
|
||||
Enabled: true, Binary: binary, ConfigPath: configPath, PipelineID: pipelineID,
|
||||
Timeout: "2m", WorkingDirectory: root, ChunkCache: "auto",
|
||||
ConfigOverlay: &overlay,
|
||||
Timeout: "2m", WorkingDirectory: root, ChunkCache: "auto",
|
||||
References: map[string]string{"party": artifactpolicy.SourceInputParty},
|
||||
Outputs: map[string]config.NotariusOutputConfig{
|
||||
"spells_first": {
|
||||
|
||||
@@ -22,16 +22,16 @@ const (
|
||||
type extractSemanticConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
PipelineID string `json:"pipeline_id,omitempty"`
|
||||
ConfigProfile string `json:"config_profile,omitempty"`
|
||||
ConfigOverlay string `json:"config_overlay,omitempty"`
|
||||
References []extractSemanticReference `json:"references"`
|
||||
Outputs []extractSemanticOutput `json:"outputs"`
|
||||
}
|
||||
|
||||
func notariusConfigProfileReuseIdentity(profile *string) string {
|
||||
if profile == nil || *profile == "" || *profile == "default" {
|
||||
func notariusConfigOverlayReuseIdentity(overlay *string) string {
|
||||
if overlay == nil || *overlay == "" || *overlay == "default" {
|
||||
return ""
|
||||
}
|
||||
return *profile
|
||||
return *overlay
|
||||
}
|
||||
|
||||
type extractSemanticReference struct {
|
||||
@@ -85,7 +85,7 @@ func (extractStage) SemanticConfigFingerprint(env *Env) (manifest.SemanticConfig
|
||||
}
|
||||
payload.Enabled = true
|
||||
payload.PipelineID = strings.TrimSpace(cfg.PipelineID)
|
||||
payload.ConfigProfile = notariusConfigProfileReuseIdentity(cfg.ConfigProfile)
|
||||
payload.ConfigOverlay = notariusConfigOverlayReuseIdentity(cfg.ConfigOverlay)
|
||||
for rawSelector, rawSourceID := range cfg.References {
|
||||
selector, err := notariusref.NormalizeSelector(rawSelector)
|
||||
if err != nil {
|
||||
|
||||
@@ -102,7 +102,7 @@ func TestExtractSemanticConfigSensitivityAndOperationalExclusions(t *testing.T)
|
||||
baseFingerprints := make([]manifest.SemanticConfigFingerprint, 0, 3)
|
||||
for _, profile := range []*string{nil, profilePointer(""), profilePointer("default")} {
|
||||
env := downstreamSemanticEnv()
|
||||
env.Config.Pipeline.Notarius.ConfigProfile = profile
|
||||
env.Config.Pipeline.Notarius.ConfigOverlay = profile
|
||||
fingerprint, err := (extractStage{}).SemanticConfigFingerprint(env)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -115,7 +115,7 @@ func TestExtractSemanticConfigSensitivityAndOperationalExclusions(t *testing.T)
|
||||
}
|
||||
}
|
||||
profiled := downstreamSemanticEnv()
|
||||
profiled.Config.Pipeline.Notarius.ConfigProfile = profilePointer("inexpensive")
|
||||
profiled.Config.Pipeline.Notarius.ConfigOverlay = profilePointer("inexpensive")
|
||||
firstProfile, err := (extractStage{}).SemanticConfigFingerprint(profiled)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -130,7 +130,7 @@ func TestExtractSemanticConfigSensitivityAndOperationalExclusions(t *testing.T)
|
||||
if !firstProfile.Equal(unchangedProfile) {
|
||||
t.Fatal("unchanged Notarius selection changed semantic fingerprint")
|
||||
}
|
||||
profiled.Config.Pipeline.Notarius.ConfigProfile = profilePointer("experimental")
|
||||
profiled.Config.Pipeline.Notarius.ConfigOverlay = profilePointer("experimental")
|
||||
secondProfile, err := (extractStage{}).SemanticConfigFingerprint(profiled)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -138,7 +138,7 @@ func TestExtractSemanticConfigSensitivityAndOperationalExclusions(t *testing.T)
|
||||
if firstProfile.Equal(secondProfile) {
|
||||
t.Fatal("named to different named Notarius selection retained semantic fingerprint")
|
||||
}
|
||||
profiled.Config.Pipeline.Notarius.ConfigProfile = nil
|
||||
profiled.Config.Pipeline.Notarius.ConfigOverlay = nil
|
||||
returnedToBase, err := (extractStage{}).SemanticConfigFingerprint(profiled)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -153,7 +153,7 @@ func TestExtractSemanticConfigSensitivityAndOperationalExclusions(t *testing.T)
|
||||
disabledBase.Config.Pipeline.Notarius.Enabled = false
|
||||
disabledNamed := downstreamSemanticEnv()
|
||||
disabledNamed.Config.Pipeline.Notarius.Enabled = false
|
||||
disabledNamed.Config.Pipeline.Notarius.ConfigProfile = profilePointer("ignored")
|
||||
disabledNamed.Config.Pipeline.Notarius.ConfigOverlay = profilePointer("ignored")
|
||||
disabledBaseFingerprint, err := (extractStage{}).SemanticConfigFingerprint(disabledBase)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
Reference in New Issue
Block a user