I have done everything from formal documentation of changes, requiring pricing and sign-off for every variation, to vaguer schemes.
The change request system sucks; it loses sight of why we're building the software and turns into a war of attrition.
The issue is always they say the spec is open to interpretation and they meant this, or they expect it to work this way (which is slightly different now they see it, but in scope because every single interaction can't be specified in advance). And either way they see no reason to pay.
So it ends in arguing and bad feeling; the client has an expectation that's not met without paying more and feels it's my fault, that they're paying when they shouldn't. I've lost time and much emotional energy.
I have gone as far as to have a "What's not included" section in every contract which helps, and that if it's not mentioned specifically then to assume it's not included; but it's a non-ideal situation.