Document the v2 operator migration

This commit is contained in:
2026-09-07 04:55:13 +00:00
parent 2b97ef3722
commit a4f37ff427
19 changed files with 263 additions and 74 deletions

View File

@@ -253,11 +253,11 @@ func TestAssembledSplitBundleCommandsUseOneEffectiveFamilyConfiguration(t *testi
}
var validated bytes.Buffer
if err := ConfigValidate(context.Background(), []string{"--config", pipelinePath, "--campaign-file", campaignPath, "--profile", "production"}, &validated); err != nil {
t.Fatalf("validate production profile: %v", err)
if err := ConfigValidate(context.Background(), []string{"--config", pipelinePath, "--campaign-file", campaignPath}, &validated); err != nil {
t.Fatalf("validate production base: %v", err)
}
if !strings.Contains(validated.String(), "profile=production") {
t.Fatalf("validate output = %q, want production profile", validated.String())
if !strings.Contains(validated.String(), "profile=none") {
t.Fatalf("validate output = %q, want unprofiled production base", validated.String())
}
for _, command := range []func(context.Context, []string, io.Writer) error{ConfigShow, ConfigSources} {
if err := command(context.Background(), []string{
@@ -268,7 +268,7 @@ func TestAssembledSplitBundleCommandsUseOneEffectiveFamilyConfiguration(t *testi
}
var diff bytes.Buffer
if err := ConfigDiff(context.Background(), []string{
"production", "testing", "--config", pipelinePath, "--campaign-file", campaignPath,
"default", "testing", "--config", pipelinePath, "--campaign-file", campaignPath,
}, &diff); err != nil {
t.Fatalf("compare profiles: %v", err)
}
@@ -330,7 +330,7 @@ func TestAssembledSplitBundleCommandsUseOneEffectiveFamilyConfiguration(t *testi
}
func TestAssembledSplitBundleProfileSwitchRecordsProvenanceAndLimitsReuse(t *testing.T) {
production := loadAssembledSplitBundleConfig(t, "production")
production := loadAssembledSplitBundleConfig(t, "")
testingCfg := loadAssembledSplitBundleConfig(t, "testing")
workspace := t.TempDir()
production.Pipeline.Workspace.Root = workspace
@@ -365,7 +365,7 @@ func TestAssembledSplitBundleProfileSwitchRecordsProvenanceAndLimitsReuse(t *tes
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))
assertAssembledProvenance(t, store, productionSummary, "", config.EffectivePipelineDigest(production.Pipeline))
testingRuns := make([]int, len(names))
testingStages := assembledSemanticStages(names, providers, testingRuns)
@@ -415,7 +415,9 @@ func assertAssembledProvenance(t *testing.T, store *manifest.LocalStore, summary
t.Fatal(err)
}
value := session.EffectiveConfig
if value == nil || value.SelectedProfile == nil || value.SelectedProfile.Name != profile || value.EffectiveConfigDigest != digest {
profileMatches := value != nil && ((profile == "" && value.SelectedProfile == nil) ||
(profile != "" && value.SelectedProfile != nil && value.SelectedProfile.Name == profile))
if !profileMatches || value.EffectiveConfigDigest != digest {
t.Fatalf("effective configuration provenance = %#v, want profile=%q digest=%q", value, profile, digest)
}
}

View File

@@ -370,12 +370,12 @@ func TestConfigCommandsInspectMaintainedSplitBundleWithoutRuntimeState(t *testin
}
for _, command := range []func(context.Context, []string, io.Writer) error{ConfigValidate, ConfigShow, ConfigSources, ConfigArtifacts} {
if err := command(context.Background(), []string{"--config", pipelinePath, "--campaign-file", campaignPath, "--profile", "production"}, io.Discard); err != nil {
if err := command(context.Background(), []string{"--config", pipelinePath, "--campaign-file", campaignPath}, io.Discard); err != nil {
t.Fatalf("inspection command %T error = %v", command, err)
}
}
var diff bytes.Buffer
if err := ConfigDiff(context.Background(), []string{"production", "testing", "--config", pipelinePath, "--campaign-file", campaignPath}, &diff); err != nil {
if err := ConfigDiff(context.Background(), []string{"default", "testing", "--config", pipelinePath, "--campaign-file", campaignPath}, &diff); err != nil {
t.Fatalf("ConfigDiff() error = %v", err)
}
if !strings.Contains(diff.String(), "audita.model") {

View File

@@ -285,15 +285,19 @@ func TestExamplesLoadAndValidate(t *testing.T) {
t.Fatalf("load split bundle campaign: %v", err)
}
for _, profile := range []struct {
name string
model string
name string
selection string
model string
}{
{name: "production", model: "narratio-production-model-placeholder"},
{name: "testing", model: "narratio-testing-model-placeholder"},
{name: "production base", model: "narratio-production-model-placeholder"},
{name: "testing", selection: "testing", model: "narratio-testing-model-placeholder"},
} {
t.Run(profile.name, func(t *testing.T) {
selected := profile.name
pipeline, err := LoadPipelineWithOptions(pipelinePath, PipelineLoadOptions{Profile: &selected})
options := PipelineLoadOptions{}
if profile.selection != "" {
options.Profile = &profile.selection
}
pipeline, err := LoadPipelineWithOptions(pipelinePath, options)
if err != nil {
t.Fatalf("load split bundle pipeline: %v", err)
}
@@ -314,10 +318,16 @@ func TestExamplesLoadAndValidate(t *testing.T) {
if cfg.Pipeline.Audita.LLMAPIKey != nil || cfg.Pipeline.Storage.Backend != StorageBackendLocal || cfg.Pipeline.Storage.S3 != nil {
t.Fatalf("split bundle must remain offline and secret-free: audita=%#v storage=%#v", cfg.Pipeline.Audita, cfg.Pipeline.Storage)
}
if selectedProfile, ok := SelectedPipelineProfile(cfg.Pipeline); !ok || selectedProfile.Name != profile.name {
t.Fatalf("selected profile = %#v, want %q", selectedProfile, profile.name)
selectedProfile, selected := SelectedPipelineProfile(cfg.Pipeline)
if profile.selection == "" && selected {
t.Fatalf("production base unexpectedly selected profile %#v", selectedProfile)
}
if profile.selection != "" && (!selected || selectedProfile.Name != profile.selection) {
t.Fatalf("selected profile = %#v, want %q", selectedProfile, profile.selection)
}
for _, key := range []string{
"session_recap",
"player_handout",
"character_meta_arannis",
"character_meta_brenna",
"character_items_arannis",
@@ -330,6 +340,12 @@ func TestExamplesLoadAndValidate(t *testing.T) {
if got := cfg.Pipeline.Scriptorium.Artifacts["character_items_arannis"].Inputs["character_meta"].Source; got != "narratio.artifact.character_meta_arannis" {
t.Fatalf("same-member input source = %q", got)
}
if got := cfg.Pipeline.Scriptorium.Artifacts["player_handout"].DependsOn; !reflect.DeepEqual(got, []string{"session_recap"}) {
t.Fatalf("input-only artifact dependency = %#v", got)
}
if got := cfg.Pipeline.Scriptorium.Artifacts["character_items_arannis"].DependsOn; !reflect.DeepEqual(got, []string{"character_meta_arannis"}) {
t.Fatalf("family input dependency = %#v", got)
}
if cfg.Party.Canonical == nil || len(cfg.Party.Canonical.Characters) != 2 {
t.Fatalf("canonical party = %#v", cfg.Party)
}
@@ -340,7 +356,18 @@ func TestExamplesLoadAndValidate(t *testing.T) {
if len(cfg.Pipeline.Publish.Outputs) != 3 {
t.Fatalf("publish outputs = %#v, want transcript plus two family outputs", cfg.Pipeline.Publish.Outputs)
}
if profile.name == "testing" {
catalog, err := EffectiveArtifactCatalog(cfg.Pipeline, cfg.Party)
if err != nil {
t.Fatal(err)
}
wantCatalogSize := 6
if profile.selection == "testing" {
wantCatalogSize++
}
if len(catalog) != wantCatalogSize {
t.Fatalf("effective artifact catalog has %d records, want %d", len(catalog), wantCatalogSize)
}
if profile.selection == "testing" {
artifact, exists := cfg.Pipeline.Scriptorium.Artifacts["testing_notes"]
if !exists || artifact.Enabled {
t.Fatalf("testing-only disabled artifact = %#v", artifact)