lineageKeyOf

The one derived property on a run header: an injective encoding of everything about a run's lineage that a later save could disagree about.

A save is rejected when it contradicts the stored lineage, and that check has to happen inside the same statement that writes — otherwise a concurrent terminal write lands between the read and the write. Comparing five properties in Cypher works but reads badly and gets the null handling wrong easily; comparing one string is exact. The individual properties are still stored separately, because that is what childrenOf and runsOfRoot seek on.

Two sources of truth for one fact is a drift hazard, so fromRow re-derives this from the properties it just read and refuses a node where the two disagree — the same shape of check DriftReportRowMapper runs over a report's scope.