From 0778624560f8b3a440c2619273eff09ca3ebce7b Mon Sep 17 00:00:00 2001 From: Satya Date: Wed, 2 Sep 2026 11:41:34 -0400 Subject: [PATCH] Edge resolution: a self-referential base edge is always read in reverse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit entity.parent_id -> entity matches every type pair in both directions, and the discovery loop kept forward whenever reverse also matched — so an array include compiled as `parent.parent_id = child.id` and every nested list read back empty. Includes always start from the parent and list what hangs under it; nothing reads the edge from a child up to its parent object. So the edge is reverse, full stop. 1286 library tests pass. Pinned by api's accounting suites on branch activity-task-assignment-lines. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AvkGU4kQ4wsqxHFpXtZKZM --- src/database/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/database/mod.rs b/src/database/mod.rs index afa6eb8..9dc3cf6 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -500,6 +500,13 @@ impl Database { let is_reverse = p_def.hierarchy.contains(&rel.destination_type) && c_def.hierarchy.contains(&rel.source_type); + // A self-referential edge on a shared ancestor table (entity.parent_id -> entity) matches + // both ways for every type pair. Includes always start from the parent and list what hangs + // under it, so the edge is read in reverse — never from a child up to its parent object. + if is_forward && is_reverse { + is_forward = false; + } + // Structural Cardinality Filtration: // If the schema requires a collection (Array), it is mathematically impossible for a pure // Forward scalar edge (where the parent holds exactly one UUID pointer) to fulfill a One-to-Many request.