@whitequark @coder
It is not possible to move all processing outside of the tool unless your model is to allow the tool to provide complex arbitrary code to the shell. For example, consider gcc or clang. Some of their flags depend on the target, so you need to parse some of the, and then do lookups against complex data structures that depend on targets. It’s sufficiently complex that writing it in declarative code is hard.
Some folks on the .NET team had a very nice solution to this for autocompletion, where a .EXE had a special section of .NET IL that PowerShell could load. If you used their declarative framework for argument parsing then it would generate this for you and it would make autocomplete work beautifully in PowrShell (not sure if this was ever released, I played with a prototype). I can imagine a lightweight WAsm interpreter being an interesting approach for doing this on *NIX.
The best argument for doing expansion in the shell is one that is sadly not realised in UNIX. If you do file expansion and opening in the shell, you can start processes with file descriptors instead of (or as well as) paths. Processes can then be started with access only to files that are either listed in a manifest or passed on the command line. Build a system like this, and you have a nice way of respecting the principle of least privilege.