Mathias Verraes has shared some thoughts about legacy applications and how development should be handled as new features are added and bugs are fixed. He proposes a "heuristic" to keep in mind as you work in your legacy code: the Repair/Replace Heuristic.
Technical Debt is a great metaphor. It shares many analogous properties with financial debt: loans, accrued interest, token payments, bankruptcy… There is a key difference however. We take financial debt with another party. [...] Technical Debt has no measure like money, and no ruleset like Property law, and, more importantly, with Technical Debt there is no other party. The organisation is both the creditor and debtor. [...] In “Managed Technical Debt”, I propose a cheap, imprecise, but surprisingly effective method for mapping and measuring debt. In short, it involves posting stickies whenever progress is impeded by debt, and keep marking the stickies for every incident.
By following this method, you gather together a better overall picture that makes determining the worst debt in your application easier. He proposes using this to follow the Repair/Replace methods: repairing something if it's well architected or replacing it if it's not.
Even when you’re not trying to decide on Repair/Replace — perhaps the decision was already made by others — the process of mapping its history will teach you more about the system and and its design. And one deep insight you learn from temporal modelling.