Case studies

Six projects that changed how we build software

None of what we believe about delivery came out of a book. There was a rebuild we talked a client out of, a data warehouse we hid behind the spreadsheets it was meant to kill, an AI pilot that only shipped once we cut it down, and three projects that convinced us the technical decisions belong with the engineers. Here are all six, roughly in the order they happened, and what each one left us with.

01
Legacy platform

The rebuild we talked a client out of

A national logistics operator came to us with a board-approved plan to replace the platform at the centre of their business - the system that took every booking, planned every route, and told hundreds of drivers where to be. It was over ten years old, every change seemed to break something else, and releases had slowed to one a quarter. Everyone agreed it had to go. We were asked to quote for the rebuild.

It would have been the biggest contract we had ever signed. But full rebuilds of systems like this have a habit of running for two years and delivering a slightly worse copy of what already exists. So we asked for four weeks inside the code first, at day rates, before anyone committed to anything.

What we found changed the conversation. The platform was not rotten. It was a mostly sound system with three genuinely bad corners, and a deploy process so frightening that nobody had shipped a small change in years. That, more than the code, was what everyone had learned to call legacy.

At a glance

Client
A UK national logistics & freight operator
Engagement
Modernising the core dispatch & booking platform
Original ask
Quote for a full 18-month rebuild
What we did
Fixed the platform in place instead
Our role
Assessment, remediation and delivery
Team
Three senior engineers alongside the client’s

The turning point

Four weeks of reading code saved eighteen months of rewriting it

We went through a year of incidents and change requests and marked where they actually landed. Most of the system had not caused trouble in years. The pain was concentrated in three places: route-planning queries that had outgrown their indexes, a pricing module with no tests that everyone was afraid to touch, and the deploy itself - manual, unrehearsed, done at 2am a few times a year.

So instead of a rebuild we did the unglamorous version. We automated the deploy until releasing was boring, which meant changes could be small, which meant they stopped being frightening. We wrote tests around the pricing module until it could be changed safely, then changed it. The slow queries took a fortnight. Ten months later the client still had the platform everyone had wanted to throw away - the same one, releasing weekly.

18 months
the rebuild plan we were asked to price
4 weeks
reading the system before recommending anything
10 months
to fix in place what the plan said to replace

What we found

  • “Legacy” turned out to mean three specific problems. The rest of the system was fine, and had been all along - nobody had looked closely enough to notice.
  • The fear was about the deploy, not the code. Once releasing was safe and boring, the codebase everyone wanted to abandon became easy to change.
  • Turning down the rebuild cost us the biggest contract we had been offered. It is also why the client is still with us.
This lesson became our legacy modernisation service
02
Data platform

The warehouse we hid behind the spreadsheets

A UK mutual insurer hired us to build a data warehouse, and the brief was blunt: get finance off spreadsheets. Month-end close ran across more than forty linked workbooks, took eleven days, and broke whenever someone renamed a tab.

Every vendor before us had pitched the same cure - dashboards, a BI tool, spreadsheet retirement - and two of those projects had already failed. So before writing anything we spent a week sitting with the finance team while they closed a month. Somewhere in that week it dawned on us that the spreadsheets were not the problem. Fifteen years of business rules lived in those cells, and they held the only numbers in the building anyone actually trusted.

So we did not take the spreadsheets away. We built the warehouse underneath them.

At a glance

Client
A UK mutual insurer
Engagement
A data warehouse under the finance reporting stack
The brief
“Get finance off spreadsheets”
What we changed
Kept the spreadsheets, replaced everything under them
Our role
Data architecture, delivery and analyst enablement
Team
Four engineers and an analytics lead alongside theirs

The turning point

We replaced what fed the spreadsheets, not the spreadsheets

The warehouse pushed clean, reconciled data into the same workbooks people already used. Same files, same tabs - the difference was that the numbers now arrived overnight from one governed source instead of being pasted in by hand from nine systems. Nobody was retrained, because on day one nothing visibly changed except that eleven days of copying stopped.

Trust moved slowly, and then it moved on its own. Once people had watched the warehouse agree with their own numbers month after month, they started going to it directly. Within a year about half the workbooks had been quietly retired by the people who owned them. We never ran a single migration workshop.

11 days
to close the month when we arrived
0
new tools finance had to learn on day one
~half
of the workbooks retired within a year, by their owners

What we found

  • People don’t trust systems, they trust numbers they have checked themselves. The spreadsheets had fifteen years of that trust; a new dashboard has none.
  • The tool you are told to kill is usually where the business logic lives. Half the rules in our warehouse came straight out of those cells.
  • Adoption you don’t have to push for is the only kind that lasts. We never migrated anyone - they moved when the numbers had earned it.
This lesson became our data & analytics service
03
AI assistant

The AI pilot that shipped once we cut it down

A UK retail group had spent nine months and three vendor pilots trying to launch a customer-support assistant that could handle anything a shopper might ask. Every pilot demoed well. None of them ever reached a customer.

The models were never the problem. The problem was that “answers anything” has no pass mark. Nobody could say what good looked like, so nobody would sign it off, and each pilot stayed a pilot until the budget moved on.

