Backing calculation for inherited_characteristic DSL declarations.
Walks the graph along a normalised via: hop chain (assignment and/or relationship
edges, in either direction — see Diffo.Provider.Calculations.Traversal), reads the
typed characteristic at the declared read role on each reached instance, optionally
renames it (as) and collapses the result to one end (collapse).
Injected automatically by TransformInheritedRefs — do not reference this module
directly; use the inherited_characteristic DSL entity inside characteristics do.
Cross-world resolution
Unlike inherited_place / inherited_party (which query universal PlaceRef /
PartyRef), the typed characteristic module varies per reached resource. This calc
resolves it at runtime via AshNeo4j.worlds/1 on each struct and
Diffo.Provider.Extension.Info.provider_characteristics/1 on its outermost resource.
Late-binding by design — the reached resource may not exist at the consumer's compile
time.
Result shape
Without collapse, a list per input record — one entry per reached instance. Each entry
is:
- A
BaseCharacteristic-derived record (or a list of such records when the reached resource's characteristic declaration is{:array, M}). %Diffo.Unknown{}when the instance can't be projected to a loadable resource module, or its module declares no characteristic at thereadrole.
With collapse: :first | :last, a single such entry or nil (empty result).
When as is set, each BaseCharacteristic record is renamed to that name (both the
loaded value and, via surfacing, the encoded TMF entry); %Diffo.Unknown{} sentinels are
left untouched.
Reason vocabulary (local to this world)
:no_concrete_world—AshNeo4j.worlds/1returned[]; the reached struct has no labels resolvable to a loadedAshNeo4j.DataLayerresource.:contextcarries%{source_id: id}.:role_not_declared— the outermost world's resource exists but itsprovider_characteristics/1has no entry for thereadrole.:contextcarries%{source_id: id, resource: module, role: atom}.
Per the Cross-domain lookups AGENTS.md section, reasons are world-local — consumers in
other worlds should treat them as opaque and (if composing) wrap via :inner_unknown.
Summary
Functions
Callback implementation for Ash.Resource.Calculation.describe/1.
Callback implementation for Ash.Resource.Calculation.has_expression?/0.
Callback implementation for Ash.Resource.Calculation.init/1.
Callback implementation for Ash.Resource.Calculation.strict_loads?/0.
Functions
Callback implementation for Ash.Resource.Calculation.describe/1.
Callback implementation for Ash.Resource.Calculation.has_expression?/0.
Callback implementation for Ash.Resource.Calculation.init/1.
Callback implementation for Ash.Resource.Calculation.strict_loads?/0.