Whoever commissions an audit usually expects a verdict on the code. I look at the code last. Not out of affectation, but because it gives the least reliable account of the risk: I can read an ugly file in an hour and still not know whether this team can ship an update next month.
So every audit starts with a question that has nothing to do with aesthetics: what does the next change cost, and what stands in its way?
Why the order decides the outcome
Ten working days are tight for an unfamiliar codebase. You can try to read all of it and fail, or you can inspect it in an order where each step shrinks the next. I do the second.
The order follows one principle: first what blocks further development, then what slows it down, last what makes it unpleasant. A project that cannot be built does not have an architecture problem — it has a build problem, and until that is solved every statement about the architecture is speculation.
It is also why I rank findings by the cost of the next change rather than by the severity of the violation. The two coincide less often than you would think.
First: does it build, on someone else's machine
The first test is the handover itself. Clone the repository, resolve dependencies, build, run it on a device — without anyone who knows the project talking me through it.
Whatever goes wrong here is the actual finding. Missing configuration files that were never committed. A step everyone on the team knows and nobody wrote down. Signing that hangs off a personal account. Every one of these hurdles costs a new developer days, and it costs them those days again every time.
I measure only two things: how long it takes me to get a running build, and how often I had to ask. Both go into the report, because both directly predict the onboarding time of every future developer.
Then: the dependencies and their expiry date
Next I look at what the app consists of besides its own code. The number of libraries says little. Their condition says everything: which are still maintained, which have been untouched for years, which are pinned to a platform version Apple will soon stop accepting.
The critical case is an unmaintained library in a central position — networking, database, authentication. It works perfectly today and is still an item with a deadline on it: at the next forced SDK change it becomes the blocker, and replacing it then hits everything it touches.
The reverse direction matters just as much: your own code welded so tightly to such a library that swapping it tears open half the app. That is the finding that later carries the highest effort estimate in the catalogue, even though nothing in the code looks broken.
Then: tests, but as information about the team
Coverage as a percentage says almost nothing. What matters is what is tested. Do the tests sit where the money is made — payment, sign-in, data synchronisation — or where they were easy to write?
Two questions answer this faster than any metric. Do the tests actually run in CI, or were they switched off at some point? And: when was the last test written? A suite that stopped two years ago is not a safety net, it is an artefact.
What I read here is less a technical state than an account of the pressure this team was last working under.
Then: the path from commit to store
Now the question gets concrete: how does a finished change reach users, and who is able to walk that path? I look at whether an automated pipeline exists at all, how long a release takes, how many steps are manual, and how many people can perform them.
The answer to that last question is surprisingly often: one. That is an architecture finding, even though it appears in no class. A release path only one person can operate is the same risk as an account that runs on a single name.
How often the app was actually released in recent months also says more about its changeability than any diagram. Where nothing has shipped for a long time, it is usually not demand that fell asleep but the path that became too unpleasant.
And only then: the code
By the time I reach the code, I already know where to look. I do not read all of it — I read the places the previous steps flagged: what every change touches, what hangs off the outdated library, what is untested and business-critical at the same time.
There I look at changeability, not beauty. How many files do I have to touch to add one field? Is there a recognisable layering, or does every part know every other? How large are the classes everything else depends on?
Ugly code that builds reliably, can be tested and ships regularly is a manageable problem. Elegant code nobody can release is not.
What this order is not good for
This order produces no quality verdict, and some clients miss it. Anyone expecting a grade for their codebase, or confirmation that their predecessor did bad work, will not get it from me. The catalogue says what makes the next change expensive — not who is to blame.
The second cost is genuine imprecision: in ten days I do not read the entire codebase. I sample along the risks the first steps exposed. A bug outside those tracks can escape me. That is stated in the report, because claiming completeness after ten days would be dishonest.
Where this does not work
The order assumes there is continued development whose cost can be measured. When the underlying question is a different one — sell, discontinue, rebuild from scratch — the focus shifts, and questions of data migration and operational risk matter more than changeability.
It also works poorly for very small apps. Where there are a few thousand lines in total, a structured audit is overhead: you simply read the code, and that takes two days rather than ten.
And it does not replace a security audit. I check fundamentals — how credentials, keys and user data are handled. A penetration test is a different exercise and belongs in different hands.
What you are left with
After ten days there is a prioritised action catalogue: every finding with a risk rating, an estimated effort and a recommended order. Not an appraisal for the shelf, but a list a team can start working through on Monday.
The most common reaction in the closing session, incidentally, is not surprise. It is relief that what everyone suspected now has a number and a sequence attached. That is exactly what the document is for: it turns a gut feeling into a basis for deciding — including the decision to do nothing for now.
How this is cut as a package is described on the iOS architecture audit page.