The call usually has the same shape. A vendor was building something — a customer portal, a workflow system, a mobile app on top of an existing platform. The relationship has ended: a dispute over invoices, the vendor folded, or the one developer who understood it left and the rest could not carry on. What remains is a repository, a staging site that may or may not still run, and a great deal of uncertainty about how far along the thing actually is.
The instinct is to ask "how much is left?". It is the wrong first question, because nobody can answer it yet — least of all a client who has just been burned by the previous estimate.
Get the assets before the opinions
Before any technical assessment, secure what exists. This sounds administrative. It is the step most often skipped, and it is where projects become genuinely unrecoverable.
- Source code, with history. A zip file of the latest version is not the same thing. The commit history is the only record of what was tried and abandoned.
- Every account the project depends on. Domain, DNS, hosting, certificates, app store listings, payment gateway, email relay, third-party API keys. Find out whose email address each one is registered to. Very often it is a departed contractor's personal address.
- Database backups, from staging and from anything that was ever called production.
- The paper trail. The original specification, every change request, and the emails where scope was agreed or argued about. These are the closest thing to a definition of "done" that exists.
A project where the domain is owned by someone who no longer answers email is not a technical problem, and no amount of engineering fixes it. Start here.
Does it run?
Then the only question that matters for the first few days: can we build it from source, deploy it to an environment we control, and log in?
Surprisingly often the answer is no. The repository does not match what is on staging. A package came from a private feed that no longer exists. The database schema was hand-edited on the server and there are no migration scripts. A connection string points at a machine nobody can find.
Until this is fixed, every other assessment is speculation, because you are assessing something you cannot run. We do not estimate anything until it runs.
Salvageable or sunk
Once it runs, the assessment proper. We are not grading the code. We are answering one question: is it cheaper to continue from here, or to start again from what is now known?
It is usually salvageable when the architecture is conventional even if untidy, the data model broadly matches the business, and the hard parts — authentication, the core workflow, the integration everyone was worried about — actually work end to end. Ugly is fine. Ugly can be fixed a screen at a time.
It is usually sunk when the data model is wrong in ways that touch everything, when the core workflow turns out to be a mock-up wired to nothing, or when the security fundamentals are absent: passwords stored in plain text, every query built by string concatenation, no concept of who is allowed to see what.
One thing worth saying clearly to the client at this point: "half-finished" is almost always measured in screens, and screens are the cheap part. A project with most of its screens built and no working core workflow is nearer a third done. A project with rough screens and a correct, tested backend is nearer four-fifths. The percentage on the last invoice rarely reflects either.
Why the first release changes nothing visible
Whatever the verdict, the first thing we ship is a release that is functionally identical to what already exists. Same features, same look. The difference is that it is built from our pipeline, deployed to an environment the client owns, by a process that is written down.
This feels like wasted effort to a client who has been waiting months for features. It is not. It proves we have everything we need. It proves the deployment path works before anything depends on it. It separates "it broke because of the takeover" from "it broke because of the change", which matters enormously for the next six months. And it gives the client the first release that has arrived when it was promised, which is worth more than any feature.
The conversation with the client
Be honest about what was found without turning it into a verdict on the previous vendor. They often had reasons: the scope moved, payments were late, the specification was ambiguous and nobody resolved it. Blaming them is satisfying and useless. The client needs a plan, not a post-mortem.
The plan is three lists. What is done and verified. What is done and unverified. What is not done. Only the third list gets an estimate, and only after the second list has been worked through — because "done and unverified" is where the surprises live, and estimating around it is how the previous number went wrong.
What good looks like a month in
The application builds, deploys and runs from assets the client controls. There is a written statement of what exists and what it does. A first release is out. And there is a scoped plan for the remainder, in plain language, that the client could take to another team if they chose to.
That last point is deliberate. A client who has just been through a bad vendor relationship should not have to trust the next one blindly. The plan should be good enough that they do not need to.