From 3da97ca50cf412181abdc8736a6143c3e8e5dc7d Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 30 Aug 2026 15:26:23 +0000 Subject: [PATCH] Add assembled pipeline configuration regression coverage --- docs/roadmap/implementation.md | 2 +- internal/app/assembled_workflow_test.go | 185 ++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 1 deletion(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index d21db9c..a2b6b43 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1185,7 +1185,7 @@ describe the completed feature once, at the correct canonical owners. ## Stage 22 — Assembled Workflow Regression And Final Validation -**Status: Pending** +**Status: Completed** ### Goal diff --git a/internal/app/assembled_workflow_test.go b/internal/app/assembled_workflow_test.go index b9d9175..a4076c5 100644 --- a/internal/app/assembled_workflow_test.go +++ b/internal/app/assembled_workflow_test.go @@ -3,8 +3,11 @@ package app import ( "bytes" "context" + "io" + "os" "path/filepath" "reflect" + "strings" "testing" "time" @@ -271,6 +274,188 @@ func TestAssembledLegacyAnalyzeTransitionPublishesOnlyCurrentRecords(t *testing. } } +func TestAssembledSplitBundleCommandsUseOneEffectiveFamilyConfiguration(t *testing.T) { + pipelinePath, campaignPath, sessionPath := assembledSplitBundlePaths() + workspacePath := filepath.Join(filepath.Dir(pipelinePath), "workspace") + if _, err := os.Stat(workspacePath); !os.IsNotExist(err) { + t.Fatalf("example workspace stat = %v, want absent", err) + } + + var validated bytes.Buffer + if err := ConfigValidate(context.Background(), []string{"--config", pipelinePath, "--campaign-file", campaignPath}, &validated); err != nil { + t.Fatalf("validate production default: %v", err) + } + if !strings.Contains(validated.String(), "profile=production") { + t.Fatalf("validate output = %q, want production profile", validated.String()) + } + for _, command := range []func(context.Context, []string, io.Writer) error{ConfigShow, ConfigSources} { + if err := command(context.Background(), []string{ + "--config", pipelinePath, "--campaign-file", campaignPath, "--profile", "testing", + }, io.Discard); err != nil { + t.Fatalf("testing inspection command %T: %v", command, err) + } + } + var diff bytes.Buffer + if err := ConfigDiff(context.Background(), []string{ + "production", "testing", "--config", pipelinePath, "--campaign-file", campaignPath, + }, &diff); err != nil { + t.Fatalf("compare profiles: %v", err) + } + if !strings.Contains(diff.String(), "audita.model") || !strings.Contains(diff.String(), "character_items_arannis.profile_id") { + t.Fatalf("profile diff = %q, want model and expanded family changes", diff.String()) + } + + common := []string{ + "2026-05-03", "--config", pipelinePath, "--campaign-file", campaignPath, + "--session", sessionPath, "--profile", "testing", + } + var planned bytes.Buffer + if err := Plan(context.Background(), common, &planned); err != nil { + t.Fatalf("plan testing bundle: %v", err) + } + if !strings.Contains(planned.String(), "profile=testing") { + t.Fatalf("plan output = %q, want testing provenance", planned.String()) + } + + original := executeStagesFn + t.Cleanup(func() { executeStagesFn = original }) + var capturedCfg *config.Config + var capturedPlan BoundedPlan + var capturedOptions RunOptions + executeStagesFn = func(_ context.Context, cfg *config.Config, plan BoundedPlan, options RunOptions) (*RunSummary, error) { + capturedCfg = cfg + capturedPlan = plan + capturedOptions = options + return &RunSummary{SessionID: cfg.Session.SessionID, ManifestPath: manifestPathForConfig(cfg.Pipeline.Workspace.Root)}, nil + } + runArgs := append(append([]string(nil), common...), "--from", "analyze", "--through", "analyze", "--artifacts", "character_items_arannis") + var runOut bytes.Buffer + if err := Run(context.Background(), runArgs, &runOut); err != nil { + t.Fatalf("bounded family run: %v", err) + } + if !reflect.DeepEqual(capturedPlan.Names(), []string{"analyze"}) { + t.Fatalf("bounded plan = %#v, want analyze only", capturedPlan.Names()) + } + if profile, ok := config.SelectedPipelineProfile(capturedCfg.Pipeline); !ok || profile.Name != "testing" { + t.Fatalf("captured profile = %#v, selected=%t", profile, ok) + } + if digest := config.EffectivePipelineDigest(capturedCfg.Pipeline); digest == "" || !strings.Contains(runOut.String(), "digest="+digest) { + t.Fatalf("run output = %q, want effective digest %q", runOut.String(), digest) + } + if got := capturedOptions.EffectiveArtifacts.Keys(); !reflect.DeepEqual(got, []string{"character_items_arannis"}) { + t.Fatalf("effective artifact keys = %#v", got) + } + if origin, ok := capturedOptions.EffectiveArtifacts.Origin("character_items_arannis"); !ok || origin.Family != "character_items" || origin.CharacterID != "arannis" { + t.Fatalf("family origin = %#v, present=%t", origin, ok) + } + fullFamily, err := resolveEffectiveArtifacts(capturedCfg, []string{"character_items"}) + if err != nil { + t.Fatalf("resolve complete family: %v", err) + } + if got := fullFamily.Keys(); !reflect.DeepEqual(got, []string{"character_items_arannis", "character_items_brenna"}) { + t.Fatalf("full family keys = %#v", got) + } + if _, err := os.Stat(workspacePath); !os.IsNotExist(err) { + t.Fatalf("inspection or bounded run created example workspace: %v", err) + } +} + +func TestAssembledSplitBundleProfileSwitchRecordsProvenanceAndLimitsReuse(t *testing.T) { + production := loadAssembledSplitBundleConfig(t, "") + testingCfg := loadAssembledSplitBundleConfig(t, "testing") + workspace := t.TempDir() + production.Pipeline.Workspace.Root = workspace + testingCfg.Pipeline.Workspace.Root = workspace + + names := []string{"prepare", "transcribe", "merge", "polish", "normalize", "trim", "render"} + providers := make([]stage.SemanticConfigFingerprinter, len(names)) + seed := manifest.New(production.Session.SessionID, time.Now().UTC()) + seed.Campaign = production.Session.Campaign + for _, candidate := range stage.All() { + seed.MarkStageSucceeded(candidate.Name(), time.Now().UTC(), nil) + } + for index, name := range names { + providers[index] = canonicalSemanticProvider(t, name) + fingerprint, err := providers[index].SemanticConfigFingerprint(&stage.Env{Config: production}) + if err != nil { + t.Fatalf("production %s fingerprint: %v", name, err) + } + seed.Stages[name].SemanticConfig = &fingerprint + } + store := &manifest.LocalStore{} + if err := store.Save(context.Background(), manifestPathForConfig(workspace), seed); err != nil { + t.Fatal(err) + } + + productionRuns := make([]int, len(names)) + productionStages := assembledSemanticStages(names, providers, productionRuns) + productionSummary, err := executeStages(context.Background(), production, productionStages, RunOptions{}) + if err != nil { + t.Fatalf("record production provenance: %v", err) + } + if !reflect.DeepEqual(productionRuns, make([]int, len(names))) { + t.Fatalf("production runs = %v, want complete reuse", productionRuns) + } + assertAssembledProvenance(t, store, productionSummary, "production", config.EffectivePipelineDigest(production.Pipeline)) + + testingRuns := make([]int, len(names)) + testingStages := assembledSemanticStages(names, providers, testingRuns) + testingSummary, err := executeStages(context.Background(), testingCfg, testingStages, RunOptions{}) + if err != nil { + t.Fatalf("switch to testing profile: %v", err) + } + if got, want := testingRuns, []int{0, 0, 0, 1, 1, 1, 1}; !reflect.DeepEqual(got, want) { + t.Fatalf("testing profile runs = %v, want %v", got, want) + } + assertAssembledProvenance(t, store, testingSummary, "testing", config.EffectivePipelineDigest(testingCfg.Pipeline)) +} + +func assembledSplitBundlePaths() (pipelinePath, campaignPath, sessionPath string) { + examplesDir := filepath.Join("..", "..", "examples") + return filepath.Join(examplesDir, "production-testing", "pipeline.yml"), + filepath.Join(examplesDir, "campaigns", "sample-campaign", "campaign.yml"), + filepath.Join(examplesDir, "session.local-audio.yml") +} + +func loadAssembledSplitBundleConfig(t *testing.T, profile string) *config.Config { + t.Helper() + pipelinePath, campaignPath, sessionPath := assembledSplitBundlePaths() + options := config.SessionLoadOptions{} + if profile != "" { + options.Profile = &profile + } + cfg, err := config.LoadWithSessionOptions(pipelinePath, campaignPath, sessionPath, options) + if err != nil { + t.Fatalf("load split bundle profile %q: %v", profile, err) + } + return cfg +} + +func assembledSemanticStages(names []string, providers []stage.SemanticConfigFingerprinter, runs []int) []stage.Stage { + stages := make([]stage.Stage, 0, len(names)) + for index, name := range names { + stages = append(stages, semanticContractRunStub{name: name, provider: providers[index], runs: &runs[index]}) + } + return stages +} + +func assertAssembledProvenance(t *testing.T, store *manifest.LocalStore, summary *RunSummary, profile, digest string) { + t.Helper() + session, err := store.Load(context.Background(), summary.ManifestPath) + if err != nil { + t.Fatal(err) + } + run, err := store.LoadRun(context.Background(), summary.RunManifestPath) + if err != nil { + t.Fatal(err) + } + for _, value := range []*manifest.EffectiveConfigProvenance{session.EffectiveConfig, run.EffectiveConfig} { + if value == nil || value.SelectedProfile == nil || value.SelectedProfile.Name != profile || value.EffectiveConfigDigest != digest { + t.Fatalf("effective configuration provenance = %#v, want profile=%q digest=%q", value, profile, digest) + } + } +} + func seedAllStagesSucceeded(t *testing.T, cfg *config.Config) { t.Helper() m := manifest.New(cfg.Session.SessionID, time.Now().UTC())