Document field-level resolution and matched sequence history
This commit is contained in:
@@ -772,6 +772,15 @@ in history. Across tiers, history follows the selected
|
||||
whole-record upsert. Incoming contributions use their assigned positions, and
|
||||
replaced payload remains available as historical evidence.
|
||||
|
||||
During resolution, eligible application-registered records are matched between
|
||||
entry and final snapshots by identity at the same collection destination.
|
||||
Queries at a surviving final position follow that record's entry history, while
|
||||
collection queries retain physical ordering and removed evidence. For example,
|
||||
if `[reports, invoices]` becomes `[invoices]`, item 0 follows invoices' earlier
|
||||
position, the collection retains reports' removal, and the absent old item 1
|
||||
remains available through historical-position queries. An added identity does
|
||||
not inherit the old occupant's history. Source locations stay source-local.
|
||||
|
||||
A mapping assembled from the selected file and imports has one composite base origin
|
||||
whose locations follow [scoped assembly order](#explicit-imports), not source-record
|
||||
acquisition order. A mapping also visited by an overlay has an overlay-layer
|
||||
@@ -1198,6 +1207,18 @@ records, helper targets, and unrecorded mutations fail the load. Equal-valued
|
||||
derived assignments may still record application intent even when there is no
|
||||
structural change.
|
||||
|
||||
Resolution compares equal-length ordinary lists recursively by position, so an
|
||||
edit to `/resources/0/path` can be recorded at that field. A length change needs
|
||||
a list or ancestor record. For application-registered collections, valid unique
|
||||
entry and final identities match records at the same destination; changing order
|
||||
or membership still requires list or ancestor coverage. Invalid or duplicate
|
||||
endpoint identities make a changed list atomic for auditing, without an early
|
||||
identity error; final registration validation remains at its normal boundary.
|
||||
YAML-only declarations do not provide this correspondence. Records and helper
|
||||
targets use final positions, and helpers never follow a later move automatically.
|
||||
Fixed entry queries continue to use entry positions. See
|
||||
[ADR 0021](adr/0021-sequence-resolution-correspondence.md) for the decision.
|
||||
|
||||
`Resolution.Error` and `Resolution.Warning` attach exact or nearest available input
|
||||
locations. Reported errors fail the load; warnings survive on a successful result. A
|
||||
returned resolver error adds one generic `resolve.hook_failed` error only when the
|
||||
@@ -1356,7 +1377,7 @@ Incompatible overlaps and invalid registrations produce `options.invalid` before
|
||||
source acquisition. Unused and root registrations are allowed and have no effect.
|
||||
|
||||
Registrations provide identity for strict composition, sequence operations,
|
||||
inheritance lookup, and final validation. Dynamic selectors apply at concrete
|
||||
inheritance lookup, resolution correspondence, and final validation. Dynamic selectors apply at concrete
|
||||
strict-composition, inheritance, and final-result destinations without requiring
|
||||
the application to enumerate mapping keys. Each strict tier has independent
|
||||
duplicate-identity state among its peers; layered precedence and inheritance
|
||||
@@ -2056,10 +2077,10 @@ rebuilt by unmarshaling their canonical text into fresh values, detaching privat
|
||||
backing storage. Ignored and unexported struct fields are zeroed rather than copied.
|
||||
|
||||
Private structural comparison operates on canonical trees. Mapping additions,
|
||||
removals, and descendant replacements retain semantic paths. A sequence is atomic:
|
||||
any sequence change reports the sequence path and never invents correspondence
|
||||
between old and new indices. Cross-kind and null/container changes replace the
|
||||
affected path.
|
||||
removals, and descendant replacements retain semantic paths. The shared
|
||||
comparison used by effective diff treats sequences atomically. Resolution uses
|
||||
its separate positional and registered-identity comparison described above.
|
||||
Cross-kind and null/container changes replace the affected path.
|
||||
|
||||
These mechanisms support decoding, resolution auditing, metadata,
|
||||
and rendering. They are not a public generic conversion or cloning API.
|
||||
|
||||
@@ -65,6 +65,7 @@ Accepted decisions:
|
||||
- [Apply CLI overrides after inheritance and decoding](adr/0018-cli-after-structural-resolution.md)
|
||||
- [Keep main-file discovery explicit and composable](adr/0019-explicit-configuration-discovery.md)
|
||||
- [Scope configuration controls to document roots](adr/0020-document-root-controls.md)
|
||||
- [Match registered records during resolution inspection](adr/0021-sequence-resolution-correspondence.md)
|
||||
|
||||
For cross-cutting changes, follow every applicable row. Completed implementation
|
||||
and remediation plans are preserved in Git history at `cb5b435`; use current
|
||||
@@ -285,6 +286,7 @@ code changes. Use the component overview to find the corresponding implementatio
|
||||
| Shared source-version modes and evidence | [Engine source-version tests](../internal/engine/source_version_test.go), [public facade tests](../facade_source_version_mode_test.go), and [consumer example tests](../examples/consumers/layered_test.go) | `go test ./internal/engine -run 'SourceVersion'`, `go test . -run 'SourceVersion'`, and `go test ./examples/consumers` |
|
||||
| Schema, defaults, projection, cloning | [Implementation flow](internal/overview.md#implementation-flow), [schema](../internal/engine/schema_test.go), [decoding](../internal/engine/decode_test.go), [projection and typed cloning](../internal/engine/projection_test.go) | `go test ./internal/engine -run 'Schema\|Decode\|Projection\|Clone\|Inline\|CompareDocument'` |
|
||||
| Lifecycle, resolution, validation, callback ownership | [Loading](../internal/engine/load_test.go), [resolution](../internal/engine/resolution_test.go), [validation](../internal/engine/validation_test.go), [ownership](../internal/engine/callback_ownership_test.go), [independence](../internal/engine/independence_test.go) | `go test ./internal/engine -run 'Load\|Resolution\|Validation\|Validator\|Hook\|Callback\|Parallel'` |
|
||||
| Resolution sequence matching and inspection | [Correspondence](../internal/engine/resolution_correspondence_test.go), [auditing and history](../internal/engine/resolution_compare_test.go), [public integration](../facade_resolution_sequences_test.go) | `go test ./internal/engine -run 'Resolution\|History\|Explain\|Sensitivity'` and `go test . -run 'Resolution\|SequenceIdentity\|Diff'` |
|
||||
| Paths, metadata, provenance | [Paths](../internal/engine/path_test.go), [metadata](../internal/engine/metadata_test.go), [provenance](../internal/engine/provenance_test.go) | `go test ./internal/engine -run 'Path\|Metadata\|Provenance\|Queries'` |
|
||||
| Passive resource contexts | [Engine contexts](../internal/engine/resource_context_test.go), [public contexts](../facade_resource_context_test.go) | `go test ./internal/engine -run 'Resource'` and `go test . -run 'SourceContext'` |
|
||||
| Secrets, bootstrap, redaction, explanation | [References](../internal/engine/secret_reference_test.go), [bootstrap](../internal/engine/secrets_test.go), [rendering](../internal/engine/render_test.go), [explanation](../internal/engine/explain_test.go) | `go test ./internal/engine -run 'Secret\|Bootstrap\|Effective\|Explain\|Explanation\|History\|Sensitivity'` |
|
||||
|
||||
@@ -161,6 +161,9 @@ before application resolution begins. The callback retains its separate fixed
|
||||
entry view; it does not read a builder that continues to change. After successful
|
||||
resolution auditing, [`resolveLoadInput`](../../internal/engine/load_result.go)
|
||||
adds the original resolution records and their net replay groups. At the existing
|
||||
resolution boundary, [`resolution_correspondence.go`](../../internal/engine/resolution_correspondence.go)
|
||||
matches eligible registered records and the shared history retains their paired
|
||||
coordinates for selection and safe replay. At the existing
|
||||
pre-secret admission boundary, [`prepareInspectionHistory`](../../internal/engine/load_result.go)
|
||||
freezes that builder and counts the retained document roots before secret lookup
|
||||
and validation.
|
||||
|
||||
@@ -376,6 +376,11 @@ it does not cover every intermediate callback state or later caller mutations.
|
||||
YAML-only declarations carry no such final guarantee through defaults, CLI
|
||||
assignments, or application resolution.
|
||||
|
||||
For resolution auditing and inspection, eligible registered collections match
|
||||
entry and final records by identity within each destination. Structural changes
|
||||
still require container coverage, and this correspondence does not change source
|
||||
composition or move final validation earlier. Public diff remains sequence-atomic.
|
||||
|
||||
Preserve source attribution, presence, history, sensitivity, and resource context
|
||||
as records survive, move, or are replaced. Identity diagnostics use paths and
|
||||
available origin information without exposing identity values. The guarantee
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Sequence resolution and inspection implementation plan
|
||||
|
||||
Status: complete.
|
||||
|
||||
## Scope and execution
|
||||
|
||||
Implement the agreed [feature roadmap](resolution-sequences.md) from baseline
|
||||
@@ -423,6 +425,8 @@ no exported type, selector, or callback lifecycle change is needed.
|
||||
|
||||
## Stage 13 — Document the implemented contract and validate the sprint
|
||||
|
||||
**Status:** Complete. Focused engine, facade, and consumer checks, `go test -race ./...`, and `./scripts/check.sh` passed with Go 1.27.0 on Linux.
|
||||
|
||||
**Scope:** canonical documentation and final integration checks.
|
||||
|
||||
1. Update `docs/config.md` resolution, layered metadata, historical explanation,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Field-level resolution and identity-aware sequence history
|
||||
|
||||
Status: agreed direction; not implemented. This roadmap describes field-level
|
||||
Status: implemented. This roadmap records field-level
|
||||
resolution auditing and identity-aware inspection of registered collections.
|
||||
The [implementation plan](implementation.md) owns execution order and verification.
|
||||
|
||||
@@ -17,27 +17,25 @@ inspection. For ordinary lists, position is the only available correspondence;
|
||||
compare positions as addresses without inferring which application object an
|
||||
element represents.
|
||||
|
||||
## Current baseline
|
||||
## Prior baseline
|
||||
|
||||
The [resolution contract](../config.md#recorded-application-resolution) audits
|
||||
the typed configuration before and after `Definition.Resolve`. Mappings are
|
||||
compared recursively, while the private structural comparator reports any list
|
||||
change at the whole-list path. A field-level record inside a changed list
|
||||
therefore fails to cover that list-level delta. Recording the whole list works.
|
||||
At the planning baseline, the resolution contract audited the typed configuration
|
||||
before and after `Definition.Resolve`. Mappings were compared recursively, while
|
||||
the private structural comparator reported any list change at the whole-list
|
||||
path. A field-level record inside a changed list therefore failed to cover that
|
||||
list-level delta. Recording the whole list worked.
|
||||
|
||||
For example, changing `/resources/0/path` and recording only that path currently
|
||||
produces an unrecorded-change diagnostic at `/resources`. This is established
|
||||
For example, changing `/resources/0/path` and recording only that path previously
|
||||
produced an unrecorded-change diagnostic at `/resources`. That was established
|
||||
behavior rather than a new regression associated with v1.0.0.
|
||||
|
||||
The comparator also serves other inspection and metadata operations. Making
|
||||
resolution auditing more precise must account for those callers rather than
|
||||
silently changing the public diff contract.
|
||||
|
||||
Resolution currently captures before and after values at the same numeric path.
|
||||
Its metadata refresh also consults entry metadata at that path. Following a
|
||||
registered record through a move therefore requires more than changing which
|
||||
deltas pass the coverage audit: the retained evidence must identify the matching
|
||||
entry and final record.
|
||||
The prior resolution implementation captured before and after values at the
|
||||
same numeric path and refreshed metadata at that path. Following a registered
|
||||
record through a move requires the matching entry and final record evidence.
|
||||
|
||||
Application registrations already define identities for collections and constrain
|
||||
their final values. YAML-only declarations have a shorter lifetime. The
|
||||
|
||||
Reference in New Issue
Block a user