Add single-source loading and version checks

This commit is contained in:
2026-09-06 20:03:22 +00:00
parent 21e3f633bc
commit cc41653bfd
13 changed files with 1022 additions and 38 deletions

View File

@@ -2,7 +2,7 @@
## Status and ownership
Status: implementation in progress; Stages 1–6 are complete and later stages are
Status: implementation in progress; Stages 1–7 are complete and later stages are
pending.
Audience: a `gpt-5.6-terra` coding agent implementing one stage per prompt, in
@@ -619,7 +619,37 @@ Acceptance:
## Stage 7 — Assemble single-source loading and schema-version checks
Status: pending.
Status: complete.
Completion evidence (2026-09-06):
- Added the public generic `Load`, `Definition`, `Options`, `Result`, version,
filesystem-context, override, validation-context, and reserved resolution
declarations in [`load.go`](../../load.go) and [`validation.go`](../../validation.go).
The active lifecycle validates options, parses one source, rejects reserved
directives, builds the schema, checks an optional application version, creates
fresh defaults, decodes, and captures detached state.
- Added absent/null/string version handling, non-string rejection, exact/nearest
primary and related input locations, safe application reports, warning retention,
and generic value-free hook failure only when no explicit error was reported.
Defaults run only after version success and exactly once for a continuing load.
- Populated effective base/default `Metadata` and chronological definition history
in [`load_metadata.go`](../../load_metadata.go), with explicit and null state,
synthetic default origins, base coordinates, equal-valued input records, and
defensive result/source/diagnostic copies. `NoSource` performs the same schema,
version, defaults, decode, and projection lifecycle without a source record.
- Added explicit `options.unavailable` gates for resolution, semantic validation,
imports, active profiles, filesystem context, overrides, and secret classification;
invalid `NoSource` combinations and `_configkit` directives fail rather than being
ignored. The [current single-source contract](../config.md#single-source-loading),
package documentation, README, and component inventory own the implemented API.
- Integration tests cover File/Bytes/Reader/NoSource, schema-version states and
warnings, related locations, raw hook-error suppression, fresh-default ordering,
metadata agreement and detachment, source lists, unavailable options, reserved
directives, and nil results for source/schema/version/decode failures. Verified
`go test ./...`, `go test -race ./...`, `go vet ./...`, `go build ./...`,
`go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on linux/amd64. No
deviations were required; resolution and semantic validation remain later work.
Read: feature [lifecycle](initial.md#resolution-lifecycle),
[version hook](initial.md#schema-checking-and-secret-classification),

View File

@@ -425,15 +425,16 @@ configuration is never returned as a successful, usable result.
Source ownership, the supported YAML subset, scalar grammar, fixed input limits,
and safe failure behavior are implemented. The [current configuration input
contract](../config.md) now owns those definitions. Typed scalar conversion into
application values remains target work in [typed decoding](#typed-decoding).
contract](../config.md) now owns those definitions, including typed scalar
conversion through the current single-source lifecycle.
## Paths and presence
Semantic path construction, JSON Pointer parsing, and current metadata query
declarations are implemented. Their current contracts are owned by the Go
documentation in [`path.go`](../../path.go) and [`metadata.go`](../../metadata.go).
The remaining presence behavior below is target lifecycle work.
Semantic path construction, JSON Pointer parsing, and base/default metadata
population are implemented. Their current contracts are owned by the Go
documentation in [`path.go`](../../path.go), [`metadata.go`](../../metadata.go),
and the [single-source configuration contract](../config.md#base-default-metadata).
Layered replacement and resolution behavior below remains target lifecycle work.
Distinguish absent, explicitly null, explicitly zero/false/empty, and other
explicit values. An explicit value equal to its default remains explicit.
@@ -672,8 +673,11 @@ Automatic migration is deferred.
## Consumer API design
The following is a proposed public API, not implemented Go reference documentation
or a frozen naming commitment. Declarations omit method bodies and private fields.
The core declarations and single-source loading subset are implemented; their
current contract is owned by [configuration input](../config.md#single-source-loading)
and Go reference comments. Remaining declarations and behavior in this section are
target design, not implemented Go reference documentation or a frozen naming
commitment. Declarations omit method bodies and private fields.
Consumer snippets assume the indicated standard-library imports and a `configkit`
import using the module path selected in the [implementation plan](implementation.md#implementation-decisions).
They are illustrative target examples, not currently runnable examples. The
@@ -682,6 +686,13 @@ and verification against consumer models.
### Entry point and reusable application definition
`Load`, `Definition`, `Options`, `FilesystemContext`, `Override`, `VersionRule`,
`Version`, `Validation`, and `Result` are declared. The current loader accepts only
the defaults and version-checking subset described by the
[single-source contract](../config.md#single-source-loading); later-feature fields
fail explicitly rather than being ignored. The complete lifecycle and option
behavior below remains the target as its owning stages land.
```go
func Load[T any](source Source, options ...Options[T]) (*Result[T], error)
@@ -795,11 +806,11 @@ func ReadWorkerDefaults() (*configkit.Result[Config], error) {
### Paths and metadata
The path API, detached metadata records, and empty/unknown query behavior are now
implemented; [`path.go`](../../path.go), [`records.go`](../../records.go), and
[`metadata.go`](../../metadata.go) own their current Go contracts. Populating
effective presence, origins, and history belongs to the loading stages. Callback
path checking and safe historical values remain target behavior below.
The path API, detached metadata records, empty/unknown query behavior, and
base/default population are now implemented; [`path.go`](../../path.go),
[`records.go`](../../records.go), [`metadata.go`](../../metadata.go), and the
[metadata configuration contract](../config.md#base-default-metadata) own current
behavior. Layered callback history and safe historical values remain target behavior.
### Resolution and validation callbacks
@@ -970,6 +981,12 @@ potentially sensitive configured values.
### Schema checking and secret classification
`VersionRule`, `Version`, and the version-checking use of `Validation` are
implemented. The [current version contract](../config.md#application-schema-versions)
owns absent/null/string handling, report locations, warnings, failure behavior, and
raw-error suppression. Secret classification and later composed-source placement
checks remain target work.
```go
type VersionRule struct {
Path Path
@@ -1030,6 +1047,12 @@ applications own secret-producing transformations not described by those records
### Results, errors, and inspection
`Result.Config`, `Metadata`, `Sources`, and `Diagnostics`, together with
`LoadError` and `WriteDiagnostics`, are implemented at the single-source boundary.
The [current loading contract](../config.md#single-source-loading) and Go reference
comments own their behavior. Effective rendering and richer layered inspection
below remain target work.
```go
type Result[T any] struct {
Config T