Expose chunk plan provenance and safe diagnostics
This commit is contained in:
@@ -69,12 +69,42 @@ type RejectedOutputManifest struct {
|
||||
DiagnosticArtifactPath string `json:"diagnostic_artifact_path,omitempty"`
|
||||
}
|
||||
|
||||
type ChunkPlanManifest struct {
|
||||
Mode string `json:"mode"`
|
||||
Action string `json:"action,omitempty"`
|
||||
SourceDigest string `json:"source_digest,omitempty"`
|
||||
PlanDigest string `json:"plan_digest,omitempty"`
|
||||
PlanSchemaVersion string `json:"plan_schema_version,omitempty"`
|
||||
RequestedModule string `json:"requested_module"`
|
||||
ProducerInputModule string `json:"producer_input_module,omitempty"`
|
||||
ProducerModule string `json:"producer_module,omitempty"`
|
||||
ProducerLLMProfile string `json:"producer_llm_profile,omitempty"`
|
||||
ProducerReferences []ReferenceProvenance `json:"producer_references,omitempty"`
|
||||
ProducerMetadata map[string]any `json:"producer_metadata,omitempty"`
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
// ChunkPlanSummary is deliberately limited to cache and validation decisions.
|
||||
// It must never contain plan units, source content, annotations, or model I/O.
|
||||
type ChunkPlanSummary struct {
|
||||
Mode string `json:"mode"`
|
||||
SourceDigest string `json:"source_digest,omitempty"`
|
||||
CandidateDigest string `json:"candidate_digest,omitempty"`
|
||||
RequestedModule string `json:"requested_module"`
|
||||
LookupStatus string `json:"lookup_status"`
|
||||
LookupReason string `json:"lookup_reason,omitempty"`
|
||||
Action string `json:"action,omitempty"`
|
||||
ValidationStatus string `json:"validation_status"`
|
||||
PublicationStatus string `json:"publication_status"`
|
||||
}
|
||||
|
||||
type RunManifest struct {
|
||||
RunID string `json:"run_id,omitempty"`
|
||||
PipelineID string `json:"pipeline_id,omitempty"`
|
||||
PipelineDigest string `json:"pipeline_digest,omitempty"`
|
||||
InputModule string `json:"input_module,omitempty"`
|
||||
Chunker string `json:"chunker,omitempty"`
|
||||
ChunkPlan *ChunkPlanManifest `json:"chunk_plan,omitempty"`
|
||||
SourceDigests []string `json:"source_digests,omitempty"`
|
||||
Extractors []string `json:"extractors,omitempty"`
|
||||
Merger string `json:"merger,omitempty"`
|
||||
|
||||
@@ -2,6 +2,7 @@ package artifacts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -16,6 +17,37 @@ func TestRunManifestOmitsEmptyOptionalFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunManifestChunkPlanIsAdditiveAndOmitsPlanContent(t *testing.T) {
|
||||
manifest := RunManifest{ChunkPlan: &ChunkPlanManifest{
|
||||
Mode: "auto", Action: "reused", SourceDigest: "sha256:source", PlanDigest: "sha256:plan",
|
||||
PlanSchemaVersion: "notarius.chunk-plan.v1", RequestedModule: "chunk/current",
|
||||
ProducerInputModule: "input/original", ProducerModule: "chunk/original",
|
||||
}}
|
||||
encoded, err := json.Marshal(manifest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
text := string(encoded)
|
||||
for _, want := range []string{`"chunk_plan"`, `"action":"reused"`, `"requested_module":"chunk/current"`, `"producer_module":"chunk/original"`} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("manifest JSON %s does not contain %s", text, want)
|
||||
}
|
||||
}
|
||||
for _, forbidden := range []string{`"plan"`, `"units"`, `"annotations"`} {
|
||||
if strings.Contains(text, forbidden) {
|
||||
t.Fatalf("manifest JSON contains forbidden field %s: %s", forbidden, text)
|
||||
}
|
||||
}
|
||||
|
||||
var legacy RunManifest
|
||||
if err := json.Unmarshal([]byte(`{"pipeline_id":"legacy"}`), &legacy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if legacy.PipelineID != "legacy" || legacy.ChunkPlan != nil {
|
||||
t.Fatalf("legacy manifest = %#v", legacy)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunManifestIncludesPipelineAndArtifactLaneFields(t *testing.T) {
|
||||
manifest := RunManifest{
|
||||
PipelineID: "pipeline-1",
|
||||
|
||||
Reference in New Issue
Block a user