Clarify evidence context and test lane filtering

This commit is contained in:
2026-07-27 14:03:23 -05:00
parent 4f2864fc96
commit 7c94b5eeed
2 changed files with 32 additions and 11 deletions

View File

@@ -81,12 +81,12 @@ evidence publishes `contexts: []`.
}
```
Each context requires `context_ref`, `evidence_refs`, and `units` arrays.
`context_ref` identifies the first and last included unit. Each evidence entry
contains a selected `lane_id` and an original `source_ref`. A unit uses the
existing source-unit shape: required `id`, `kind`, `text`, and self `ref`, plus
optional JSON-object `metadata`. Fixed payload objects reject unknown fields;
unit metadata may contain application-defined JSON values.
Each context requires a `context_ref` object and `evidence_refs` and `units`
arrays. `context_ref` identifies the first and last included unit. Each
evidence entry contains a selected `lane_id` and an original `source_ref`. A
unit uses the existing source-unit shape: required `id`, `kind`, `text`, and
self `ref`, plus optional JSON-object `metadata`. Fixed payload objects reject
unknown fields; unit metadata may contain application-defined JSON values.
## Citations And Context

View File

@@ -2,6 +2,7 @@ package pipeline
import (
"context"
"fmt"
"reflect"
"strings"
"testing"
@@ -22,19 +23,34 @@ func (output testEvidenceOutput) EvidenceContextPolicy() EvidenceContextPolicy {
return cloneEvidenceContextPolicy(output.policy)
}
func TestPrepareEvidencePlanSelectsActiveLanesAndOwnsPolicy(t *testing.T) {
func TestEvidencePolicyResolutionAndPreparationSurviveLaneFiltering(t *testing.T) {
registries, _ := constructionRegistries(t, nil, nil)
registries.ArtifactEvidence = NewArtifactEvidenceRegistry()
registerTestEvidenceOutput(t, &registries, EvidenceContextPolicy{Enabled: true, WindowUnits: 2, LaneIDs: []string{"artifact", "inactive"}})
policy := EvidenceContextPolicy{Enabled: true, WindowUnits: 2, LaneIDs: []string{"artifact", "inactive"}}
profileValidated := false
registerTestEvidenceOutputWithProfileValidation(t, &registries, policy, func(context OutputProfileOptionContext, _ map[string]any) error {
profileValidated = true
if want := []string{"artifact", "inactive"}; !reflect.DeepEqual(context.LaneIDs, want) {
return fmt.Errorf("configured lane ids = %#v, want %#v", context.LaneIDs, want)
}
return nil
})
if err := RegisterArtifactEvidence(registries.ArtifactEvidence, "test/notes", func(codecNotes) []source.SourceRef { return nil }); err != nil {
t.Fatal(err)
}
profile := constructionProfile()
profile.Artifacts["inactive"] = profile.Artifacts["artifact"]
profile.Output.Options = map[string]any{"known": true}
resolved, err := ResolvePipeline(profile, ResolveOptions{}, registries.catalog())
resolved, err := ResolvePipeline(profile, ResolveOptions{Only: []string{"artifact"}}, registries.catalog())
if err != nil {
t.Fatal(err)
}
if !profileValidated {
t.Fatal("output profile options were not validated")
}
if lanes := resolved.AllArtifactLanes(); len(lanes) != 1 || lanes[0].ID != "artifact" {
t.Fatalf("resolved lanes = %#v, want only the invocation-selected lane", lanes)
}
prepared, err := Prepare(resolved, registries, ModuleDependencies{})
if err != nil {
t.Fatalf("Prepare() error = %v, want nil", err)
@@ -85,11 +101,16 @@ func TestPrepareEvidencePlanRejectsMissingAndMismatchedCapabilities(t *testing.T
}
func registerTestEvidenceOutput(t *testing.T, registries *Registries, policy EvidenceContextPolicy) {
t.Helper()
registerTestEvidenceOutputWithProfileValidation(t, registries, policy, nil)
}
func registerTestEvidenceOutputWithProfileValidation(t *testing.T, registries *Registries, policy EvidenceContextPolicy, validateProfile OutputProfileOptionValidator) {
t.Helper()
registry := NewOutputEncoderRegistry()
if err := registry.RegisterBuilderWithSpec(defaultModuleSpec("output", StageOutput), func(options map[string]any) error {
if err := registry.RegisterBuilderWithProfileValidation(defaultModuleSpec("output", StageOutput), func(options map[string]any) error {
return RejectUnknownOptions(options, "known")
}, func(BuildRequest) (contracts.OutputEncoder, error) {
}, validateProfile, func(BuildRequest) (contracts.OutputEncoder, error) {
return testEvidenceOutput{policy: cloneEvidenceContextPolicy(policy)}, nil
}); err != nil {
t.Fatal(err)