diff --git a/docs/consumers/README.md b/docs/consumers/README.md index 25323f9..6b38cdf 100644 --- a/docs/consumers/README.md +++ b/docs/consumers/README.md @@ -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: