Dear reader, don't be like me. Don't spend ages chasing your own tail, chasing a red herring down a rabbit hole, all because of an incorrect assumption.
When you use the GPIO configuration locking feature of the CH32V003 - a feature that allows you to make the mode and direction of selected GPIO pins unchangeable once locked, guarding against accidental modification - when the manual says that the configuration is locked until a reset occurs, they're not wrong.
I added an input pin to my code, but was extremely puzzled when that line was not being pulled up by the configured internal pull-up as it should have been. I double, triple, quadruple checked my code, went off on tangents, down dead ends, and generally wasted a lot of time. Not once did it occur to me to actually reset the microcontroller.
You see, when flashing new code to the MCU (at least with the WCH-LinkUtility software), it doesn't get reset. And so because I was using the GPIO config locking, and had locked all pins, my new code for the new GPIO input never took effect.
In hindsight, it should have been apparent that no reset occurs when programming flash, because you don't actually need to connect the reset line to the Link-E programmer to do so (SWDIO only is sufficient). I assume it does something like re-initialise execution at zero instead.