Skip to content
Hominis Agentic OS · early access program now openJoin the waitlist
RealAI

Case studiesFinancial services technology

Case study
Financial services technologyA European banking group's IT services subsidiary

Ten prescribed practices handed to a supplier, and every line answers a defect the review had already recorded

A European banking group's IT services subsidiary commissioned a post-mortem review of an offshore build that was stopped before user acceptance testing. The review read the contract and the project record, interviewed both sides, inspected a sample of the codebase and compared two builds taken about ten weeks apart, finding no improvement between them sufficient to allow acceptance testing. It produced five technical recommendations, the last of which was a single slide carrying ten development practices addressed to the supplier. Read alone the ten look generic. Read against the preceding findings, each one is the inverse of something the review had already recorded: the clone list, the caching race conditions, the swallowed exceptions, the authorisation checks the penetration test walked past. Automated test coverage across both stacks sat at roughly 10 to 15 percent. What this engagement produced was findings and recommendations, not a remediated codebase.

10Prescribed practices, each traceable to a defect class already observed
Client
A European banking group's IT services subsidiary
Duration
Post-project review, findings and recommendations
AI · RIDGE E77.3 N68.8ρmax 1.00
10 to 15%Automated test coverage found across both stacks
5Technical recommendations, of which the hygiene list is the last
2 buildsCompared about ten weeks apart, with no improvement sufficient to allow acceptance testing

Any review can end with a list of good practices. The list writes itself, it offends nobody, and it survives a steering group because no one argues against commenting their code. That is why the closing hygiene slide is the least trusted page in a review report. Readers skip it, and they are usually right to.

A European banking group's IT services subsidiary commissioned a post-mortem review of an offshore software development engagement stopped before user acceptance testing began. The review read the contract, interviewed both sides, inspected a sample of the codebase against selected quality characteristics from the relevant international standard, and compared two builds taken about ten weeks apart to see whether quality was moving. It found no improvement sufficient to allow acceptance testing. The technical recommendations came to five, and the last was one slide carrying ten development practices addressed to the supplier.

The challenge

The ten lines are ordinary. Comment and document as you write, using what the development environment already gives you. Adhere to the object-oriented design principles the contract already named. Build shared controls for common functionality so they can be reused. Keep type usage consistent across the codebase. Keep the code readable through capitalised query keywords, consistent temporary names, limited line length and shallow nesting. Dispose of unmanaged resources such as file and network handles as soon as they are finished with. Avoid type conversion where it carries a performance cost. Do not paste code in from elsewhere. Block cross-site scripting and injection attacks and test for vulnerabilities frequently. Check for memory leaks, handle exceptions properly and log them every time.

Nothing on that list would surprise a competent developer. Which is the point of reading it backwards.

Every line is the inverse of a defect the review had already recorded, with a tracker reference attached. The design-principle line exists because the codebase violated the principle set the contract had required, with classes carrying too many unrelated concerns, and because the patterns in use had been adopted without being understood: dependencies left to automatic injection rather than stated, synchronous and asynchronous code mixed in one place, observer subscriptions never balanced by unsubscriptions.

The commenting and documentation line exists because the system design document was missing. The contract carried it as a deliverable, and the review found no evidence of one describing the coding standards, the design principles, or the reasoning behind the way the build was being approached. Without it the client's own architects could not follow the development logic in the software they were paying for.

The reuse line and the copy-paste line exist because the reviewers found clones: repeated blocks differing in small details that could have been one private function, and blocks copied into unrelated areas that should have been a service call. The review named the cost. A fix has to be propagated across an unknown number of files, because nobody knows how many copies exist.

The unmanaged-resource and memory-leak lines exist because memory leaks were already listed among the consequences of the patterns observed, and because resource management in the front end had no consistent concept behind it. Packages of up to a hundred kilobytes crossed the wire, and the data context was passed back and forth on every call. There was data loss.

The exception-handling line exists because of a specific habit. To avoid throwing errors, the code tested whether the next statement was executable and skipped it when it was not. The exceptions stopped appearing. The consequences of the skipped statements did not, and surfaced later somewhere else, which is worse than a stack trace.

The security line exists because a penetration test had already walked past the authorisation checks. Not every service call tested for the caller's rights. In several places a property missing from the server response was created on the client, and the server then accepted the invented value as correct. Data could disappear from the database, and a malicious user could alter it without going through the front end.

The consistency, readability and type-conversion lines come from the typing findings, where typing of variables and properties was insufficient, implicit casting hid bugs that surfaced later through unrelated changes, and an enumeration's value was verified by looking up its index from the string form of its own name.

The approach

Derivation is what gives a hygiene list its authority, and it also decides whether the list is enforceable. A generic practice cannot be checked. A practice written against an observed defect class comes with its own test, because the defect is the test.

The four recommendations that preceded it were built the same way. Design and coding standards were to be agreed in advance rather than assumed, with a review over at least ten percent of the code and non-conformance extrapolated from that sample. Guidelines were to name the design problems the team would meet, the pattern for each and the anti-patterns to avoid, with the supplier's architect owning that choice jointly with the client's. Automated tooling was to check the code against an agreed quality model and report back, making conformance a measurement rather than an opinion. And peer review was to happen consistently rather than when time allowed.

That fourth one carried the only quantities on the page. Review no more than a few hundred lines at a sitting, because past roughly three to four hundred lines defect density drops and yield settles into a band of seventy to ninety percent. Keep the inspection rate below five to six hundred lines an hour, since reading faster stops finding things. Annotate the code beforehand, and keep a checklist of your own repeated mistakes. The review cited published inspection research, and projects where diligent peer review is reported to have saved as much as half of total development cost. That is a cited claim about other projects, not a result this engagement delivered.

Automated test coverage across both stacks was roughly ten to fifteen percent. At that level a quality model is aspiration, and the tooling recommendation is what makes the other nine lines observable rather than declared.

The outcome

A review produces findings and recommendations. No code was remediated here. The build had been stopped, the application was assessed as incomplete, error-prone and unfit for acceptance testing, and the recommendations were phased for a client and a supplier who might never work together again. The deliverable was a derived list with evidence attached to every line, plus a sequence for acting on it.

What would be done differently now is where the evidence comes from. Each of those ten practices leaves a trace in systems the project already ran. Clone density, nesting depth, coverage by module, exception handling that swallows rather than raises: static analysis reads all of it on every commit. The recommendation on that page asked instead for a manual review across at least a tenth of the code with non-conformance extrapolated from the sample, which was the right answer for a fixed budget and the wrong one once a codebase can be measured continuously and the trend published to both parties.

The same holds for the project record. Defect ageing, rework rates and the path a ticket takes through the workflow sit in the tracker already. Process mining over those events gives the delivery finding a source rather than an interview quote, early enough to matter. That is the part that failed here. The quality problems were noticed in the first months and escalated, and nothing changed for months after, because neither party had a measured position to argue from.

That pattern shows up wherever we work on data readiness and machine learning pipelines. Teams ask for a model long before their delivery process can tell them whether anything it produces was any good. A model that scores code or triages a defect queue needs a defect class it is measured against and a lineage record of what it saw when it decided. The current wave of cautious language-model pilots in code review runs into exactly this, because a model can summarise a diff convincingly and be scored against nothing. The Platform work we do begins with the defect classes and their measurement, and Consult engagements start by asking what an organisation can already observe.

A hygiene list is not weak because it is basic. It is weak when it is recited. Ten lines derived from ten observed defect classes are a specification for the next build. The same ten lines copied from a handbook are a page everyone agrees with and nobody implements.

NEXT STEP

Ready to make AI real?