Best practice for synchronizing VHDL stimuli with circuit
I've since come to the conclusion that, since inputs need to be stable at the rising edge of the clock, I should be changing stimuli only at the falling edge of the clock


This is not a preferred approach.  You want your TB to represent the system you will be operating within.  In your system you will have a clock that goes to your FPGA, and you will have clocks that go to BFMs with which you interface.  If you are not modeling the BFMs (e.g. DSP, microprocessor, etc.) you are not modeling, and thus verifying, the bus operation/protocol, only that you can apply data to the interface and that your FPGA will interpret that data once received.  This is typical in a rudimentary TB that uses FileIO methods to read a sequential set of values and drive those values on the pins.  This is ok, for sanity check maybe, but falls short of what should be considered "verification".

Sadly, VHDL is not a verification language like Vera, Specman, or SystemVerilog's OOP-space.  VHDL, via Jim Lewis' efforts (Synthworks), has made strides in terms of OSVVM and, as such, greatly helps one model (arguably verify) designs using VHDL.  If you don't have access to SV or the knowledge to employ it, and are strictly VHDL, OSVVM is probably about as good as it gets, and certainly better than using "test case files" via FileIO methods.