Tagged union over the two node kinds the engine recognises. Both variants are structurally { readonly id: NodeId } at runtime; the _phantom brand provides type-level narrowing without leaking a discriminator onto the value. Everything else previous drafts called a "kind" (formula, selector, constraint, resource, effect, conflict, collection, index, workflow) is a role a node can play, not a kind it permanently is — a formula is just a derived whose compute happens to interpret an expression string, a constraint is a derived returning a validation result, an effect is not a node at all but a post- commit subscription.

Type Parameters

  • T

    Value type carried by the node.