Out of curiosity, have you looked into capture checking from Scala? It's proposed as a generalization of the rust borrow checker, to handle capabilities and other side-effectful computations (error handling, asynchrony, ...) in an ergonomic manner. Not sure if/how much cross-pollination there might be :-)
https://docs.scala-lang.org/scala3/reference/experimental/ca...