We suggested something much less impressive: pick the one workflow with a clear right answer - returns triage - build a way to score it before building the feature, and put a person behind every call the model wasn’t sure about.

At a glance

Client
A UK multi-brand retail group
Engagement
A customer-support assistant, after three stalled pilots
Original plan
One assistant that could answer anything
How it shipped
One workflow - returns triage - live in 5 weeks
Our role
Scoping, evaluation harness, delivery and handover
Team
Three engineers and an ML specialist

The turning point

We cut it down until it could be measured

Returns triage was a good place to start precisely because it was boring: a few hundred cases a day, a written policy behind each one, and a decision you could mark right or wrong the next morning. We graded a set of real historical cases first, and only shipped once the assistant beat the human queue it was replacing on that set.

Anything it wasn’t confident about went to a person, and every one of those hand-offs was logged and reviewed. It was live behind a flag in five weeks. A quarter later it was clearing most of the queue on its own - and, more usefully, the team knew exactly which kinds of case it still couldn’t be trusted with.

9 months
of pilots with nothing in production
5 weeks
to put one scoped workflow live behind a flag
62%
of returns triaged without reaching a human

What we found

  • “Answers anything” can never be signed off, because nobody can say when it works. One measurable workflow can.
  • Build the scoring before the feature. A model you can grade is a model you can improve; a model you can’t is a demo.
  • The number that matters is deflection: how much work never reached a human - and that everything important still did.
This lesson became our AI & automation service
04
AI-native delivery

The team got smaller and the work got faster

A UK B2B software business asked us to rebuild their customer portal, and the engagement arrived staffed the way these things have been staffed for twenty years: an external project manager, an external product owner, a design studio, an outsourced QA house - and, at the end of that chain, the people actually writing the code.

Nobody in the chain was doing a bad job, which is what made the problem hard to see. A change to a single screen took a fortnight, and when we traced one through, nine of those fourteen days were spent waiting: for the ticket to be groomed, for the mock-up to come back, for a regression pack to be re-run by testers who had never used the product.

We had spent the previous year building agentic tooling around our own engineers, and we knew what it had done to this kind of work. So we made an awkward proposal: shrink the team to four seniors, give them the tooling, and let them own the whole loop.

At a glance

Client
A UK B2B software business
Engagement
Rebuild of the customer portal
How it was staffed
External PM, PO, design studio and QA house
What we changed
Four senior engineers owning research through release
The tooling
Agentic assistants and harnesses built around the engineers
Our role
Delivery, tooling and clean handover

The turning point

We removed the hand-offs instead of managing them

The four of them took everything: the research, the spec they would build against, screens prototyped in code rather than in a design tool, tests generated and reviewed as they went. The agentic tooling absorbed most of what the client used to buy in - the exploratory test sweep, the first draft of a regression pack, the survey of a legacy codebase nobody had read in years - and did it the afternoon the question came up, not the sprint after.

What was left was the part that doesn’t automate: deciding what to build, and being answerable for it. That stayed with the people writing the code, where it had always belonged. The fortnight became a day.

5 hand-offs
a single change made before it reached a user
9 of 14 days
of a typical change spent waiting, not building
Same day
from agreed change to production, once the loop closed

What we found

  • Every hand-off is a queue. The people in ours were good at their jobs; the waiting between them was the cost, and no amount of coordination was going to remove it.
  • The engineers who do the research should build the thing. The understanding earned in week one is exactly what gets lost when the work is handed to someone else in week three.
  • The tooling didn’t replace an engineer. It removed the reasons we had been hiring around one.
  • It only worked because the tooling was built around the developers. The harnesses, generators and evaluation loops we wrote for that team are why four people could hold the whole loop.
  • The old staffing model wasn’t wrong when it was written. It was written for a world where none of this existed.
This engagement became the model for the whole firm - read our vision
05
Model or parser

The feature that never needed a model

An insurance broker engaged us to build what their roadmap called AI-powered invoice ingest. A handful of suppliers sent the same file every month, in the same fixed schema, columns in the same order - and a language model was going to read it, understand it, and post the totals to the ledger.

The product manager who designed the flow wasn’t technical and had never been asked to be. From the outside, a system that answers a question correctly is a system that answers a question correctly, and the newest way of doing it looks like the best one. The distinction the whole design turned on - a parser is either right or it stops, a model is only ever plausible - was one they had no reason to know existed.

We flagged it in the first week. But the flow was already signed off and had been demoed to the end users as “the AI reading your invoices”. So we spent two weeks teaching a language model to read a file whose shape had never once changed.

At a glance

Client
A UK insurance broker
Engagement
An “AI-powered” supplier invoice ingest
Original plan
A language model reading a fixed-schema file
Why
A non-technical PM owned the flow, and signed it off
What we changed
A parser for the columns, a model only for the free text
Our role
Delivery and integration - and, eventually, the parser

The turning point

The parser took an afternoon, and never got a row wrong

Eventually one of the engineers stopped arguing and just wrote it: about two hundred lines of parser, run against forty thousand historical rows in nine seconds. It matched every one. The model we had spent two weeks on was at 98.7% - and the misses were the dangerous kind. Not crashes. Totals that looked completely reasonable and were quietly wrong by a decimal place.

