Add family artifact selection and provenance

This commit is contained in:
2026-08-30 14:27:42 +00:00
parent 257f10c9fb
commit c91599ef36
17 changed files with 248 additions and 24 deletions

View File

@@ -205,6 +205,10 @@ func (analyzeStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
logs = append(logs, artifactResult.Logs...)
generatedConfigs = append(generatedConfigs, artifactResult.GeneratedConfigs...)
if origin, ok := analyzeArtifactOrigin(execution, plan.Name); ok {
artifactResult.Metadata["family"] = origin.Family
artifactResult.Metadata["character_id"] = origin.CharacterID
}
artifactMetadata = append(artifactMetadata, artifactResult.Metadata)
for _, reused := range artifactResult.ReusedArtifacts {
sourceID, _ := reused["source_id"].(string)
@@ -314,6 +318,10 @@ func failedAnalyzeResult(
UpdatedAt: time.Now().UTC(),
Error: NonResumable(cause.Error()).Reason,
}
if origin, ok := analyzeArtifactOrigin(execution, item.Key); ok {
record.Family = origin.Family
record.CharacterID = origin.CharacterID
}
if fingerprint != "" {
record.FingerprintVersion = manifest.AnalyzeFingerprintContractVersion
record.Fingerprint = fingerprint
@@ -332,6 +340,14 @@ func failedAnalyzeResult(
}}
}
func analyzeArtifactOrigin(execution analyzeExecutionContext, key string) (config.ArtifactFamilyMemberOrigin, bool) {
if execution.Env == nil || execution.Env.Config == nil || execution.Env.Config.Pipeline == nil {
return config.ArtifactFamilyMemberOrigin{}, false
}
origin, ok := config.ArtifactFamilies(execution.Env.Config.Pipeline).Members[key]
return origin, ok
}
func artifactCfgMap(execution analyzeExecutionContext) map[string]config.ScriptoriumArtifactConfig {
if execution.Env == nil || execution.Env.Config == nil || execution.Env.Config.Pipeline == nil ||
execution.Env.Config.Pipeline.Scriptorium == nil {

View File

@@ -6,6 +6,7 @@ import (
"strings"
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
"gitea.maximumdirect.net/eric/narratio/internal/config"
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
)
@@ -60,7 +61,7 @@ func (analyzeStage) ValidateResume(_ context.Context, env *Env, m *manifest.Mani
if err != nil {
return ResumeValidation{}, fmt.Errorf("analyze resume: plan configured artifacts: %w", err)
}
summary := analyzeResumeSummary(plan)
summary := analyzeResumeSummary(plan, env.Config.Pipeline)
if len(plan.ExecutionOrder) == 0 {
return ResumeValidation{Resumable: true, Analyze: summary}, nil
}
@@ -71,24 +72,28 @@ func (analyzeStage) ValidateResume(_ context.Context, env *Env, m *manifest.Mani
}, nil
}
func analyzeResumeSummary(plan analyzeWorkPlan) *AnalyzeResumeSummary {
func analyzeResumeSummary(plan analyzeWorkPlan, pipeline *config.PipelineConfig) *AnalyzeResumeSummary {
return &AnalyzeResumeSummary{
ExplicitTargets: append([]string(nil), plan.ExplicitTargets...),
PrerequisiteWork: exportAnalyzeResumeItems(plan.PrerequisiteWork),
ExecutionOrder: exportAnalyzeResumeItems(plan.ExecutionOrder),
ReusedCurrent: exportAnalyzeResumeItems(plan.ReusedCurrent),
PrerequisiteWork: exportAnalyzeResumeItems(plan.PrerequisiteWork, pipeline),
ExecutionOrder: exportAnalyzeResumeItems(plan.ExecutionOrder, pipeline),
ReusedCurrent: exportAnalyzeResumeItems(plan.ReusedCurrent, pipeline),
}
}
func exportAnalyzeResumeItems(items []analyzePlanItem) []AnalyzeResumeArtifact {
func exportAnalyzeResumeItems(items []analyzePlanItem, pipeline *config.PipelineConfig) []AnalyzeResumeArtifact {
if len(items) == 0 {
return nil
}
result := make([]AnalyzeResumeArtifact, 0, len(items))
for _, item := range items {
result = append(result, AnalyzeResumeArtifact{
entry := AnalyzeResumeArtifact{
Key: item.Key, Role: string(item.Role), Reason: string(item.Reason), Forced: item.Forced,
})
}
if origin, ok := config.ArtifactFamilies(pipeline).Members[item.Key]; ok {
entry.Family, entry.CharacterID = origin.Family, origin.CharacterID
}
result = append(result, entry)
}
return result
}

View File

@@ -67,10 +67,12 @@ type AnalyzeResumeSummary struct {
// AnalyzeResumeArtifact is one deterministic artifact-level plan entry.
type AnalyzeResumeArtifact struct {
Key string
Role string
Reason string
Forced bool
Key string
Family string
CharacterID string
Role string
Reason string
Forced bool
}
// Normalized returns a result with a bounded reason and no reason on success.