Expose chunk plan provenance and safe diagnostics

This commit is contained in:
2026-07-18 00:45:01 +00:00
parent 8ba5228c01
commit 6fc6ce0adb
15 changed files with 363 additions and 41 deletions

View File

@@ -63,6 +63,7 @@ type RunInput struct {
type RunOutput struct {
Manifest artifacts.RunManifest `json:"manifest"`
ChunkPlan *artifacts.ChunkPlanSummary `json:"chunk_plan,omitempty"`
NormalizeOutputs []contracts.SerializedOutput `json:"normalize_outputs,omitempty"`
Rejected []contracts.RejectedOutput `json:"rejected,omitempty"`
Warnings []contracts.Warning `json:"warnings,omitempty"`
@@ -81,6 +82,11 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err
input.llmClient = input.Prepared.dependencies.LLM
output.Manifest = manifestFromPipeline(input)
output.ChunkPlan = &artifacts.ChunkPlanSummary{
Mode: string(effectiveChunkCacheMode(input.ChunkCacheMode)), RequestedModule: input.pipeline.Chunk.Module,
LookupStatus: "skipped", LookupReason: "chunk plan lookup skipped",
ValidationStatus: "not_run", PublicationStatus: "not_requested",
}
checkpoints := input.Checkpoints
if checkpoints == nil {
checkpoints = NoopCheckpointRecorder()
@@ -193,6 +199,7 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err
return failOutput(output), fmt.Errorf("write chunk debug artifact: %w", err)
}
chunkResult, err := r.runChunkPlan(ctx, input, doc, sourceInput, sessionID)
applyChunkPlanExecution(&output, chunkResult)
if err != nil {
return failOutput(output), err
}
@@ -481,10 +488,14 @@ func manifestFromPipeline(input RunInput) artifacts.RunManifest {
pipeline := input.pipeline
manifest := artifacts.RunManifest{
PipelineID: pipeline.ID,
PipelineDigest: pipeline.Digest,
InputModule: pipeline.Input.Module,
Chunker: pipeline.Chunk.Module,
PipelineID: pipeline.ID,
PipelineDigest: pipeline.Digest,
InputModule: pipeline.Input.Module,
Chunker: pipeline.Chunk.Module,
ChunkPlan: &artifacts.ChunkPlanManifest{
Mode: string(effectiveChunkCacheMode(input.ChunkCacheMode)),
RequestedModule: pipeline.Chunk.Module,
},
OutputEncoder: pipeline.Output.Module,
ArtifactLanes: make([]artifacts.ArtifactLaneManifest, 0, len(pipeline.ArtifactLanes)),
ValidatorChains: validatorChainManifests(pipeline.ValidatorChains),
@@ -673,11 +684,38 @@ func cloneMetadata(metadata map[string]any) map[string]any {
}
out := make(map[string]any, len(metadata))
for key, value := range metadata {
out[key] = value
out[key] = cloneMetadataValue(value)
}
return out
}
func cloneMetadataValue(value any) any {
switch typed := value.(type) {
case map[string]any:
return cloneMetadata(typed)
case []any:
out := make([]any, len(typed))
for i := range typed {
out[i] = cloneMetadataValue(typed[i])
}
return out
case json.RawMessage:
return append(json.RawMessage(nil), typed...)
case []byte:
return append([]byte(nil), typed...)
case []string:
return append([]string(nil), typed...)
case map[string]string:
out := make(map[string]string, len(typed))
for key, item := range typed {
out[key] = item
}
return out
default:
return value
}
}
func cloneLLMProfiles(profiles []artifacts.LLMProfileManifest) []artifacts.LLMProfileManifest {
if len(profiles) == 0 {
return nil