I was expecting y^2. Is there other functionality that lets me do these substitutions? I’m trying to write some code that polynomializes nonlinear ODEs, and that relies on substitutions of this kind.

indicates to me that this could be a matter of simplification vs. substitution. Are there certain rules in the CAS community which prescribe order of operations? Difficult, it seems (Knuth-Bendix, or so).

Symbolics performs subtree matching to subsitute. That is why it does not work for (1/(x^2)) here. This type of general substitution can get be complicated to implement as you need to search all possible rewrites of an expression to figure out if any one of them will allow substitution, but maybe there are simple but effective things we can do to start with.