I've uploaded an update: Craig Lage was correct that I had incorrectly put the masked-value "interpolation" fix in a function that wasn't being called by the MEDIAN_PER_ROW correction (but confusingly was run by the debug code). This resulted in the columns with bad bleeds continuing to have NaN values, causing the masking code to mask and interpolate these pixels (doing a poor job as there is also oversubtraction that pushed the interpolated values below the background level). I've fixed that, and although it's better (the crosstalk ghosts do not appear to have significant oversubtraction), the source bleed is still oversubtracting (~65 ADU on the shown image). Growing the input mask helps somewhat, with 2-pixel growth reducing the oversubtraction to ~25 ADU. I'm going to look at some bleeds, and see if there's a larger grow value that yields better results.
I've pushed the current version in case others want to look at it, and I'm hoping to have a cleaned up version ready tomorrow that can hopefully go into review.