A 180-person HRTech company received a board mandate to ship AI-powered features. Fourteen months later, the team had built four prototypes, held three board reviews, and delivered nothing to customers. The engineers were not the problem.
The company had been growing for seven years. Its core product — a workforce management platform used by mid-market employers — was solid. Revenue was strong. But the board had watched competitors launch AI-assisted scheduling, AI-generated job descriptions, and AI-powered compliance flagging, and the pressure to respond had become impossible to ignore.
The CTO, who had been with the company for four years and had built a capable engineering organisation, received the mandate clearly: ship something with AI in it, this year, that customers can use.
Fourteen months later, nothing had shipped. The CTO called me when the fourth prototype stalled in staging.
The first thing I asked to see was not a product roadmap. It was the architecture diagram. Specifically, I wanted to understand how the application accessed its own data — which services owned which tables, and whether any part of the system had a clean interface that could be called independently.
The answer was what I had expected. The platform was a seven-year-old monolith. Not a distributed monolith — a genuine single-deployment application in which the UI, business logic, and data layer were deeply entangled. Every screen in the product read directly from shared database tables. There were over four hundred stored procedures. No service had its own schema. Nothing had a public API that hadn't been added as an afterthought in year five.
The four AI prototypes had all run into the same wall from different directions. The AI-assisted scheduling feature needed real-time availability data — but availability lived inside a stored procedure that also calculated payroll accruals, and extracting it without touching the payroll calculation was not a small task. The job description generator needed to pull role metadata scattered across three tables with no consistent foreign key. The compliance flagging prototype needed to call an external LLM API — but the monolith had no HTTP client layer, and adding one had required touching a file that was also responsible for session management.
"Every time we tried to add the AI layer, we ended up refactoring something fundamental. The prototypes kept stalling not because of the AI — but because of everything we had to move to make room for it."
Fourteen months of effort had produced four incomplete prototypes and one deeply fatigued engineering team. The board was losing confidence. The CTO was running out of explanations that didn't sound like excuses. The AI features had simply exposed a structural truth the company had been able to ignore while it was building in a single direction.
The first thing we did was stop all four prototypes. Completely. Not paused — stopped. I walked the CTO through why: each prototype was accumulating integration debt against a shared codebase with no boundaries, and the debt from four simultaneous experiments was now larger than the value any of them could deliver. Continuing was not persistence. It was compounding a losing position.
The second thing we did was identify two bounded contexts within the monolith — two areas of the product where the data ownership was relatively clean and the business logic was relatively self-contained. Scheduling was one. The job-posting flow was the other. Neither was a greenfield build; both had years of production code behind them. But both had data that could be extracted behind a clean internal API without touching the rest of the system.
We used the strangler fig pattern — not a full rewrite, not a big-bang migration. We built thin API wrappers around the scheduling data layer and the job metadata tables. The monolith continued running exactly as it had. The new AI features called the wrappers. The wrappers called the database. Nothing else changed.
The first AI feature — smart shift suggestions, surfacing recommended schedule adjustments based on historical attendance and leave patterns — was scoped against the scheduling wrapper. It was intentionally narrow: it only worked for employers with more than fifty employees and only surfaced suggestions, never made changes. The AI call was a single prompt with structured output. We shipped it to a customer cohort in ten weeks.
The board received a live product demo in the next quarterly review — the first one in five cycles that included a working feature rather than a prototype. The CTO's position, which had been under quiet pressure, stabilised. The monolith is still running. It will probably run for another three years. That is fine. The company is no longer trying to rewrite it and ship AI at the same time.
The deeper lesson is one I have seen in every organisation that has tried to add AI capability to a platform that wasn't designed for it: the AI is not the hard part. The hard part is having a system clean enough that the AI has somewhere to live. Most companies discover this fourteen months in, after four failed prototypes. The ones that discover it in week two — by asking what the integration surface looks like before they write a single prompt — spend the next fourteen months building things that ship.
The AI mandate the board issued was not wrong. The architecture it landed on was not ready for it. The gap between those two facts is where most enterprise AI programmes spend their budget.
The right sequence is not: get the AI working, then figure out where it goes. The right sequence is: figure out where it goes, what it needs from the existing system, and whether that system can provide it cleanly — and only then write the model code. That conversation takes an afternoon. The alternative takes fourteen months, and it still doesn't ship.