aeternum

What we check before a real business uses it

Before a driving school could depend on our own product, we audited it the way we would audit one we inherited. What makes that useful is not the list it produces. It is the rule it follows about what counts as knowing something.

DriveFlow is our own product, a platform for Swiss driving schools covering booking, the training record, billing and school administration. We built it, we run it, and it is going into pilot.

Before that, we audited it as if somebody else had written it and we had been asked whether it was safe to depend on.

That is a normal thing to do for a client. It is an easy thing to skip on your own product, and skipping it is how most small teams end up learning about their software from the people paying for it.

The rule that makes an audit worth anything

The temptation with your own code is to answer the readiness question by consulting how you feel about it. You know which parts are solid because you built them, and that knowledge quietly substitutes for evidence.

So the audit ran on one rule. A claim about whether the system works counts only if something was actually run. Anything that came from knowing the codebase instead had to be labelled as inference, in the report, in writing.

That sounds like bookkeeping until you apply it and notice how much of a normal readiness conversation is inference wearing the clothes of a fact. The security review is a good example. It was a static read: nothing was executed against the live database or a payment account. That limitation is written at the top of the document, because a reader who did not know it would reasonably treat every statement inside as tested.

Labelling it costs one paragraph. Not labelling it means the next person to read the report, including us in six months, mistakes a careful opinion for a measurement.

The four questions

We ask them in the order the business cares about, not the order the code is organised in.

Can somebody read data that is not theirs. Can somebody change data that is not theirs. Does the money arrive where it is supposed to. And if any of those goes wrong, would we find out.

The first three are about the system. The fourth is about us, and it is the one small teams answer worst, because it is the only one where the honest answer often turns out to be no.

What came out well

The application layer held up. Every route authenticates, checks that the request belongs to the right school before it does anything, and only then writes with elevated privileges. The order matters: a check that happens after the write is not a check.

The money handling was careful in the specific ways that are painful to retrofit. The payment webhook claims a payment exactly once, so a retried delivery cannot double-charge. It refunds automatically when the thing being paid for fails to materialise. It never re-reads a price after the charge, which is the gap through which a changed price silently rewrites a completed transaction.

None of that was luck. It is what comes out of putting billing in during the first week rather than bolting it on once there is something to bill for.

Where the work went

The substantial change was moving authorisation down a level.

Checks that live in application code are correct until somebody adds a route and forgets to call them, and that person is usually you, eighteen months later, in a hurry. Checks that live at the database mutation boundary cannot be forgotten, because there is no path around them. One migration moved a long list of them into that layer, which is the right place for them and the reason the equivalent list will not reappear.

That is a general principle rather than a DriveFlow one. If a system’s rule about who may change what exists only in the code that happens to call it today, then that rule is a convention. Put it where the data lives and it becomes a constraint.

The finding we did not expect

The audit’s most useful result was not about the product. It was that our test suite had been telling us less than we thought.

Fourteen end-to-end specs, around 157 tests, covering booking, onboarding, invitations, school-owner flows and accessibility. Depth was never the problem. The problem was that a test with no credentials available skipped itself, and in a summary line a skipped test and a passing test look exactly alike. So a green run had been proving very little, quietly, for a while.

That is worse than a failing suite. A failing suite tells you to go and look.

The wider version of this is worth carrying into any project old enough to have accumulated tooling. Work moves the product forward, and nothing in the process notices when the evidence layer moves backwards. Nobody decides to let it happen. It happens because progress is measured and the measurements are not.

It is fixed, and the fix is structural rather than a resolution to be careful: the toolchain now runs on every push and every pull request, and it gates on four checks rather than on whether anybody remembered to run them.

What this means for your project

When you commission software, everybody you talk to will say they test. The question that separates them is what the last audit found and what happened next.

A team that has never written down a conclusion it did not like has either been extraordinarily lucky or has not looked hard enough to be in a position to dislike anything. The verdict is not the valuable part. The willingness to write one down before deciding how you feel about it is.

That is most of what product development is once the building is done: knowing what has been verified, keeping it separate from what is merely believed, and being able to tell a client which is which without having to go and check first. The same instinct runs through how we decide where a model is allowed to run, where the interesting question is again which claims have been tested rather than assumed.

We will write again once DriveFlow is running in real schools. That post will be more useful than this one, because a pilot teaches things no audit can reach.

The service behind this

Product Development in detailScope is the only lever that reliably moves a deadline.

Questions about this.

Do you run this on client work, or only on your own product?

Both, and the same way. The difference with a client project is that we are reading somebody else's decisions rather than our own, which is easier to do honestly. On your own product there is nobody to hand the report to, so the discipline has to come from the format instead.

What does an audit like this actually cost in time?

Less than people expect, because most of it is reading rather than building. The expensive part is not the audit, it is what it finds, and finding it before a business depends on the system is the entire point. Nobody has ever told us afterwards that they would rather have discovered it in production.

Is DriveFlow live with driving schools?

It is going into pilot. That is the step after this audit and before anything that deserves to be called a launch. When schools are running on it we will write about what the pilot taught us, which will be more useful than anything we could write beforehand.

Tell us what you want to build.

Building something in this direction? Tell us what you want to build.

Keep reading

  1. The Swiss case for running a model on your own hardwareAI6 min read
  2. The AI Act got delayed. Three parts of it did not.AI4 min read