mark_unobserved doesn't switch necessary children to clean
should also remove from queue; if they were in the queue, i guess they were dirty?
there's also the bug where if a node becomes non-observed because we mark its inbound observed edge as 'dirty' we won't mark upstream things as non observed. in general we have a lot of observed bugs. maybe should move more observed calculation shit into the graph.
also i think if a node is not observed, we can skip incrementing height for its children. only important bit is that observed nodes that descend from another observed node have different heights; intermediate non-observed nodes can share height with one of the observed nodes or another