Every core banking replacement I've worked on gets framed, initially, as a technology problem: an old system needs to become a new one. By the time the migration is underway, it's almost always clear that the harder problem was never the technology — it was the decisions embedded in how the old system was used, which nobody had documented because nobody had needed to.
A legacy system accumulates decades of small workarounds: a batch job that runs at a specific time because of a constraint that no longer exists, an approval step that exists because of a control failure fifteen years ago that's long since been addressed a different way. None of this is in the requirements documentation, because it was never designed — it accreted.
Migration projects that treat the new system as a direct replacement for the old one's documented functionality miss this accreted layer entirely, and discover it, expensively, during testing — or worse, after go-live, when a workaround nobody knew about turns out to have been load-bearing.
The teams that migrate well are the ones who treat discovery of these undocumented decisions as the actual first phase of the project, before any system design begins — interviewing the people who've run the old process for years and asking, specifically, what they do that isn't written down anywhere.
The system is genuinely the easy part. It's replaceable, in principle, by any competent vendor. The decisions embedded in decades of operational habit are not written down anywhere, and finding them before they find you is the actual work of a migration.