Explain source-aware path normalization inside lists

This commit is contained in:
2026-11-03 01:27:33 +00:00
parent c2b3cb32da
commit f7044cf695

View File

@@ -308,6 +308,66 @@ application choice, not a ConfigKit fallback: consumers can instead reject it or
choose another explicit base. The example intentionally performs neither target
existence checks nor confinement checks.
### Normalizing paths inside a list
Suppose `/srv/catalog/resources.yml` supplies this configuration, and the
application interprets file-authored relative paths against their declaring
file's directory:
```yaml
resources:
- name: reports
path: ./reports
- name: invoices
path: ./invoices
```
Apply the same source-aware policy as `LoadNotariusPaths` to each `path` field
while the list remains in its entry order:
1. Build the field's semantic path, such as
`configkit.Keys("resources").Index(0).Key("path")`.
2. Query `Resolution.EntryInfo` at that path and use `Resolution.Source` to
identify its declaring file. Choose the base under the application's policy;
defaults, CLI values, and missing or composite provenance need their own
handling, as in the maintained example above.
3. Resolve the relative value against that base and use `Normalize` to assign
and record the individual field. For a mutation already performed by the
application, use `RecordNormalization` instead.
4. Continue without reordering the list. Later resource access uses the resolved
value rather than trying to recover a base directory from its effective origin.
For these file-authored values, the resulting configuration is:
```yaml
resources:
- name: reports
path: /srv/catalog/reports
- name: invoices
path: /srv/catalog/invoices
```
Each changed `path` has a resolution origin, while its history retains the
earlier relative value and source evidence. Unchanged fields such as `name`
retain their source origins. Field-level recording avoids attributing the whole
list to the path-normalization operation; it does not preserve a file origin on
the normalized fields themselves.
If the application also restructures the list during resolution, a whole-list
record covers the structural change. For a collection registered with `name`
as its identity, history follows each surviving record through a reorder, but
descendants can acquire synthetic resolution origins without source locations.
Historical source evidence and effective origins answer different questions;
identity-aware history does not automatically select a resource base for a
derived value. Resolve source-relative values before moving records, and account
for final positions when recording helper targets. `EntryInfo` continues to use
entry positions even after a move.
See [resolution recording](../config.md#resolution-recording-and-failure-rules)
for helper and coverage behavior, and
[origins and historical paths](../config.md#presence-origins-and-historical-paths)
for the distinction between resolution origins and retained source evidence.
## Intentional migration changes
When upgrading, start with the changes relevant to your dependency and inputs: