Software projects keep you on your toes. Sometimes you can snatch victory from the jaws of defeat. Other times, circumstances change, and even the best laid plans fail. Good teams follow best practices, but the best teams will achieve continuous improvement. But those only help with known risks.
| What about unknown risks that show up mid-project?
The story I’m going to share spanned 9 months. I was brought into an initial conversation with Ken (CEO of LightSaber Inc.) – which was a pre-revenue startup. Ken was a veteran CEO and past executive at a large enterprise. He was articulate and seemed to have the right connections to pull off this idea for a mobile application. He had been working on this side project (on and off for about 3 years) with an offshore team.
Ken felt close to the finish line, but wasn’t getting what he needed from his current team; he needed professional help. We’d been in these transition situations before, and knew the red flags when taking over a codebase. So I didn’t pull any punches – honesty is the best policy.
“So Ken, ” I said, “With an older codebase there will be a learning curve for us and therefore estimates and projections will not be accurate”.
“I understand. I assume you will be as transparent as possible as we continue through the project?”
“Yes sir,” I responded, “We are good at identifying and escalating risks so we will definitely keep you in the loop. We will also come to you with options on how to proceed. But bear in mind, we have the known unknowns but we also have unknown unknowns that we may run into.”
“Well… don’t you have a way to assess the codebase first?” Ken asked.
“Of course, we will but any application has thousands of lines of code,” I explained. “We will do our best to identify issues but in my experience with inheriting code – I can’t guarantee there will be no surprises. We can, however, guarantee quick escalations and tight communication. Alternatively, if you want more predictability – we‘d have to consider a rewrite.”
Ken: “Makes sense. Let’s cross that bridge when we get to it. For now, we keep the codebase”
And so we proceeded.
| This was one of the situations where every layer of the onion exposed new risks.
The first task was setting up a new environment. We discovered that for no apparent reason, this smallish application needed two separate technical stacks: PHP and Microsoft.net. Weird – but we get it done.
Then Ken adds that he wanted “3-4 small features added before launch.” His plan is to raise another round of funding post-launch. We accept.
Then we completed a code review and full functional testing of the application. The offshore team was reusing code from an application that was written for an entirely different project. On top of that, the codebase was not actually 3 years old but rather over a decade old, and there were a number of quirky bugs. We fix them.
Then Ken’s request for 3-4 small features became a couple of dozen changes. We accommodate.
At each change in scope or new risk – Ken seemed to understand the situation, so we kept going into the next stage.
Onward we went, my team and I jumped through hoops of technical limitations and workarounds, and – somehow we pulled it off. Of course, we’ve overshot the budget now. That’s when we found out Ken had run out of budget. Given that we were so close to the finish line, our CEO offers discounts so we can get to launch.
| There is too much Sunk Cost at play; we have no choice but to go all-in and get this product live.
And… launch shenanigans! The code gets rejected a couple of times by the App Store – we have to get creative and slap some band-aids on. The product is live – finally. We heave a sigh of relief.
But wait! We find out that Ken never had a team to help him with validation on his end – he hadn’t fully tested the features. We were back on the phone within days of launch with production issues. Ken had previously declined ongoing support due to budget constraints. But we went in anyway, luckily it turns out it was a quick fix: we got the app working again.
| Are we done yet? Nope.
Next week, another firefight. I’m not a confrontational guy but I had to say something at this point.
“Ken, we sent you a couple of options for production support. Did you have a chance to take a look?” Ken is ready for that, “I did. We will get more budget once the next round of funds comes in. For now, I can’t commit”
How else do I say this? “I understand Ken, but without a paid support agreement, we can’t keep providing support”
Ken was not a happy camper, “Look, you guys have charged me close to $100K and in the last 9 months, you’ve reset the timeline so many times. I’ve been patient with you – now you need to fix the bugs you caused. I can’t have bugs while I’m in the middle of a demo”
The call went downhill from there. After 45 minutes of argument, the account was settled and alternative options were sent to Ken so we could step away from the project.
Ken has a held-together-with-glue-and-prayers application. We’ve lost money. No saving grace, no Hail Mary – a failed project. We did an internal retrospective and asked – what could we have done differently?
| Lesson learned: Don’t inherit a low-quality codebase that has never been launched.
This has been our official policy since then. We have stopped inheriting unproven code – it’s not personal. Founders are risk-takers and visionaries, but they are also human. Their optimism and hope may be misplaced, and they will hear what they want to. Ken was never going to agree to a rewrite.
| In retrospect, the only way to succeed on this project was to never have taken it on.
So learn to say no and pick your battles/projects carefully. Perhaps this can help you, dear reader, to make the right choices!
Story by Jared McGuire
(Real names not used for privacy)