Implement generated artifact handoff and provenance

This commit is contained in:
2026-07-21 21:39:23 +00:00
parent afb7ed3cf1
commit 22d4f29670
12 changed files with 749 additions and 85 deletions

View File

@@ -23,6 +23,7 @@ type PreparedPipeline struct {
chunker contracts.Chunker
chunkValidators preparedValidatorChain
output contracts.OutputEncoder
artifactCodecs *ArtifactCodecRegistry
checkpointFingerprints []CheckpointFingerprint
}
@@ -78,11 +79,12 @@ func Prepare(resolved ResolvedPipeline, registries Registries, deps ModuleDepend
}
stable := cloneResolvedPipeline(resolved)
prepared := &PreparedPipeline{
Input: cloneModuleBinding(stable.Input),
Chunk: cloneModuleBinding(stable.Chunk),
Output: cloneModuleBinding(stable.Output),
resolved: stable,
dependencies: deps,
Input: cloneModuleBinding(stable.Input),
Chunk: cloneModuleBinding(stable.Chunk),
Output: cloneModuleBinding(stable.Output),
resolved: stable,
dependencies: deps,
artifactCodecs: registries.ArtifactCodecs,
}
request := func(binding ModuleBinding, references contracts.ReferenceSet) BuildRequest {
return BuildRequest{Dependencies: deps, Options: cloneOptions(binding.Options), References: references}
@@ -134,31 +136,6 @@ func Prepare(resolved ResolvedPipeline, registries Registries, deps ModuleDepend
return prepared, nil
}
func rejectGeneratedBindings(resolved ResolvedPipeline) error {
check := func(stepID, laneID string, target ResolvedReferenceTarget) error {
for _, binding := range target.Bindings {
if binding.Artifact == nil {
continue
}
return fmt.Errorf("pipeline %q step %q lane %q %s reference slot %q uses a generated artifact; generated reference execution is not supported yet", resolved.ID, stepID, laneID, target.Stage, binding.SlotName)
}
return nil
}
if err := check("", "", resolved.ChunkReferences); err != nil {
return err
}
for _, step := range resolved.Steps {
for _, lane := range step.ArtifactLanes {
for _, target := range []ResolvedReferenceTarget{lane.ExtractReferences, lane.MergeReferences, lane.NormalizeReferences} {
if err := check(step.ID, lane.ID, target); err != nil {
return err
}
}
}
}
return nil
}
func prepareLane(pipeline ResolvedPipeline, lane ResolvedArtifactLane, registries Registries, deps ModuleDependencies) (preparedLaneExecutor, error) {
executor := preparedLaneExecutor{resolved: cloneResolvedArtifactLane(lane)}
request := func(binding ModuleBinding, references contracts.ReferenceSet) BuildRequest {
@@ -339,6 +316,9 @@ func validateRegistrySet(resolved ResolvedPipeline, registries Registries) error
if registries.Chunkers == nil {
return fmt.Errorf("chunker registry must not be nil")
}
if registries.ArtifactCodecs == nil {
return fmt.Errorf("artifact codec registry must not be nil")
}
if registries.Extractors == nil {
return fmt.Errorf("extractor registry must not be nil")
}