Define identified configuration resources

This commit is contained in:
2026-11-02 03:53:09 +00:00
parent 0b271267a0
commit aba890aa86
3 changed files with 51 additions and 12 deletions

View File

@@ -243,6 +243,14 @@ Validation: inspect the registration selectors and schema; when runnable, load
one headerless root list and one version-2 collection. Resolution/validation
callers are completed in the following stages.
Completion: the typed document now uses identified resource slices, registers
all six root and collection identity rules, and checks specification version 2.
Added a focused root/collection list fixture and reviewed the selectors and
schema. The focused test cannot yet compile because field capture, resolution,
validation, indexing, prompt materialization, and older fixtures still expect
maps; those migrations are assigned to the following stages. Formatting and
`git diff --check` passed; execution of the new fixture remains deferred.
## Stage 4: Preserve Field Presence And Resolution At List Paths
Scope: backend/profile field capture, normalization, and defaulting in

View File

@@ -18,20 +18,21 @@ import (
type document struct {
Version *string `yaml:"version"`
Backends map[string]backendConfig `yaml:"backends"`
Profiles map[string]profileConfig `yaml:"profiles"`
Prompts map[string]promptConfig `yaml:"prompts"`
Backends []backendConfig `yaml:"backends"`
Profiles []profileConfig `yaml:"profiles"`
Prompts []promptConfig `yaml:"prompts"`
Collections map[string]collectionConfig `yaml:"collections"`
}
type collectionConfig struct {
ReleaseVersion *string `yaml:"release_version"`
Backends map[string]backendConfig `yaml:"backends"`
Profiles map[string]profileConfig `yaml:"profiles"`
Prompts map[string]promptConfig `yaml:"prompts"`
ReleaseVersion *string `yaml:"release_version"`
Backends []backendConfig `yaml:"backends"`
Profiles []profileConfig `yaml:"profiles"`
Prompts []promptConfig `yaml:"prompts"`
}
type backendConfig struct {
ID string `yaml:"id"`
Endpoint *string `yaml:"endpoint"`
APIKeyEnv *string `yaml:"api_key_env"`
ConcurrencyLimit *int `yaml:"concurrency_limit"`
@@ -56,6 +57,7 @@ type authenticationProbeConfig struct {
}
type profileConfig struct {
ID string `yaml:"id"`
Backend *string `yaml:"backend"`
Endpoint *string `yaml:"endpoint"`
Model *string `yaml:"model"`
@@ -71,7 +73,7 @@ type profileConfig struct {
}
type promptConfig struct {
Version *string `yaml:"version"`
ID string `yaml:"id"`
DefaultProfile *string `yaml:"default_profile"`
Description *string `yaml:"description"`
SessionID *string `yaml:"session_id"`
@@ -141,9 +143,9 @@ type resourceSet struct {
isCollection bool
namespace string
bases resourceBases
backends map[string]backendConfig
profiles map[string]profileConfig
prompts map[string]promptConfig
backends []backendConfig
profiles []profileConfig
prompts []promptConfig
}
func rootResourceBases() resourceBases {
@@ -230,6 +232,14 @@ func load(main configkit.Input, underlays []configkit.Underlay) (*loaded, error)
Underlays: underlays,
SourceVersionMode: configkit.SourceVersionModeIfPresent,
Definition: configkit.Definition[document]{
SequenceIdentities: []configkit.SequenceIdentity{
configkit.SequenceIdentityAt(configkit.Keys("backends"), "id"),
configkit.SequenceIdentityAt(configkit.Keys("profiles"), "id"),
configkit.SequenceIdentityAt(configkit.Keys("prompts"), "id"),
configkit.SequenceIdentityMatching(configkit.SequenceSelector{configkit.SequenceLiteralKey("collections"), configkit.SequenceAnyMappingKey(), configkit.SequenceLiteralKey("backends")}, "id"),
configkit.SequenceIdentityMatching(configkit.SequenceSelector{configkit.SequenceLiteralKey("collections"), configkit.SequenceAnyMappingKey(), configkit.SequenceLiteralKey("profiles")}, "id"),
configkit.SequenceIdentityMatching(configkit.SequenceSelector{configkit.SequenceLiteralKey("collections"), configkit.SequenceAnyMappingKey(), configkit.SequenceLiteralKey("prompts")}, "id"),
},
Version: &configkit.VersionRule{
Path: configkit.Keys("version"),
Check: checkConfigurationVersion,
@@ -302,7 +312,7 @@ func checkConfigurationVersion(version configkit.Version, validation *configkit.
if !version.Present {
return nil
}
if version.Null || version.Text != "1" {
if version.Null || version.Text != "2" {
validation.Error(configkit.Keys("version"), "unsupported configuration specification version")
}
return nil

View File

@@ -12,6 +12,27 @@ func mapping(label string, values map[string]any) configkit.Input {
return configkit.Input{Source: configkit.Mapping(label, values)}
}
func TestLoadIdentifiedResourceLists(t *testing.T) {
for _, header := range []bool{false, true} {
values := map[string]any{
"backends": []any{map[string]any{"id": "local", "endpoint": "https://example.invalid/v1"}},
"collections": map[string]any{"team": map[string]any{
"backends": []any{map[string]any{"id": "local", "endpoint": "https://example.invalid/v1"}},
}},
}
if header {
values["version"] = "2"
}
loaded, err := load(mapping("identified resources", values), nil)
if err != nil {
t.Fatalf("load identified resources with header %t: %v", header, err)
}
if loaded.result.Config.Backends[0].ID != "local" || loaded.result.Config.Collections["team"].Backends[0].ID != "local" {
t.Fatal("identified root and collection resources were not retained")
}
}
}
func TestLoadChecksOptionalConfigurationVersion(t *testing.T) {
for _, test := range []struct {
name string