Add audited application resolution
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status and ownership
|
||||
|
||||
Status: implementation in progress; Stages 1–7 are complete and later stages are
|
||||
Status: implementation in progress; Stages 1–8 are complete and later stages are
|
||||
pending.
|
||||
|
||||
Audience: a `gpt-5.6-terra` coding agent implementing one stage per prompt, in
|
||||
@@ -684,7 +684,36 @@ Acceptance:
|
||||
|
||||
## Stage 8 — Implement recorded application resolution
|
||||
|
||||
Status: pending.
|
||||
Status: complete.
|
||||
|
||||
Completion evidence (2026-09-06):
|
||||
|
||||
- Implemented per-load `Resolution`, `IsExplicit`, `Record`, `Default`, `Normalize`,
|
||||
`Error`, and `Warning` in [`resolution.go`](../../resolution.go), and enabled the
|
||||
resolver in `Load` after successful decode while leaving semantic validation gated.
|
||||
- Added schema-aware path/kind/dependency checks, safe reason requirements, dynamic
|
||||
and typed helper projection, final helper/path consistency checks, before/after
|
||||
structural comparison, exact/ancestor record coverage, and distinct safe failures
|
||||
for invalid values, targets, records, and unrecorded changes.
|
||||
- Coalesced repeated path intent deterministically, retaining unique reasons and
|
||||
dependencies, using the last helper value, and promoting mixed operations to
|
||||
normalization. Equal-valued derived intent remains recorded; map copy/writeback,
|
||||
container coverage, deletions, and new dynamic/map descendants are supported.
|
||||
- Integrated resolution origins and history without changing surviving input
|
||||
explicitness, retained private detached before/after snapshots, sorted records by
|
||||
semantic path, and made retained callback-context use panic with fixed value-free
|
||||
text. Resolver errors are suppressed unless explicitly reported through the
|
||||
context; warnings remain on successful results. The
|
||||
[current resolution contract](../config.md#recorded-application-resolution) owns
|
||||
this behavior.
|
||||
- Focused tests execute the timeout/artifact consumer shape, explicit null/zero and
|
||||
absent-baseline behavior, normalization, map writeback, equal and repeated helper
|
||||
intent, stable map-derived record order, subtree removal, snapshot detachment,
|
||||
unrelated targets, invalid paths/kinds/values, unrecorded mutation, safe hook
|
||||
failures, and closed resolution/version contexts. 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;
|
||||
semantic validation remains later work.
|
||||
|
||||
Read: feature [resolution callbacks](initial.md#resolution-and-validation-callbacks).
|
||||
|
||||
|
||||
@@ -571,37 +571,16 @@ rendering remain target work below.
|
||||
|
||||
## Recorded resolution and validation
|
||||
|
||||
Application-owned resolution runs after decoding and may derive absent values
|
||||
or normalize explicitly configured ones. Provide a narrow resolution context
|
||||
that exposes metadata and records each changed semantic path, operation kind
|
||||
(derived default or normalization), and a safe reason. Dependency paths may be
|
||||
recorded when a value is derived from other fields.
|
||||
Application-owned recorded resolution is implemented. The
|
||||
[current resolution contract](../config.md#recorded-application-resolution) owns
|
||||
explicitness queries, helpers and manual records, structural mutation auditing,
|
||||
coalescing, diagnostics, origins, history, and snapshot ownership. Layered input
|
||||
history, redacted explanation, and secret dependency propagation remain target work.
|
||||
|
||||
A resolver may mutate the typed configuration, but ConfigKit compares its
|
||||
before/after configuration projection and requires records for changed paths.
|
||||
Unrecorded changes are resolution errors. Container replacement records cover
|
||||
changed descendants. Capture previous/final values internally from the actual
|
||||
configuration rather than trusting separately supplied values. Application
|
||||
resolvers own meaningful reasons; a diff alone cannot explain intent. Reasons
|
||||
must not embed secrets. The proposed [resolution API](#resolution-and-validation-callbacks)
|
||||
provides helpers to combine assignments and records. Snapshot comparison verifies
|
||||
net changes during the hook; it does not reconstruct intermediate assignments.
|
||||
A record describes the hook's before/final transition and declared intent, not an
|
||||
automatically recovered event log. Equal-valued derived-default assignments may
|
||||
still have a record identifying their intent. Multiple records at the same path
|
||||
are coalesced for that hook, retaining declared reasons and dependencies.
|
||||
|
||||
The final configuration, effective output, presence queries, and explanation
|
||||
records must agree. Do not render the pre-resolution YAML tree as the final
|
||||
configuration. ConfigKit promises an independently owned snapshot it does not
|
||||
subsequently mutate, not language-enforced immutability of exported Go values.
|
||||
Callers should treat returned configuration as read-only; later caller mutations
|
||||
are outside the captured metadata snapshot.
|
||||
|
||||
Canonical typed projection, detached cloning, and structural comparison are now
|
||||
implemented as private foundations. The [current ownership contract](../config.md#typed-projection-and-ownership)
|
||||
owns those mechanics; publishing independently captured results remains lifecycle
|
||||
work.
|
||||
Canonical typed projection, detached cloning, structural comparison, and publishing
|
||||
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
|
||||
@@ -613,7 +592,9 @@ is outside this lifecycle. Do not run later hooks on an invalid typed value.
|
||||
Safe diagnostic/provenance value records, canonical diagnostic rendering, and
|
||||
`LoadError` access are implemented. Their current contracts are owned by
|
||||
[`records.go`](../../records.go) and [`diagnostic.go`](../../diagnostic.go).
|
||||
Attaching those records to the loading lifecycle remains target work below.
|
||||
Base/default and resolution records are attached to the current loading lifecycle.
|
||||
Additional layers, safe historical values, redaction, and rendering remain target
|
||||
work below.
|
||||
|
||||
Retain input sources, layer, line/column where available, import sites, effective
|
||||
origins, overridden definition records, and resolution operations. Container
|
||||
@@ -814,6 +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.
|
||||
|
||||
```go
|
||||
func (r *Resolution) IsExplicit(path Path) bool
|
||||
func (r *Resolution) Record(path Path, kind ChangeKind, reason string, dependencies ...Path)
|
||||
|
||||
Reference in New Issue
Block a user