pub const CREATE_CONCEPTS_GUARD_LINEAGE: &str = "\n CREATE TRIGGER IF NOT EXISTS trg_concepts_cross_lineage\n BEFORE INSERT ON concepts\n WHEN EXISTS (\n SELECT 1 FROM concepts\n WHERE id = NEW.id AND branch_id <> NEW.branch_id\n )\n BEGIN\n SELECT RAISE(ABORT, \'macrame: concept belongs to another lineage; a branch inherits concepts, it does not restate them\');\n END;\n ";Expand description
A branch inherits concepts; it does not restate them (§15.2, D-214).
concepts is a current-state projection keyed by identity — id is
NOT NULL UNIQUE and the write path uses ON CONFLICT(id) DO UPDATE — so
two lineages holding different beliefs about one concept is two rows with
one id, which the unique index refuses on its own (probe §2). What it
refuses it refuses as a constraint failure, naming nothing; this guard
turns the same refusal into a sentence that says which rule was broken.
It fires before ON CONFLICT is considered, which is not obvious and
was measured rather than assumed (probe §7): a cross-lineage upsert is
refused, a same-lineage one is accepted, and a new id is accepted.
Exact-branch equality, not ancestry. A branch that may restate its parent’s concepts is the overlay design, and the overlay is deferred with its reopen trigger named (D-214) — a guard that quietly permitted the ancestry case would ship half of it with none of the machinery that makes it correct.