Update artifact resolution so configured artifact IDs are resolved through the runtime catalog

This commit is contained in:
2026-05-19 18:49:27 -05:00
parent 859ae1ae10
commit 3e79cf4724
4 changed files with 307 additions and 2 deletions

View File

@@ -137,3 +137,131 @@ func TestResolveSessionArtifactValidatesTranscriptShape(t *testing.T) {
t.Fatalf("error = %q, want segments validation error", err.Error())
}
}
func TestResolveSessionArtifactWithCatalogBuiltInBehaviorUnchanged(t *testing.T) {
workspace := t.TempDir()
paths := buildSessionPaths(workspace, "campaign", "session")
canonicalPath := filepath.Join(paths.TranscriptsDir, "trimmed.json")
if err := os.MkdirAll(filepath.Dir(canonicalPath), 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
if err := os.WriteFile(canonicalPath, []byte(`{"segments":[]}`), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
resolved, err := ResolveSessionArtifactWithCatalog(paths, nil, ArtifactTranscriptTrimmed, NewArtifactCatalog())
if err != nil {
t.Fatalf("ResolveSessionArtifactWithCatalog() error = %v", err)
}
if resolved.Path != canonicalPath {
t.Fatalf("resolved.Path = %q, want %q", resolved.Path, canonicalPath)
}
if resolved.Provenance != "fallback.canonical_path" {
t.Fatalf("provenance = %q, want fallback.canonical_path", resolved.Provenance)
}
}
func TestResolveSessionArtifactWithCatalogConfiguredAvailableGenerated(t *testing.T) {
workspace := t.TempDir()
paths := buildSessionPaths(workspace, "campaign", "session")
outputPath := filepath.Join(paths.ArtifactsDir, "session_recap.md")
if err := os.MkdirAll(filepath.Dir(outputPath), 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
if err := os.WriteFile(outputPath, []byte("recap\n"), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
catalog := NewArtifactCatalog()
if err := catalog.RegisterConfiguredArtifacts(
map[string]ConfiguredArtifactDefinition{
"session_recap": {Enabled: true, OutputPath: "artifacts/session_recap.md"},
},
nil,
); err != nil {
t.Fatalf("RegisterConfiguredArtifacts() error = %v", err)
}
sourceID := ConfiguredArtifactSourceID("session_recap")
if err := catalog.MarkAvailableGenerated(sourceID, outputPath); err != nil {
t.Fatalf("MarkAvailableGenerated() error = %v", err)
}
resolved, err := ResolveSessionArtifactWithCatalog(paths, nil, sourceID, catalog)
if err != nil {
t.Fatalf("ResolveSessionArtifactWithCatalog() error = %v", err)
}
if resolved.Path != outputPath {
t.Fatalf("resolved.Path = %q, want %q", resolved.Path, outputPath)
}
if resolved.Provenance != ArtifactProvenanceGeneratedCurrentAnalyzeRun {
t.Fatalf("provenance = %q, want %q", resolved.Provenance, ArtifactProvenanceGeneratedCurrentAnalyzeRun)
}
}
func TestResolveSessionArtifactWithCatalogConfiguredAvailableFromDisk(t *testing.T) {
workspace := t.TempDir()
paths := buildSessionPaths(workspace, "campaign", "session")
outputPath := filepath.Join(paths.ArtifactsDir, "player_handout.md")
if err := os.MkdirAll(filepath.Dir(outputPath), 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
if err := os.WriteFile(outputPath, []byte("handout\n"), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
catalog := NewArtifactCatalog()
if err := catalog.RegisterConfiguredArtifacts(
map[string]ConfiguredArtifactDefinition{
"player_handout": {Enabled: false, OutputPath: "artifacts/player_handout.md"},
},
nil,
); err != nil {
t.Fatalf("RegisterConfiguredArtifacts() error = %v", err)
}
sourceID := ConfiguredArtifactSourceID("player_handout")
if err := catalog.MarkAvailableFromDisk(sourceID, outputPath); err != nil {
t.Fatalf("MarkAvailableFromDisk() error = %v", err)
}
resolved, err := ResolveSessionArtifactWithCatalog(paths, nil, sourceID, catalog)
if err != nil {
t.Fatalf("ResolveSessionArtifactWithCatalog() error = %v", err)
}
if resolved.Provenance != ArtifactProvenanceDisabledFromDisk {
t.Fatalf("provenance = %q, want %q", resolved.Provenance, ArtifactProvenanceDisabledFromDisk)
}
}
func TestResolveSessionArtifactWithCatalogConfiguredPlannedButUnavailable(t *testing.T) {
workspace := t.TempDir()
paths := buildSessionPaths(workspace, "campaign", "session")
catalog := NewArtifactCatalog()
if err := catalog.RegisterConfiguredArtifacts(
map[string]ConfiguredArtifactDefinition{
"session_recap": {Enabled: true, OutputPath: "artifacts/session_recap.md"},
},
nil,
); err != nil {
t.Fatalf("RegisterConfiguredArtifacts() error = %v", err)
}
_, err := ResolveSessionArtifactWithCatalog(paths, nil, ConfiguredArtifactSourceID("session_recap"), catalog)
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, ErrSessionArtifactNotFound) {
t.Fatalf("errors.Is(err, ErrSessionArtifactNotFound)=false; err=%v", err)
}
}
func TestResolveSessionArtifactWithCatalogUnsupportedConfiguredSourceFails(t *testing.T) {
workspace := t.TempDir()
paths := buildSessionPaths(workspace, "campaign", "session")
catalog := NewArtifactCatalog()
_, err := ResolveSessionArtifactWithCatalog(paths, nil, "narratio.artifact.unknown", catalog)
if err == nil {
t.Fatal("expected error, got nil")
}
if !strings.Contains(err.Error(), "unsupported artifact source") {
t.Fatalf("error = %q, want unsupported artifact source", err.Error())
}
}