At my last company, I headed the Engineering org and was told by my CEO that there was was no time for refactors of our monolith (and not a good one at that...access to HTTP request all the way down, for example) or anything silly like that, so we went a very similar route. We did what we called the zombie rewrite, which was an inside out refactoring that left no changes on the surface.
Step one was to slowly rework things into logical services that still relied on the underlying legacy code. Eventually, we got to the point where cross functional domain logic was accessed via logical services rather than direct use of classes in other domains. Once we accomplished that, we slowly worked back down to understand, optimize, and refactor legacy code in digestible chunks. The final stage was to work up to the REST API level to create a more sane implementation of the web bits that preserved existing behavior.
It took the better part of a year to do all the work, but by going piece by piece (which allowed for understanding some wonky code), we had very, very, very few regressions and minimally impacted our overall ability to still deliver on the roadmap.
Step one was to slowly rework things into logical services that still relied on the underlying legacy code. Eventually, we got to the point where cross functional domain logic was accessed via logical services rather than direct use of classes in other domains. Once we accomplished that, we slowly worked back down to understand, optimize, and refactor legacy code in digestible chunks. The final stage was to work up to the REST API level to create a more sane implementation of the web bits that preserved existing behavior.
It took the better part of a year to do all the work, but by going piece by piece (which allowed for understanding some wonky code), we had very, very, very few regressions and minimally impacted our overall ability to still deliver on the roadmap.