The model kept exactly one job - the free-text notes field, where the input really is unstructured and a good guess beats no answer. Everything with a column heading went back to plain code. The lesson wasn’t that the model was bad. It was that the decision about where to use it sat with someone who couldn’t evaluate the answer, and nobody had built a step where the people who could were asked first.

2 weeks
teaching a model to read a file with a fixed schema
1 afternoon
to write the parser that replaced it
98.7%
model accuracy - and the 1.3% were silent, not loud

What we found

  • A parser is right or it stops. A model is plausible. Those are not two flavours of the same thing, and if the input has a fixed schema you don’t need a guess.
  • The failure to fear is the quiet one. A broken parser halts the run and someone looks at it; a wrong model posts a plausible number to the ledger.
  • Use a model where the input is genuinely unstructured, and nowhere else. The notes field kept its assistant. The columns never needed one.
  • The engineer who said all this in week one was right in week one. The two weeks were the cost of a sign-off process that never asked them.
This judgement is built into our AI & automation service
06
Design, afterwards

The screens were beautiful, and the product didn’t work that way

We joined a field-services company three months after a design studio had finished its work: sixty-four screens, signed off, rendered to the pixel, for a tool that schedules the engineers who fix boilers and broadband in people’s houses. No code existed yet, and everyone was pleased.

The studio was good. It had also never sat with a dispatcher. The screens assumed a job has one engineer, at one address, on one day. Real jobs split in half, get handed to a second engineer at two in the afternoon, and finish at an address nobody had heard of that morning. There was no screen for any of that.

The developers built to the mock-ups anyway, because the mock-ups were what had been signed. Every state the designs hadn’t imagined became a workaround, and the workarounds became the product. Three weeks in, someone asked what the screen looked like when a job was reassigned mid-shift. There wasn’t one.

At a glance

Client
A UK field-services company
Engagement
Scheduling and dispatch for field engineers
How it started
64 signed-off screens from an external design studio
The problem
The studio had never watched the work the product describes
What we changed
Build the functionality first, design it once it is real
Our role
Delivery, and rebuilding the flows the mock-ups had missed

The turning point

We built it plain first, and designed it once it was real

We stopped drawing and started building: plain screens, barely styled, wired to real data and put in front of real dispatchers. Within a fortnight we had found seventeen states a job could actually be in, against the three the mock-ups allowed for. Half of them were the awkward ones - reassigned, part-completed, cancelled while the engineer was already at the door.

Then we brought in a designer. One, embedded with the team, working on a product that existed rather than a picture of one. Their work was better for it: they weren’t guessing which states needed a screen, they could open the app and count all seventeen. Design stopped being a blueprint handed down to the developers and went back to being what it is good at - making something that already works clear and quick to use.

64 screens
designed and signed off before any code existed
3 of 17
real job states the mock-ups had allowed for
2 weeks
of plain screens on real data to find the other fourteen

What we found

  • A mock-up is a claim about how the domain behaves, usually made by whoever has watched the domain least.
  • Developers will build the impossible state rather than argue with a signed picture. Authority sat with the artefact nobody could test.
  • Ugly and correct comes first. A plain screen on real data tells you in a day which states exist; a beautiful one tells you what someone assumed.
  • Design is neither the wrapping nor the blueprint. Brought in once the thing is real, a designer makes something true better - and their work improves, because the answers are in front of them.
This lesson became our product & UX design service
What we learned

Six lessons we kept

One from each project above, in the order they came. Together they’re most of how we work now: understand the system before you build, measure before you automate, and keep the decisions with the people who can evaluate the answer.

Read the system before you replace it

Most of what gets called legacy is a few specific problems nobody has looked at closely. Four weeks in the code is cheaper than eighteen months of rebuild - and sometimes the right recommendation is the one that loses you the contract.

Replace the plumbing, not the tools people trust

Fifteen years of checked numbers beats any dashboard. Put the new system underneath what people already use, let it earn agreement month after month, and the migration largely takes care of itself.

Scope it until you can score it

“Answers anything” has no pass mark, so it never gets signed off. Cut the work down to one thing you can grade, build the scoring before the feature, and keep a person behind everything the system isn’t yet trusted with.

Remove the hand-offs, don’t manage them

Every hand-off is a queue, however good the people standing in it. Senior engineers who do the research should build what they researched - and agentic tooling has removed most of the reasons anyone ever staffed around them.

Reach for a model only when a guess beats nothing

A parser is right or it stops; a model is merely plausible. If the input has a fixed schema, certainty is cheaper, faster and safer than intelligence - and the decision belongs with people who can tell the difference.

Design what exists, not what might

Screens drawn before code are guesses about a domain nobody has watched yet, and developers will build the impossible state rather than argue with a picture. Get it working plainly first, then bring in a designer to make it good.

Six projects taught us this. Yours doesn’t have to.

Book a free consultation. We’ll talk through what you’re building, where the waiting and the risk are hiding, and the shortest route to working software in front of real users.