Derive family member publish destinations

This commit is contained in:
2026-09-07 11:52:57 +00:00
parent f7a40afc7a
commit 884a62e8a6
5 changed files with 342 additions and 14 deletions

View File

@@ -334,6 +334,82 @@ func TestFamilyPublishRulesExpandToConcreteArtifacts(t *testing.T) {
}
}
func TestExplicitFamilyMemberPublishDestinationResolution(t *testing.T) {
dir := t.TempDir()
writePartyResolutionFile(t, filepath.Join(dir, "party.yml"), `schema_version: narratio.party.v1
characters:
alice:
player: {name: Alice Player}
character:
name: Alice
classes: [{name: wizard}]
`)
for _, test := range []struct {
name string
source string
dest string
wantDest string
wantErr string
}{
{
name: "derive generated member output",
source: "narratio.artifact.meta_alice",
wantDest: "artifacts/alice.md",
},
{
name: "preserve explicit override",
source: "narratio.artifact.meta_alice",
dest: "published/alice-summary.md",
wantDest: "published/alice-summary.md",
},
{
name: "reject unknown source",
source: "narratio.artifact.missing",
wantErr: "is unsupported",
},
} {
t.Run(test.name, func(t *testing.T) {
publishDestination := ""
if test.dest != "" {
publishDestination = " dest: " + test.dest + "\n"
}
pipeline := artifactFamilyPipelineYAML(`
meta:
enabled: true
for_each: party.characters
prompt_id: dnd.meta
profile_id: production
output_path_pattern: artifacts/{character_id}.md
`) + `
publish:
outputs:
- source: ` + test.source + "\n" + publishDestination
pipelinePath, campaignPath, sessionPath := writeArtifactFamilyConfig(t, dir, pipeline)
cfg, err := LoadWithSessionOptions(pipelinePath, campaignPath, sessionPath, SessionLoadOptions{})
if test.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), test.wantErr) {
t.Fatalf("LoadWithSessionOptions() error = %v, want %q", err, test.wantErr)
}
return
}
if err != nil {
t.Fatalf("LoadWithSessionOptions() error = %v", err)
}
if got := cfg.Pipeline.Publish.Outputs[0].Dest; got != test.wantDest {
t.Fatalf("resolved runtime destination = %q, want %q", got, test.wantDest)
}
effective, err := MarshalEffectivePipeline(cfg.Pipeline)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(effective), "dest: "+test.wantDest+"\n") {
t.Fatalf("effective pipeline omitted resolved destination:\n%s", effective)
}
})
}
}
const validFamilyYAML = `
character_meta:
enabled: true