Project version protections through item placement

This commit is contained in:
2026-10-16 19:11:08 +00:00
parent 190431740a
commit c19825620c
10 changed files with 276 additions and 50 deletions

View File

@@ -37,6 +37,40 @@ func TestSourceVersionAbsentPathKeepsUnresolvedSegmentIntent(t *testing.T) {
}
}
func TestFragmentVersionClaimUsesAssignedSequenceProjection(t *testing.T) {
t.Parallel()
fragment := sourceVersionTestDocument(t, "items: [{version: v1}]\n")
rangeForPeer := []sequenceRange{{sourceIndex: 1, path: Keys("items"), start: 1, end: 2}}
if node := fragmentVersionClaimProjected(fragment, &VersionRule{Path: Keys("items").Index(0).Key("version")}, 1, rangeForPeer); node != nil {
t.Fatalf("peer append claimed main index 0: %#v", node)
}
if node := fragmentVersionClaimProjected(fragment, &VersionRule{Path: Keys("items").Index(1).Key("version")}, 1, rangeForPeer); node == nil || node.Text != "v1" {
t.Fatalf("assigned peer index 1 claim = %#v, want its version node", node)
}
nested := sourceVersionTestDocument(t, "items: [{nested: [{version: nested-v}]}]\n")
nestedRanges := []sequenceRange{
{sourceIndex: 1, path: Keys("items"), start: 1, end: 2},
{sourceIndex: 1, path: Keys("items").Index(0).Key("nested"), start: 2, end: 3},
}
if node := fragmentVersionClaimProjected(nested, &VersionRule{Path: Keys("items").Index(1).Key("nested").Index(2).Key("version")}, 1, nestedRanges); node == nil || node.Text != "nested-v" {
t.Fatalf("nested assigned claim = %#v, want nested version", node)
}
ancestor := sourceVersionTestDocument(t, "items: {version: replacement}\n")
if node := fragmentVersionClaim(ancestor, &VersionRule{Path: Keys("items").Index(0).Key("version")}); node == nil || node.Kind != document.Mapping {
t.Fatalf("destructive sequence ancestor claim = %#v, want mapping node", node)
}
effective := effectiveSourceVersionRuleForPlacement(&VersionRule{Path: Keys("version")}, Keys("catalog", "entries"), sourceVersionModeRequired, placementModeSequenceItem)
if got, want := effective.Path.String(), "/catalog/entries/0/version"; got != want {
t.Fatalf("item effective version path = %q, want %q", got, want)
}
defaultRule := effectiveSourceVersionRuleForPlacement(&VersionRule{Path: Keys("version")}, Keys("catalog", "entries"), sourceVersionModeDefault, placementModeSequenceItem)
if got, want := defaultRule.Path.String(), "/version"; got != want {
t.Fatalf("default effective version path = %q, want %q", got, want)
}
}
type sourceVersionMountedService struct {
Version string `yaml:"version"`
}
@@ -473,6 +507,83 @@ func TestSourceVersionLoadChecksMountedMainLocallyAndProtectsEffectivePath(t *te
}
}
func TestSourceVersionItemPlacementKeepsLocalChecksAndProtectsProjectedPath(t *testing.T) {
t.Parallel()
for _, test := range []struct {
name string
load func(Definition[map[string]any]) error
}{
{
name: "ordinary",
load: func(definition Definition[map[string]any]) error {
_, err := Load(Mapping("main", map[string]any{"version": "v1", "name": "ordinary"}), testSecretBinding(), Options[map[string]any]{
Definition: definition, SourceVersionMode: sourceVersionModeRequired,
destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem,
Overrides: []Override{{Path: Keys("catalog", "entries"), Value: []any{}, Flag: "--entries"}},
})
return err
},
},
{
name: "layered",
load: func(definition Definition[map[string]any]) error {
_, err := LoadLayered(Input{Source: Mapping("main", map[string]any{"version": "v1", "name": "layered"}), Destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem}, testSecretBinding(), LayeredOptions[map[string]any]{
Definition: definition, SourceVersionMode: sourceVersionModeRequired,
Overrides: []Override{{Path: Keys("catalog", "entries"), Value: []any{}, Flag: "--entries"}},
})
return err
},
},
} {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
checks := 0
definition := Definition[map[string]any]{Version: &VersionRule{
Path: Keys("version"),
Check: func(version Version, _ *Validation) error {
checks++
if !version.Present || version.Text != "v1" {
t.Errorf("source-local version = %#v, want v1", version)
}
return nil
},
}}
err := test.load(definition)
var loadErr *LoadError
if !errors.As(err, &loadErr) {
t.Fatalf("item placement override error = %T %v, want *LoadError", err, err)
}
requireSourceVersionDiagnostic(t, loadErr.Diagnostics(), CodeOverrideVersion, "/catalog/entries")
if checks != 1 {
t.Fatalf("source-version checker called %d times, want once", checks)
}
})
}
}
func TestSourceVersionItemEvidenceUsesProjectedSensitivityPath(t *testing.T) {
t.Parallel()
const canary = "PROJECTED-VERSION-EVIDENCE-CANARY"
secretPath := Keys("catalog", "entries").Index(0).Key("version")
loaded, err := Load(Mapping("main", map[string]any{"version": canary}), testSecretBinding(), Options[map[string]any]{
Definition: Definition[map[string]any]{
Version: &VersionRule{Path: Keys("version"), Check: func(Version, *Validation) error { return nil }},
Secret: func(path Path) bool { return path.String() == secretPath.String() },
},
SourceVersionMode: sourceVersionModeRequired,
destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem,
})
if err != nil {
t.Fatalf("item source-version load: %v", err)
}
sources := loaded.Inspection.Sources()
if len(sources) != 1 || sources[0].VersionCheck == nil || !sources[0].VersionCheck.Redacted || sources[0].VersionCheck.Version.Text != "" {
t.Fatalf("projected source-version evidence was not redacted: %#v", sources)
}
}
func TestSourceVersionLoadChecksNullAndNoSourceMain(t *testing.T) {
t.Parallel()