The blogBrick by brick · Episode 1/5

My first project doesn't build anything

It reads code someone else already wrote, measures what state it's in, and says where to start. Here's why I laid this brick first.

"Brick by brick" series, Episode 1/5 · 2. Documented search · 3. The FHIR bridge · 4. ITFacto · 5. The model is the last question


You don't build a wall out of order

Every brick carries the next one. A brick laid too early rests on nothing, and the problem isn't that it collapses - it's that it doesn't collapse straight away.

We build AI systems exactly like that, except we forget it. The question I get asked first is always the same one: which model. It arrives three bricks too early.

This series is about three public demonstrators, twenty months inside a company, and above all the order in which I laid them. Let's start with the first brick, the one that surprises people most: my first project doesn't build anything at all.


The skill that just changed sides

Writing code has never been easier. In 2026, an assisted developer ships in a day what used to take a week, and a beginner gets something in three minutes that compiles, runs, and looks right.

It's that last part that should occupy us. Looks right.

Scarcity has moved. It isn't in production any more, it's in reading. Being able to open a repository you didn't write, in a few minutes, and say where it's weak, what will get expensive in six months, and what to fix first. That skill hasn't been automated, and demand for it has grown at exactly the rate code started raining down.

Which is why my first tool is a tool that looks. You give it a GitHub handle, it walks the public repositories, it measures, and it sends back a report. It never executes the code. It never touches anything private. It doesn't produce a single line. It analyses, and it proposes.


Everyone can say "good code", nobody can define it

Try the experiment in a team meeting. Ask what well-built code is. You'll get five answers, all sincere, all different, and none of them written down anywhere.

For one person it's readability. For another, tests. For a third, simplicity - a notion nobody agrees on either. And if you ask them to compare two repositories, you'll harvest impressions, not arguments.

But you can't improve what you can't describe. That's true of code, it's true of everything else, and it's precisely the wall most projects hit when they set out to "improve the quality" of anything.

So my real first task wasn't development. It was writing down my definition, in six axes I stand behind as a position:

  • Structure and readability. Complexity, duplication, file size, organisation.
  • Security. Secrets exposed in history, vulnerabilities detectable by static analysis.
  • Debt under control. Where changes concentrate, and the files everyone avoids touching.
  • Rhythm and curation. Commit granularity, generated files committed by accident, hygiene of the history.
  • Tests. Their presence, their integration into CI, the share of code actually covered.
  • Dependencies. Manifest present, versions pinned.

Six axes is few. That's deliberate. A grid you can't hold in your head isn't a grid, it's a form, and forms change nobody's behaviour.

And those six axes are arguable. Someone can legitimately dispute how they're weighted. Good: a definition you can dispute is a definition that exists. That's already infinitely more than an impression.


A score that moves from one day to the next isn't a score

Here is the difficulty I didn't see coming, and which took up most of the project.

Ask a language model to grade a repository out of a hundred. It will give you a number. Ask again tomorrow, same repository: the number will have moved. Ask it to compare two projects it graded separately, and you'll discover the two scores were never on the same scale.

That isn't a flaw in the model, it's a property. A judgement with no reference point is an opinion, elegantly phrased.

Hence two construction principles. First, measure before interpreting: the objective metrics are computed, not guessed, and the AI comes in afterwards, to explain and to prioritise. Second, calibrate the score against a reference corpus, so that a number means something relative to comparable repositories rather than relative to the mood of one run.

That corpus had to be built. 2,784 public repositories measured, sampled in strata: seven languages, four popularity bands - including projects under ten stars, so as not to calibrate on the elite - and several activity windows, with a minimum of thirty repositories per stratum on pain of merging into the parent stratum.

The count varies from one metric to another, from 2,245 to 2,784, and that isn't a collection defect: a metric only counts where it has surface to stand on. A repository with no tests doesn't have poor coverage, it has none. Conflating the two would mean penalising the absence of material as though it were a quality defect.

So a score isn't compared to a threshold I decided. It's compared to a percentile: your position among projects that resemble yours. That's the only way to get a score that discriminates instead of flattering everyone at 72 out of 100.

A number you can't defend to someone who disagrees is worth nothing. In an earlier professional life I spent years having to defend findings in front of people my conclusions did not suit. You learn quickly there that an assessment stands or falls on its method.


Reporting isn't enough

An audit that merely lists what's wrong produces a very well-documented effect: you read it, you feel bad, you do nothing.

Which is why the tool doesn't stop at measuring. It sorts. Recommendations come out ranked by impact and by effort, each with one concrete action, because the only question that matters when you inherit an imperfect project isn't "what's wrong", it's "what do I start with on Monday".

And the report also says what's going well. A summary of recurring strengths, phrased without flattery. That isn't politeness: you can't consolidate what you haven't identified, and a developer who doesn't know what they do well will lose it at the next rewrite.

The difference comes down to one word. A tool that judges ranks people. A tool that analyses and proposes gives them a handle. Only the second one is any use.


What this brick was carrying

I hadn't planned to start here. I started here because I couldn't do otherwise.

The systems I was going to build next all rested on a promise of reliability. And I had no way of backing that promise until I'd written down what reliable meant, and what would measure it. I'd have been asking to be taken at my word. Which is exactly what I hold against demonstrations that impress and prove nothing.

The Auditor served against me first. My own repositories went under it, and it wasn't comfortable.

Here's the brick, and it's worth well beyond code:

You don't build reliable until you've written down, in black and white and in measurable terms, what reliable means.

Transpose it to any project at all. How will we know this system works? If nobody can answer at kickoff, nobody will be able to answer at delivery either. You'll settle for an opinion - usually the opinion of the most convincing person in the room.


Last word

This first brick was only a yardstick. A yardstick is no use until you measure something with it.

So what remained was to build something under my own criteria, and to do it on the most demanding ground I know: a field where a plausible but wrong answer does more damage than no answer at all.

That's Episode 2.


📖 In the same series - Episode 2: documented search (an answer that cites its sources, or says nothing) · Episode 3: the FHIR bridge (plugging knowledge into the real world) · Episode 4: ITFacto (twenty months, five applications, real users) · Episode 5: the model is the last question (the four questions for the first meeting).

The three systems described in this series are online and public. I design traceable, verifiable AI systems, from use case to deployment - more about my background, or write to contact@lamoulinette.ai.

← Back to the blog