diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 230b58a..158a54f 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -548,6 +548,14 @@ Focused check: `go test .` and `go test ./examples/consumers`. Finding: completes **F06**, following its schema-path subset in Stage 1. Owners: the exact records/files listed in [audit F06](audit.md#f06-trim-unread-private-result-and-transport-members). +Status: **complete** (F06). Prior completed commits: `2736ddf`, `deb9aa5`, +`ae3408a`, `ea27f17`, `08a8c25`, `877c497`, `8aba43d`, `7bf2f0c`, +`0f9ecf1`, `119b42c`, `247a12b`, `4fcff5f`, `12d350a`, `08f2a8f`, +`826062a`, `e4a5ecb`. Validation passed: +`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine`, +`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test .`, and +`git diff --check`. + Remove `collectionPolicyResolution`'s four named unread fields; `inputPresence.null`; directive extraction's two presence flags; `importSelection.outcome`; `importDeclarationSpec.excludeSet`; `selectedOverlayRequest.filesystem`; diff --git a/internal/engine/collection_policy.go b/internal/engine/collection_policy.go index 9ceaacd..20557a3 100644 --- a/internal/engine/collection_policy.go +++ b/internal/engine/collection_policy.go @@ -14,11 +14,7 @@ type collectionPolicy struct { type collectionPolicyResolution struct { policy collectionPolicy operation sequenceMode - declarations []sequenceDeclarationSpec - declarationsPresent bool - identityDeclarationPresent bool modeDeclarationPresent bool - applicationIdentityFields []string applicationIdentityPresent bool effectiveIdentityFields []string } @@ -60,9 +56,6 @@ func resolveCollectionPolicy( } } result := collectionPolicyResolution{ - declarations: normalizedDeclarations, - declarationsPresent: len(normalizedDeclarations) != 0, - applicationIdentityFields: normalizedApplicationIdentityFields, applicationIdentityPresent: len(normalizedApplicationIdentityFields) != 0, } @@ -73,7 +66,6 @@ func resolveCollectionPolicy( var declaredModeLocation *Location for _, declaration := range normalizedDeclarations { if declaration.identityPresent { - result.identityDeclarationPresent = true if declaredIdentityFields == nil { declaredIdentityFields = cloneStrings(declaration.identityFields) declaredIdentityLocation = collectionDeclarationLocation(declaration.identityLocation, declaration.location) diff --git a/internal/engine/collection_policy_test.go b/internal/engine/collection_policy_test.go index 2496d6d..c97ac3e 100644 --- a/internal/engine/collection_policy_test.go +++ b/internal/engine/collection_policy_test.go @@ -21,8 +21,8 @@ func TestResolveCollectionPolicyReconcilesDeclarationsBeforeComposition(t *testi if len(diagnostics) != 0 { t.Fatalf("policy diagnostics = %#v", diagnostics) } - if !resolved.declarationsPresent || !resolved.identityDeclarationPresent || !resolved.modeDeclarationPresent { - t.Fatalf("declaration presence was lost: %#v", resolved) + if !resolved.modeDeclarationPresent { + t.Fatalf("mode declaration was lost: %#v", resolved) } wantFields := []string{"id", "namespace"} if !reflect.DeepEqual(resolved.policy.identityFields, wantFields) || !reflect.DeepEqual(resolved.effectiveIdentityFields, wantFields) { @@ -31,9 +31,6 @@ func TestResolveCollectionPolicyReconcilesDeclarationsBeforeComposition(t *testi if !resolved.policy.identityPresent || !resolved.policy.explicitModePresent || resolved.policy.explicitMode != sequenceModeAppend || resolved.operation != sequenceModeAppend { t.Fatalf("resolved explicit policy = %#v, operation %d", resolved.policy, resolved.operation) } - if len(resolved.declarations) != 3 || resolved.declarations[0].identityLocation == nil || resolved.declarations[2].location.Line == 0 { - t.Fatalf("declaration locations were not retained: %#v", resolved.declarations) - } } func TestResolveCollectionPolicyRejectsConflictingPeersAtBothSites(t *testing.T) { diff --git a/internal/engine/decode.go b/internal/engine/decode.go index 63ea900..1fed3c5 100644 --- a/internal/engine/decode.go +++ b/internal/engine/decode.go @@ -22,7 +22,6 @@ type decodeIssue struct { } type inputPresence struct { - null bool location document.Location } @@ -434,7 +433,7 @@ func fieldForDecode(root reflect.Value, index []int, allocate bool) (reflect.Val } func collectPresence(node *document.Node, path Path, presence map[string]inputPresence) { - presence[path.String()] = inputPresence{null: node.Kind == document.Null, location: node.Location} + presence[path.String()] = inputPresence{location: node.Location} switch node.Kind { case document.Mapping: for _, entry := range node.Mapping { diff --git a/internal/engine/directives.go b/internal/engine/directives.go index d429a11..c86a428 100644 --- a/internal/engine/directives.go +++ b/internal/engine/directives.go @@ -19,11 +19,9 @@ const ( ) type rootDirectiveExtraction struct { - body *document.Node - imports []importDeclarationSpec - sequences []sequenceDeclarationSpec - importsPresent bool - sequencesPresent bool + body *document.Node + imports []importDeclarationSpec + sequences []sequenceDeclarationSpec } func splitImportDirectives(root *document.Node) (*document.Node, []importDeclarationSpec, []Diagnostic) { @@ -74,7 +72,6 @@ func parseRootDirectiveBlock(node *document.Node, directivePath Path, context ro fieldPath := directivePath.Key(entry.Key) switch entry.Key { case "imports": - extracted.importsPresent = true if context == rootDirectiveContextOverlay { diagnostics = append(diagnostics, nodeImportDiagnostic(CodeOverlayDirective, fieldPath, "overlays cannot contain imports", entry.Value)) continue @@ -87,7 +84,6 @@ func parseRootDirectiveBlock(node *document.Node, directivePath Path, context ro extracted.imports = append(extracted.imports, parsed...) diagnostics = append(diagnostics, issues...) case "sequences": - extracted.sequencesPresent = true if context == rootDirectiveContextImportsOnly { diagnostics = append(diagnostics, sequenceDeclarationDiagnostic(fieldPath, "sequence declarations are not enabled in this extraction context", entry.Value)) continue diff --git a/internal/engine/directory_selection_test.go b/internal/engine/directory_selection_test.go index bb3c47c..f42c202 100644 --- a/internal/engine/directory_selection_test.go +++ b/internal/engine/directory_selection_test.go @@ -43,7 +43,7 @@ func TestSelectShallowDirectoriesUnionsRootsAndPatterns(t *testing.T) { if len(diagnostics) != 0 { t.Fatalf("selection diagnostics = %#v", diagnostics) } - if selection.outcome != importSelectionHasCandidates || len(selection.candidates) != 3 { + if len(selection.candidates) != 3 { t.Fatalf("selection = %#v, want three unioned matches", selection) } if selection.candidates[0].path != "one/README" || selection.candidates[1].path != "one/a.yaml" || selection.candidates[2].path != "two/a.yaml" { @@ -353,7 +353,7 @@ func TestSelectDirectoriesRetainsEmptySearchAndDirectoryVisitLimits(t *testing.T } accounting := &importAccounting{} selection, diagnostics := selectDirectoryImportCandidates(access, root, specs[0], policy, defaultImportLimits(), accounting) - if len(diagnostics) != 0 || selection.outcome != importSelectionNone || len(selection.candidates) != 0 { + if len(diagnostics) != 0 || len(selection.candidates) != 0 { t.Fatalf("empty recursive selection, diagnostics = %#v, %#v", selection, diagnostics) } if accounting.entries != 5 { diff --git a/internal/engine/glob.go b/internal/engine/glob.go index e1b8298..76a74dc 100644 --- a/internal/engine/glob.go +++ b/internal/engine/glob.go @@ -120,9 +120,6 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec // Source allowance is charged by source admission, after this filtered set // reaches the traversal; that preserves repeated-source diagnostics first. selection := importSelection{candidates: selected} - if len(selected) != 0 { - selection.outcome = importSelectionHasCandidates - } return selection, nil } diff --git a/internal/engine/import_selection.go b/internal/engine/import_selection.go index 8faf30d..6c32583 100644 --- a/internal/engine/import_selection.go +++ b/internal/engine/import_selection.go @@ -26,7 +26,6 @@ type selectedImportCandidate struct { // importSelection contains lexical candidates only; admission assigns source identity later. type importSelection struct { candidates []selectedImportCandidate - outcome importSelectionOutcome } func selectNamedImportCandidates(access *filesystemAccess, basePath string, spec importDeclarationSpec, policy resolvedImportPolicy) (importSelection, []Diagnostic) { @@ -68,9 +67,6 @@ func selectNamedImportCandidates(access *filesystemAccess, basePath string, spec candidates = append(candidates, candidate) } selection := importSelection{candidates: candidates} - if len(candidates) != 0 { - selection.outcome = importSelectionHasCandidates - } return selection, nil } @@ -174,9 +170,6 @@ func selectDirectoryImportCandidates(access *filesystemAccess, basePath string, return importSelection{}, []Diagnostic{*importSelectionDiagnostic(spec.fieldSites["dir"], CodeImportMissing, "required directory import selected no files")} } selection := importSelection{candidates: selected} - if len(selected) != 0 { - selection.outcome = importSelectionHasCandidates - } return selection, nil } diff --git a/internal/engine/import_selection_test.go b/internal/engine/import_selection_test.go index 8ef8a46..95bb66a 100644 --- a/internal/engine/import_selection_test.go +++ b/internal/engine/import_selection_test.go @@ -30,7 +30,7 @@ func TestSelectNamedImportsHandlesPartialAndEmptySelections(t *testing.T) { if len(diagnostics) != 0 { t.Fatalf("optional partial selection diagnostics = %#v", diagnostics) } - if selection.outcome != importSelectionHasCandidates || len(selection.candidates) != 1 || filepath.Base(selection.candidates[0].path) != "present.yaml" { + if len(selection.candidates) != 1 || filepath.Base(selection.candidates[0].path) != "present.yaml" { t.Fatalf("partial selection = %#v", selection) } @@ -48,7 +48,7 @@ func TestSelectNamedImportsHandlesPartialAndEmptySelections(t *testing.T) { t.Fatal(diagnostics) } empty, diagnostics := selectNamedImportCandidates(access, root, emptySpecs[0], resolvedImportPolicy{required: true}) - if len(diagnostics) != 0 || empty.outcome != importSelectionNone || len(empty.candidates) != 0 { + if len(diagnostics) != 0 || len(empty.candidates) != 0 { t.Fatalf("required empty path selection, diagnostics = %#v, %#v", empty, diagnostics) } } @@ -123,7 +123,7 @@ func TestSelectNamedImportsDoesNotOpenExcludedContentOrApplySearchControls(t *te t.Fatal(diagnostics) } selection, diagnostics := selectNamedImportCandidates(access, ".", specs[0], policy) - if len(diagnostics) != 0 || selection.outcome != importSelectionNone { + if len(diagnostics) != 0 || len(selection.candidates) != 0 { t.Fatalf("excluded selection, diagnostics = %#v, %#v", selection, diagnostics) } if filesystem.openCalls != 0 || filesystem.statCalls == 0 { diff --git a/internal/engine/import_spec.go b/internal/engine/import_spec.go index ef78ab5..42defd0 100644 --- a/internal/engine/import_spec.go +++ b/internal/engine/import_spec.go @@ -35,7 +35,6 @@ type importDeclarationSpec struct { pattern []string patternSet bool exclude []string - excludeSet bool depth int depthSet bool destination Path @@ -327,7 +326,7 @@ func parseImportWildcardAssignment(spec *importDeclarationSpec, field string, no case "pattern": spec.pattern, spec.patternSet = values, true case "exclude": - spec.exclude, spec.excludeSet = values, true + spec.exclude = values } return nil } diff --git a/internal/engine/import_spec_test.go b/internal/engine/import_spec_test.go index 8d520ec..01d92ab 100644 --- a/internal/engine/import_spec_test.go +++ b/internal/engine/import_spec_test.go @@ -38,7 +38,7 @@ func TestParseImportDeclarationSpecNormalizesPresenceAndPlacement(t *testing.T) t.Fatalf("stored paths = declaration %q, required %q", first.path.String(), first.fieldSites["required"].path.String()) } second := specs[1] - if second.selector != importSelectorDirectory || second.paths == nil || len(second.paths) != 0 || !second.patternSet || second.pattern == nil || len(second.pattern) != 0 || !second.excludeSet || second.exclude == nil { + if second.selector != importSelectorDirectory || second.paths == nil || len(second.paths) != 0 || !second.patternSet || second.pattern == nil || len(second.pattern) != 0 || second.exclude == nil { t.Fatalf("empty list presence was lost: %#v", second) } third := specs[2] diff --git a/internal/engine/load_input.go b/internal/engine/load_input.go index 14f9498..09f3717 100644 --- a/internal/engine/load_input.go +++ b/internal/engine/load_input.go @@ -107,7 +107,7 @@ func applyInputLayers(source Source, filesystem *FilesystemContext, overlay stri } } request := selectedOverlayRequest{ - name: overlay, filesystem: resolved, protectionRule: protectionRule, + name: overlay, protectionRule: protectionRule, sequencePolicy: policy, limits: defaultImportLimits(), versionState: input.versionState, } access, diagnostic := openSelectedOverlayAccess(resolved) diff --git a/internal/engine/load_request.go b/internal/engine/load_request.go index 511e676..9bccfdb 100644 --- a/internal/engine/load_request.go +++ b/internal/engine/load_request.go @@ -207,7 +207,7 @@ func assembleLayeredInput[T any](request loadRequest[T], input assembledInput, p return input, append(versionDiagnostics, *diagnostic) } overlayRequest := selectedOverlayRequest{ - name: request.overlay, filesystem: resolved, protectionRule: request.protectionVersion(), + name: request.overlay, protectionRule: request.protectionVersion(), sequencePolicy: policy.sequencePolicy, limits: defaultImportLimits(), versionState: input.versionState, } var diagnostics []Diagnostic diff --git a/internal/engine/override_context.go b/internal/engine/override_context.go index df8d76e..00f3a9f 100644 --- a/internal/engine/override_context.go +++ b/internal/engine/override_context.go @@ -11,7 +11,6 @@ type postDecodeOverrideContext struct { decoded decodedConfiguration metadata Metadata resolution resolutionInput - sources []SourceInfo applications []historyApplication postDecodeApps []historyApplication referenceInput *document.Node @@ -76,7 +75,6 @@ func preparePostDecodeOverrideContext(input assembledInput, before decodedConfig decoded: after, metadata: metadata, resolution: resolution, - sources: sources, applications: applications, postDecodeApps: postDecodeApps, referenceInput: documentWithMetadataLocations(assigned.final, metadata, input.document), diff --git a/internal/engine/override_context_test.go b/internal/engine/override_context_test.go index 89c7df1..f4ef99f 100644 --- a/internal/engine/override_context_test.go +++ b/internal/engine/override_context_test.go @@ -72,9 +72,6 @@ func TestPostDecodeOverrideContextOrdersDecodeCLIAndResolutionEvidence(t *testin if len(prepared.applications) != 1 || len(prepared.postDecodeApps) != len(batch.overrides) || len(prepared.historyApplications()) != 1+len(batch.overrides) { t.Fatalf("history applications = structural:%d CLI:%d all:%d", len(prepared.applications), len(prepared.postDecodeApps), len(prepared.historyApplications())) } - if len(prepared.sources) != len(sources)+len(batch.overrides) || prepared.sources[len(prepared.sources)-1].Layer != LayerCLI { - t.Fatalf("prepared source order = %#v", prepared.sources) - } if prepared.resolution.contexts["source-1"].BaseDir != "/config" { t.Fatalf("resolution source contexts = %#v", prepared.resolution.contexts) } diff --git a/internal/engine/selected_overlay.go b/internal/engine/selected_overlay.go index 860fdf3..02f0dea 100644 --- a/internal/engine/selected_overlay.go +++ b/internal/engine/selected_overlay.go @@ -30,7 +30,6 @@ func validOverlayName(name string) bool { type selectedOverlayRequest struct { name string - filesystem resolvedFilesystemContext protectionRule *VersionRule sequencePolicy sequencePolicy limits importLimits diff --git a/internal/engine/selected_overlay_test.go b/internal/engine/selected_overlay_test.go index 3cb3fa6..5f17644 100644 --- a/internal/engine/selected_overlay_test.go +++ b/internal/engine/selected_overlay_test.go @@ -590,7 +590,7 @@ func TestLoadOverlayCountsAgainstAggregateBudgets(t *testing.T) { t.Fatal(diagnostic) } request := selectedOverlayRequest{ - name: "testing", filesystem: resolved, limits: test.limits(main, len(overlayData)), + name: "testing", limits: test.limits(main, len(overlayData)), } if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { t.Fatal(diagnostic) diff --git a/internal/engine/sequence_declaration.go b/internal/engine/sequence_declaration.go index b5a90f2..90f52b0 100644 --- a/internal/engine/sequence_declaration.go +++ b/internal/engine/sequence_declaration.go @@ -11,16 +11,15 @@ const ( ) type sequenceDeclarationSpec struct { - path Path - location Location - destination Path - destinationLocation Location - identityFields []string - identityPresent bool - identityLocation *Location - mode sequenceMode - modePresent bool - modeLocation *Location + path Path + location Location + destination Path + identityFields []string + identityPresent bool + identityLocation *Location + mode sequenceMode + modePresent bool + modeLocation *Location } func parseSequenceDeclarationDirective(node *document.Node, directivePath Path) ([]sequenceDeclarationSpec, []Diagnostic) { @@ -60,7 +59,6 @@ func parseSequenceDeclarationSpec(node *document.Node, declarationPath Path) (se return sequenceDeclarationSpec{}, []Diagnostic{*diagnostic} } declaration.destination = destination - declaration.destinationLocation = publicLocation(entry.Value.Location) case "key": fields, locations, errIndex, valid := parseSequenceIdentityFieldSet(entry.Value) if !valid { diff --git a/internal/engine/sequence_declaration_test.go b/internal/engine/sequence_declaration_test.go index 7532e1d..a0b61c8 100644 --- a/internal/engine/sequence_declaration_test.go +++ b/internal/engine/sequence_declaration_test.go @@ -24,14 +24,14 @@ func TestParseSequenceDeclarationPresenceAndRelativeDestination(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { extracted := extractSequenceDeclarationsYAML(t, "configkit:\n sequences:\n - "+test.declaration+"\n", rootDirectiveContextSource) - if !extracted.sequencesPresent || len(extracted.sequences) != 1 { + if len(extracted.sequences) != 1 { t.Fatalf("extraction = %#v", extracted) } declaration := extracted.sequences[0] if declaration.destination.String() != "/prompts" || declaration.path.String() != "/configkit/sequences/0" { t.Fatalf("relative destination or declaration path changed: %#v", declaration) } - if declaration.location.SourceID != "sequence-declarations" || declaration.location.Line == 0 || declaration.destinationLocation.SourceID != "sequence-declarations" || declaration.destinationLocation.Line == 0 { + if declaration.location.SourceID != "sequence-declarations" || declaration.location.Line == 0 { t.Fatalf("declaration source locations were not retained: %#v", declaration) } if declaration.identityPresent != test.wantIdentity || declaration.modePresent != test.wantMode { @@ -63,13 +63,13 @@ func TestParseSequenceDeclarationNormalizesEquivalentFieldSets(t *testing.T) { } } -func TestExtractRootDirectivesCombinesImportsAndSequencesWithPresence(t *testing.T) { +func TestExtractRootDirectivesCombinesAndRemovesImportsAndSequences(t *testing.T) { extracted := extractSequenceDeclarationsYAML(t, `configkit: imports: [{path: fragments/base.yaml}] sequences: [] value: true `, rootDirectiveContextSource) - if !extracted.importsPresent || len(extracted.imports) != 1 || !extracted.sequencesPresent || len(extracted.sequences) != 0 { + if len(extracted.imports) != 1 || len(extracted.sequences) != 0 { t.Fatalf("mixed extraction = %#v", extracted) } if extracted.body == nil || extracted.body.Kind != document.Mapping || len(extracted.body.Mapping) != 1 || extracted.body.Mapping[0].Key != "value" { @@ -89,7 +89,7 @@ func TestExtractRootDirectivesAllowsSequencesButRejectsOverlayImports(t *testing extracted, diagnostics := extractRootDirectives(parseRootDirectiveDocument(t, `configkit: sequences: [{destination: [prompts], key: id}] `), rootDirectiveContextOverlay) - if len(diagnostics) != 0 || !extracted.sequencesPresent || len(extracted.sequences) != 1 { + if len(diagnostics) != 0 || len(extracted.sequences) != 1 { t.Fatalf("overlay sequence extraction = %#v, %#v", extracted, diagnostics) } } diff --git a/internal/engine/source_version.go b/internal/engine/source_version.go index 22aeed0..b3bab6c 100644 --- a/internal/engine/source_version.go +++ b/internal/engine/source_version.go @@ -26,7 +26,6 @@ const ( type sourceVersionAncestor struct { path Path - kind document.Kind } type sourceVersionEvidence struct { @@ -38,8 +37,6 @@ type sourceVersionEvidence struct { version Version location *Location ancestors []sourceVersionAncestor - absence sourceVersionPathAbsence - checked bool redacted bool } @@ -239,7 +236,6 @@ func processSourceVersionWithDirectiveContext(root *document.Node, rule *Version evidence := &sourceVersionEvidence{ path: rule.Path.clone(), resolvedPath: resolved.resolvedPath, destination: destination.clone(), ancestors: resolved.ancestors, - absence: resolved.absence, } location := resolved.nearest if resolved.present { @@ -277,7 +273,6 @@ func processSourceVersionWithDirectiveContext(root *document.Node, rule *Version } } - evidence.checked = true result.diagnostics = canonicalDiagnostics(reportVersion(rule, interpreted.version, root)) if hasErrors(result.diagnostics) { evidence.redactText() @@ -334,7 +329,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath } current := root resolved.nearest = current.Location - resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{kind: current.Kind}) + resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{}) for position, segment := range path.segments { switch current.Kind { case document.Mapping: @@ -373,7 +368,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath } resolved.nearest = current.Location resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{ - path: Path{segments: clonePathSegments(resolved.resolvedPath.segments[:position+1], 0)}, kind: current.Kind, + path: Path{segments: clonePathSegments(resolved.resolvedPath.segments[:position+1], 0)}, }) } resolved.node = current diff --git a/internal/engine/source_version_test.go b/internal/engine/source_version_test.go index 97bfb02..e489303 100644 --- a/internal/engine/source_version_test.go +++ b/internal/engine/source_version_test.go @@ -217,7 +217,7 @@ func TestSourceVersionExtractionPreservesVersionVocabulary(t *testing.T) { return nil }} result := processSourceVersion(root, rule, sourceVersionContribution, Keys("collections", "weather"), sourceVersionModeIfPresent) - if len(result.diagnostics) != 0 || !result.evidence.checked || result.evidence.version != test.want || checked != test.want { + if len(result.diagnostics) != 0 || result.evidence.version != test.want || checked != test.want { t.Fatalf("result = %#v, checked = %#v", result, checked) } if _, found := documentAtPath(result.payload, rule.Path); found { @@ -245,35 +245,34 @@ func TestSourceVersionExtractionHandlesMissingAndMalformedValues(t *testing.T) { wantCode Code wantPresent bool wantCallback bool - wantAbsence sourceVersionPathAbsence }{ { name: "missing mapping member is optional absence", input: "settings: {}\n", path: Keys("settings", "version"), mode: sourceVersionModeIfPresent, - role: sourceVersionContribution, wantPresent: false, wantAbsence: sourceVersionMemberMissing, + role: sourceVersionContribution, wantPresent: false, }, { name: "missing below scalar is optional absence", input: "settings: scalar\n", path: Keys("settings", "version"), mode: sourceVersionModeIfPresent, - role: sourceVersionContribution, wantPresent: false, wantAbsence: sourceVersionPathObstructed, + role: sourceVersionContribution, wantPresent: false, }, { name: "required absence reports nearest location", input: "settings: scalar\n", path: Keys("settings", "version"), mode: sourceVersionModeRequired, - role: sourceVersionContribution, wantCode: CodeVersionError, wantAbsence: sourceVersionPathObstructed, + role: sourceVersionContribution, wantCode: CodeVersionError, }, { name: "unavailable sequence index is absence", input: "versions: [1]\n", path: Keys("versions").Index(3), mode: sourceVersionModeRequired, - role: sourceVersionContribution, wantCode: CodeVersionError, wantAbsence: sourceVersionIndexUnavailable, + role: sourceVersionContribution, wantCode: CodeVersionError, }, { name: "required actual main absence", input: "name: demo\n", path: Keys("version"), - mode: sourceVersionModeRequired, role: sourceVersionMain, wantCode: CodeVersionError, wantAbsence: sourceVersionMemberMissing, + mode: sourceVersionModeRequired, role: sourceVersionMain, wantCode: CodeVersionError, }, { name: "main optional absence invokes checker", input: "name: demo\n", path: Keys("version"), - mode: sourceVersionModeIfPresent, role: sourceVersionMain, wantCallback: true, wantAbsence: sourceVersionMemberMissing, + mode: sourceVersionModeIfPresent, role: sourceVersionMain, wantCallback: true, }, {name: "boolean", input: "version: true\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true}, {name: "fraction", input: "version: 4.5\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true}, @@ -307,15 +306,9 @@ func TestSourceVersionExtractionHandlesMissingAndMalformedValues(t *testing.T) { if result.evidence == nil || result.evidence.version.Present != test.wantPresent { t.Fatalf("evidence = %#v", result.evidence) } - if result.evidence.absence != test.wantAbsence { - t.Fatalf("absence cause = %v, want %v", result.evidence.absence, test.wantAbsence) - } if test.wantCode == CodeVersionType && (!result.evidence.redacted || result.evidence.version.Text != "") { t.Fatalf("malformed value was retained: %#v", result.evidence) } - if !test.wantCallback && result.evidence.checked { - t.Fatalf("evidence incorrectly records a callback: %#v", result.evidence) - } }) } } @@ -339,7 +332,7 @@ func TestSourceVersionExtractionConsumesOnlySelectedNodes(t *testing.T) { if original, found := documentAtPath(root, Keys("settings", "version")); !found || original.Text != "8" { t.Fatalf("original source changed: %#v, found %v", original, found) } - if len(result.evidence.ancestors) != 3 || result.evidence.ancestors[1].kind != document.Mapping { + if len(result.evidence.ancestors) != 3 || result.evidence.ancestors[1].path.String() != "/settings" || result.evidence.ancestors[2].path.String() != "/settings/version" { t.Fatalf("ancestor shape = %#v", result.evidence.ancestors) } @@ -1492,7 +1485,7 @@ func TestSourceVersionOverlayProtectsMountedMainAndPreservesSequenceCoordinates( t.Fatalf("resolve overlay context: %#v", diagnostic) } request := selectedOverlayRequest{ - name: "testing", filesystem: resolved, protectionRule: effectiveRule, + name: "testing", protectionRule: effectiveRule, limits: defaultImportLimits(), versionState: state, } if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { @@ -1544,7 +1537,7 @@ func TestSourceVersionImportAccountingIncludesConsumedHeaderNodes(t *testing.T) if len(foundDiagnostics) != 0 || composed == nil || len(sources) != 2 || accounting.nodes != wantNodes || accounting.bytes != wantBytes { t.Fatalf("exact raw byte/node accounting = %#v, %d/%d, want %d/%d, %#v", composed, accounting.bytes, accounting.nodes, wantBytes, wantNodes, foundDiagnostics) } - if len(state.evidence) != 1 || state.evidence[0].sourceID != "source-2" || !state.evidence[0].checked || state.evidence[0].version.Text != "accepted" { + if len(state.evidence) != 1 || state.evidence[0].sourceID != "source-2" || state.evidence[0].version.Text != "accepted" { t.Fatalf("acquired child evidence = %#v", state.evidence) } if _, present := documentAtPath(composed.root, Keys("version")); present {