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 choose another explicit base. The example intentionally performs neither target
existence checks nor confinement checks. 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 ## Intentional migration changes
When upgrading, start with the changes relevant to your dependency and inputs: When upgrading, start with the changes relevant to your dependency and inputs: