What if we can unify those three approaches? What if it is all XCQ. Hear me out.
What if 1) and 2) just return XCQ programs instead of the value itself. I say this because 1) and 2) are mainly about discovering common queries which are already queryable via XCQ.
This might potentially leads to less code duplication and avoids the situation where stuff is only accessible via 1) and 2) but not via XCQ because somebody didn’t write an extension for it. It would allow us to confidently say that everything can be queried via a custom XCQ but also defining a list of useful queries inside the runtime.
The problem is of course that it might be complicated to define XCQ programs within the runtime. They have to be compiled for a different target. But I think if we really want that we could make it happen.