Thank you, Jean. That does fix this example. I still suspect the root cause of my problem lies in how the lengths and positions of stems that are attached to beams are calculated. I'm guessing that your idea of removing the Stem_engraver and the Note_spacing_engraver is somehow connected to this comment inside Note_spacing::get_spacing:
/*
Ugh. If Stem is switched off, we don't know what the
first note head will be.
*/
The only problem is, there are still spots where I detect this problem where things outside-staff are being pushed away, even when I remove the Stem_engraver and the Beam_engraver. After experimenting a bit more, I found that I was able to fix my problem completely with these two commands:
\override Beam.quantized-positions = #'(0 . 0) (I noticed this actually takes an interval instead of a boolean)
\override Stem.length = #0
The default definition of Stem.length is ly:stem::calc-length, and this function throws an error if you change the definition of Beam.quantized-positions. Again, though, it's surprising that all of these functions are still running even though I shut off stems and beams. I'm not really sure why.
Thanks again!
Brian