kapps_ogm.node.node_address#

Address reconciliation between a fetched node and the node about to be written.

kapps_ogm.node.node_address.reconcile_anonymous_addresses(*, old: Node, new: Node) → None[source]#

Copy stable anonymous-node addresses from a fetched node onto the node about to be written.

An anonymous node’s address is deliberately absent from the pydantic projection, so a caller who fetches, calls model_dump(), edits a value and commits the plain dict has no address in their payload. Without this step every commit would mint a fresh address, delete the old node and strand every triple the ClassSpec does not declare — the failure this whole mechanism exists to prevent. The address is therefore recovered from the store side instead.

Entries are aligned positionally, which is why OGM._fetch_complex_property returns its groups in a deterministic order: both the caller’s earlier fetch and the fetch inside commit then see the same sequence. A value with no counterpart on the old side is a genuinely new node and is left unaddressed, so that OGM._assign_id mints for it.

An old address that is still a blank node is not copied. The node has not been skolemised yet, so leaving the new one unaddressed relocates it to a Skolem IRI on this write — a one-time migration, after which its address is stable.

Known limitation: alignment is by position, so a caller who reorders an equal-length list of anonymous values silently swaps their addresses. A shortened list is refused outright (see AmbiguousNodeAlignmentError), but reordering is not detectable from position alone. It cannot arise until one property carries two or more anonymous nodes, which no current domain model does. Closing it wants content-based matching, and that alone is not enough: under the locator pattern two sibling parameter nodes are often content-identical.

Parameters:
  • old – The node as fetched from the store, carrying the authoritative addresses.

  • new – The node about to be written. Mutated in place.

Raises:

AmbiguousNodeAlignmentError – If a property’s outgoing list is shorter than the stored one.