After few years of working on this complicated project, and with only few months left, i realized that my programmer been feeding me BS all along, that the system is not near ready, with quick fixes piling up, and a programmer that had me in a corner where the code is full of deprecated, duplicated, unused code, and that he is the only one that gets it, how to deal with such a situation ? if i fire him with 5 months to go, it will take that much time for someone new to understand the code? if i let him be, then that sends the wrong message to other team members !
Couple of suggestions :
You have to replace that person and refactor the code.Client also need to know, if required.
But you cannot do that rightaway. Two ways :
Get new person rightaway and ask him to partner him in his module. When he becomes comfortable in the module, replace original person. This new person should know that original person is supposed to be replaced and original person should not be aware. This approach is taken when you have so much dependency and you know that this person will not give KT.
Second, get new person - Ask original person to give KT to this
person. Prepare KT plan and follow that. Escalate to higher management or involve HR if this person does not give KT properly
See which plan suits you.
After few years of working on this complicated project, and with only few months left
Well that's the first mistake, you've been working for YEARS on a project and haven't seen anything? Methodologies such as Agile exist to avoid things like this.
Having said that, if you know it's a state, and you can't trust your developer, you need to relay this to your sponsor/customer that there is an issue NOW. Now go through the features you are doing, and prioritise them. Don't keep your dev, he is either useless/malicious/got a hidden agenda, you can't trust what he'll do going forward, and realistically you're no worse off without him.
Get another dev/contractor/company in to assess the code, in order of the priority. Get a timeboxed estimate of what each feature will take to fix/build/complete (when I say timeboxed I mean get your dev to spend a pre-agreed block of time evaluating, not until it's all looked at, keep it high level).
Now the hard part, look at each feature against priority and cost and decide if this is fixable or junk. Be ruthless, remember the sunk cost fallacy, it may be the best solution is to just stop.
If you find there is something to save, get them working on the features in priority, with regular reviews (so either sprints or deliveries depending on your process of choice), you need to build just enough to satisfy requirements/mvp and get the thing shipping. Re-evaluate each delivery to decide if this is still viable. DO NOT get the devs to refactor, the code base is a mess, and if you get to V2, you'll probably start again. Only allow them to refactor/redo if there is no way to use (or the code is just too bad/non-performant etc), you are going to throw it away so save the design for the next version.
You have discovered a risk. First, don't get emotional about it. The risk doesn't care that you've been eating BS or who is to blame. Neither does the customer. If you're having trouble remaining neutral, discuss your problem with someone that understands your organization, the context of the problem, and that can be neutral.
You have 3 basic paths: - Accept - Mitigate (via various options) - Wait & Track
Your goal is to make a risk-neutral decision, i.e. find a feasible solution that accounts for the risk and optimizes return for your customer.
Think about the impacts (costs) and likeliness of failure (probability) associated of accepting the risk as it stands, mitigating it via various methods like OP's suggest, or just deferring action.
You also need to root cause this risk. Why did this go on for so long? How can you avoid this issue on future projects?