Complete single-source semantic validation
This commit is contained in:
@@ -38,7 +38,8 @@ The current lifecycle is:
|
||||
```text
|
||||
validate options → parse one source → reject reserved directives → build schema
|
||||
→ check the optional application version → create and clone defaults
|
||||
→ strictly decode → snapshot configuration and metadata
|
||||
→ strictly decode → recorded application resolution → semantic validation
|
||||
→ snapshot configuration and metadata
|
||||
```
|
||||
|
||||
`File`, `Bytes`, and `Reader` each contribute one base source with the deterministic
|
||||
@@ -46,17 +47,17 @@ ID `source-1`. `NoSource` skips parsing, supplies an absent version to a configu
|
||||
version checker, contributes no source, and continues through defaults, decode, and
|
||||
projection. A missing file remains an error; it is never interpreted as no input.
|
||||
|
||||
The current `Options` boundary accepts a defaults factory and `VersionRule`.
|
||||
Imports, active profiles, filesystem context, overrides, semantic validator
|
||||
callbacks, and dynamic secret classification return an explicit
|
||||
The current `Options` boundary accepts a defaults factory, `VersionRule`, resolver,
|
||||
and semantic validator. Imports, active profiles, filesystem context, overrides,
|
||||
and dynamic secret classification return an explicit
|
||||
`options.unavailable` error because their lifecycle stages are not implemented.
|
||||
The reserved profile spelling `default` selects no active profile. `NoSource`
|
||||
additionally rejects imports, active profiles, and filesystem context as invalid
|
||||
combinations. Input containing a reserved `_configkit` mapping key is rejected while
|
||||
imports are disabled.
|
||||
|
||||
Every source, options, schema, version, defaults, or decode failure returns a nil
|
||||
result and a `*LoadError`. Successful results contain caller-owned `Config`, detached
|
||||
Every source, options, schema, version, defaults, decode, resolution, or validation
|
||||
failure returns a nil result and a `*LoadError`. Successful results contain caller-owned `Config`, detached
|
||||
`Metadata`, a defensive source list, and defensive nonfatal diagnostics. Mutating
|
||||
the returned configuration or inspection records cannot alter ConfigKit's private
|
||||
snapshot. ConfigKit performs no logging and exposes no effective writer yet.
|
||||
@@ -122,6 +123,33 @@ retain history. ConfigKit privately snapshots each recorded before/after subtree
|
||||
later safe explanation; caller mutations of `Result.Config` cannot alter those
|
||||
snapshots.
|
||||
|
||||
### Semantic validation
|
||||
|
||||
An optional `Definition.Validate` callback runs after successful resolution and
|
||||
receives the resolved configuration plus a per-load `Validation` context. It can
|
||||
collect multiple independent `validate.error` and `validate.warning` reports.
|
||||
Warnings continue the lifecycle and are returned on success; any error returns a nil
|
||||
result with the full safe diagnostic and source report.
|
||||
|
||||
Primary and related paths must be valid for the application schema. Omitted declared
|
||||
fields and missing string-map or dynamic keys are valid report targets; unknown
|
||||
struct fields and malformed paths produce `validate.invalid_path`. ConfigKit attaches
|
||||
the exact surviving input location when one exists, otherwise the nearest input
|
||||
container location, or no primary location for defaults-only synthetic state.
|
||||
|
||||
Validation is read-only. ConfigKit projects the configuration immediately before and
|
||||
after the callback and returns `validate.mutation` at every detected net-change path,
|
||||
including nested mutable state. A value that can no longer be projected is also a
|
||||
mutation failure. No mutated or otherwise invalid configuration is published.
|
||||
Callback panics remain programming failures, and retained contexts use the same
|
||||
fixed closed-context panic as version and resolution callbacks.
|
||||
|
||||
Only schema-bound exported state participates in loading, resolution audit,
|
||||
validation audit, metadata, and snapshots. Ignored or unexported ordinary fields are
|
||||
zero in returned detached values. Applications retain responsibility for domain
|
||||
rules and runtime initialization; validators should not start clients or depend on
|
||||
live services as a substitute for configuration validation.
|
||||
|
||||
## YAML documents
|
||||
|
||||
The private YAML boundary currently accepts exactly one nonempty document whose root
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
This is the contributor entry point for ConfigKit. Read the task-specific owners
|
||||
below before making changes. The repository is in early implementation: its public
|
||||
loader currently covers one strict source, typed defaults, schema-version checks,
|
||||
recorded application resolution, and metadata. The
|
||||
recorded application resolution, semantic validation, and metadata. The
|
||||
[component overview](internal/overview.md) owns the implementation inventory.
|
||||
|
||||
## Initial orientation
|
||||
|
||||
@@ -203,6 +203,16 @@ intent, coalesced repeated writes, private before/after snapshots, deterministic
|
||||
record ordering, and safe hook diagnostics. Semantic validation remains assigned to
|
||||
the next lifecycle work.
|
||||
|
||||
Validation implementation record (2026-09-06): ConfigKit generalized Narratio's
|
||||
`TestNormalizeLoadAndValidate`, `TestRepresentativeLoadDefaultsAndValidation`,
|
||||
strict registry decoding, and maintained extraction-example expectations into the
|
||||
post-resolution `Validation` lifecycle and synthetic consumer examples. ConfigKit
|
||||
keeps domain rules application-owned, resolves schema-valid missing/dynamic report
|
||||
paths to nearest input locations, collects independent warnings/errors, and audits
|
||||
the full typed projection to reject validator mutation. Live resources, registries,
|
||||
campaign/session logic, commands, and application runtime initialization were not
|
||||
extracted.
|
||||
|
||||
### Secrets bootstrap
|
||||
|
||||
Assigned to the explicit bootstrap operation:
|
||||
|
||||
@@ -22,11 +22,13 @@ module and package documentation boundary. Its implemented public primitives are
|
||||
`load_metadata.go`; and
|
||||
- recorded application defaulting and normalization in `resolution.go`, including
|
||||
explicitness queries, helper verification, structural mutation audit, coalesced
|
||||
intent, private before/after snapshots, and resolution metadata integration.
|
||||
intent, private before/after snapshots, and resolution metadata integration; and
|
||||
- post-resolution schema-aware report collection and validator mutation detection in
|
||||
`validation.go`, completing the public single-source callback lifecycle.
|
||||
|
||||
The [configuration contract](../config.md) owns implemented input, schema, decoding,
|
||||
single-source lifecycle, version checking, recorded resolution, metadata, and
|
||||
ownership behavior.
|
||||
single-source lifecycle, version checking, recorded resolution, semantic validation,
|
||||
metadata, and ownership behavior.
|
||||
|
||||
The source-extraction inventory records the application foundations assigned to
|
||||
future implementation work:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status and ownership
|
||||
|
||||
Status: implementation in progress; Stages 1–8 are complete and later stages are
|
||||
Status: implementation in progress; Stages 1–9 are complete and later stages are
|
||||
pending.
|
||||
|
||||
Audience: a `gpt-5.6-terra` coding agent implementing one stage per prompt, in
|
||||
@@ -744,7 +744,37 @@ Acceptance:
|
||||
|
||||
## Stage 9 — Add semantic validation and finish the single-source lifecycle
|
||||
|
||||
Status: pending.
|
||||
Status: complete.
|
||||
|
||||
Completion evidence (2026-09-06):
|
||||
|
||||
- Reused `Validation` for post-resolution application reports in
|
||||
[`validation.go`](../../validation.go), with `validate.error`,
|
||||
`validate.warning`, and `validate.invalid_path` classifications. Omitted declared
|
||||
fields and missing string-map/dynamic keys remain valid report paths; unknown
|
||||
struct fields and malformed primary or related paths fail safely.
|
||||
- Attached exact or nearest input locations to primary and related reports, retained
|
||||
independent errors and warnings, continued through warnings, and returned no
|
||||
configuration on any semantic error. Version, decode, and resolution failures stop
|
||||
before later hooks.
|
||||
- Added before/after typed projection around the validator. Any net scalar,
|
||||
container, or nested mutable-state change, and any newly unprojectable value,
|
||||
returns `validate.mutation` without publishing the mutated object. Callback
|
||||
contexts close after invocation and callback panics remain programming failures.
|
||||
- Removed the semantic-validator options gate, finalized metadata only after
|
||||
successful resolution/validation, and retained defensive configuration snapshot,
|
||||
metadata, diagnostic, and source ownership. The
|
||||
[current semantic-validation contract](../config.md#semantic-validation) owns the
|
||||
completed single-source lifecycle and application/runtime-state boundary.
|
||||
- Added compiling executable examples in [`example_test.go`](../../example_test.go)
|
||||
for minimal loading, defaults-only operation, related-path validation, actionable
|
||||
schema-version guidance, and resolution followed by validation. Focused tests cover
|
||||
multiple reports, missing/dynamic paths, related/nearest locations, invalid paths,
|
||||
validator mutation, hook ordering and stop points, warnings, and final value/
|
||||
explicitness/origin/history agreement. 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;
|
||||
imports and profiles remain deliberately unavailable.
|
||||
|
||||
Read: feature [diagnostic callbacks](initial.md#resolution-and-validation-callbacks)
|
||||
and [schema reports](initial.md#schema-checking-and-secret-classification).
|
||||
|
||||
@@ -582,10 +582,10 @@ independently captured resolved results are implemented. The
|
||||
[current ownership contract](../config.md#typed-projection-and-ownership) owns those
|
||||
mechanics.
|
||||
|
||||
Application semantic validation runs after successful resolution and collects
|
||||
independent errors in a standard diagnostic form. Validators are read-only and
|
||||
own domain requirements; checking live S3 buckets or starting runtime clients
|
||||
is outside this lifecycle. Do not run later hooks on an invalid typed value.
|
||||
Application semantic validation is implemented. The
|
||||
[current semantic-validation contract](../config.md#semantic-validation) owns
|
||||
schema-aware reporting, nearest locations, warning/error behavior, mutation audit,
|
||||
callback lifetime, and application/runtime responsibility boundaries.
|
||||
|
||||
## Provenance, diagnostics, and redaction
|
||||
|
||||
@@ -795,9 +795,10 @@ behavior. Layered callback history and safe historical values remain target beha
|
||||
|
||||
### Resolution and validation callbacks
|
||||
|
||||
The resolution declarations and behavior below are implemented; the
|
||||
[current recorded-resolution contract](../config.md#recorded-application-resolution)
|
||||
is authoritative. Semantic validation behavior in this section remains target work.
|
||||
The resolution and semantic-validation declarations and behavior below are
|
||||
implemented. The [current recorded-resolution contract](../config.md#recorded-application-resolution)
|
||||
and [semantic-validation contract](../config.md#semantic-validation) are
|
||||
authoritative.
|
||||
|
||||
```go
|
||||
func (r *Resolution) IsExplicit(path Path) bool
|
||||
|
||||
Reference in New Issue
Block a user