Document field-level resolution and matched sequence history

This commit is contained in:
2026-11-03 01:01:25 +00:00
parent 43ac34d10e
commit c2b3cb32da
10 changed files with 59 additions and 21 deletions

View File

@@ -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.