13. Derived labels and relationships — DERIVE rules
A rule set defines a derived label: a label that exists on no stored node, whose membership is CONCLUDED from data by rules — including rules that refer to the label they are defining. A rule set may equally define a derived relationship — an edge whose existence is a conclusion (§13.4); everything in this section reads the same for both, with membership a node for a label and an ordered pair for a relationship. That self-reference is the point: it expresses propagation no single query can — ownership chains, phoenix succession, status that feeds back into further status. Where a view (§8) saves one query, a rule set is many unordered clauses of one definition, evaluated to a least fixpoint. A view cannot reference itself; a rule may.
# rules/phoenix-succession.yml — one rule set per file (shipped by realm-gov-uk)name: gov-uk/phoenix-successionderives: PhoenixSuccessordescription: >- An appointment that follows the same officer's appointment at a company the register now records as dissolved; phoenixDepth counts dissolved predecessors in the chain.rules: - derive: "(b:PhoenixSuccessor)" from: | MATCH (a:UkAppointment {companyStatus: 'dissolved'}), (b:UkAppointment) WHERE b.officerId = a.officerId AND b.companyNumber <> a.companyNumber AND a.appointedOn IS NOT NULL AND b.appointedOn IS NOT NULL AND b.appointedOn > a.appointedOn - derive: "(c:PhoenixSuccessor {phoenixDepth: d})" from: | MATCH (b:PhoenixSuccessor), (c:UkAppointment) WHERE c.officerId = b.officerId AND c.companyNumber <> b.companyNumber AND b.companyStatus = 'dissolved' AND b.appointedOn IS NOT NULL AND c.appointedOn IS NOT NULL AND c.appointedOn > b.appointedOn WITH c, max(coalesce(b.phoenixDepth, 1) + 1) AS dEach rule is a head and a body — read it as an implication:
deriveis a node pattern — or, for a derived relationship, a relationship pattern (§13.4) — naming what the rule concludes: which body variable becomes a member, and (optionally) derived properties computed from body bindings. Its one label (or relationship type) must be the rule set’sderives. Quote it: property maps contain:, which YAML would otherwise read as a nested mapping.fromis ordinary read-only Virtual Cypher that BINDS variables and stops — no RETURN. The head is the projection; the host constructs the runnable query from the parsed head, and both productions are parsed by the real Cypher parser (the same §8.1 stance: no new grammar in queries, definition is metadata).
Semantics in one sentence: a node carries the label — a pair of nodes carries the relationship — if and only if some rule concludes it. Rules are unordered clauses — reordering them cannot change the result — and evaluation runs to a fixpoint, so a member concluded by one rule can satisfy another rule’s body; the second rule above chains through its own conclusions, which is how a depth-unbounded pattern is expressed in two clauses. Two rule sets may derive the same label: that is the union of their clauses, not a conflict. The classic worked case is the OFAC 50 Percent Rule — blocked if listed, or if blocked parties in AGGREGATE own ≥ 50%, recursively — where the entity that matters is on no list and no fixed-depth query can be correct for all data.

