Expand description
Structural invariant over a finished spatial-node set, split out of
spatial.rs to stay under the module-size ratchet (the same reason
spatial_tree.rs and spatial_elevation.rs exist).
#3973 fixed the same defect shape twice, pointwise, in two different
code paths: a dangling children_ids entry naming an entity with no
corresponding node in nodes_map (first a depth-capped node resurrected
as a fake root, then a rescued orphan’s children_ids populated straight
from spatial_children_map with no filtering). Each fix closed one path
into the tree without ruling the shape out structurally, so this checks
the finished tree instead of any one code path.
Functions§
- reachability_
and_ 🔒depth_ violations - Global check, added for #4022: BFS every
children_idsedge starting from every node whoseparent_idis the sentinel0(there can legitimately be more than one, see the module doc above), tracking depth as it goes. Any node the walk never reaches is flagged - this is what catches a cycle isolated from every root (e.g. two nodes that are each other’s parent and only listed child: each satisfies the local clauses above, but neither has aparent_id == 0node in its ancestry, so neither is ever enqueued). Any node the walk does reach has itslevelcompared against the depth the walk assigned it, catching alevelthat disagrees with the node’s actual position in the tree. - spatial_
hierarchy_ 🔒consistency_ violations - Check a finished node set for the dangling-reference shape #3973 fixed
twice pointwise: (a) every id in every node’s
children_idsmust resolve to a node in the set, (b) every node’sparent_idmust either resolve to a node or be the root sentinel (0- never a real STEP entity id), and (c) the two directions must agree -A.children_idscontainingBandB.parent_id == Aare two representations of the same fact. Clause (c) is the one that actually catches the family: a fake root with a real parent_id disagreement passes (a) and (b) - it names no nonexistent id and has a resolvable-or-sentinel parent - while still being wrong.