Method

Why VibeLock will never give you a security score

Reproducibility is not a nice property of a security claim. It is the whole product, and it is what rules out every number we could have invented.

Dr Kelvin K Awagu6 September 20267 min read

The obvious way to build a security rating in 2026 is to hand a model your project and ask it for a number out of a hundred. It takes an afternoon. It demos well. It is also the one design that cannot do the job the number exists to do.

The job is narrow, and it is not “assess security”. Plenty of tools assess security. The job is to give a founder something they can put in front of an investor, an enterprise buyer or a procurement questionnaire, and have it hold up when that person pushes back on it. Everything below comes from taking that one sentence seriously for longer than is comfortable.

The question that breaks a model generated score

Imagine you send a security number to a prospective customer’s reviewer and they reply with four words: “how did you get 82?”

If a model produced it, you cannot answer. You can describe the inputs it saw, but you cannot show the step from those inputs to 82, because there was no step. You cannot show that the same project would produce 82 again tomorrow, because it might not. You cannot show which of your open items cost you the eighteen points, so you cannot tell them what you are doing about it.

Worse, the reviewer can run the experiment themselves. They change nothing, ask again, and get 79. At that point the number is not evidence of anything, and neither is the rest of your submission, because you offered it as evidence and it did not hold.

Computing it yourself does not save it

The apparent fix is to compute the number with a pure function over evidence the product observed, publish the function, and let anyone recompute it. Same inputs, same output, every time, on any machine, with no network call. When a reviewer asks how you got 82, you hand them the arithmetic.

That answer holds for about one question. The next one is the one that matters: you chose those weights. Why is this control critical and that one medium? Reproducing an arbitrary judgement is not the same as defending it. You have made the judgement repeatable, not sourceable, and a reviewer who wants to argue has nothing to argue with except your authority.

Reproducing an arbitrary judgement is not the same as defending it. A weight nobody outside the company can check is a claim resting on our authority, which is the one thing this product cannot afford.

A weight is a liability with no upside

Weights are also less load bearing than the argument about them suggests. Perturb any single severity weight in a scheme like this by ten percent and coverage moves by roughly a sixth of a point. Twenty five percent moves it by four tenths. Halving or doubling one, far outside any defensible disagreement, moves it by under a point.

That is not a defence of the weight. A parameter that must be defended, cannot be sourced, and does not change the answer is not a feature. It is a liability with no upside, and the right thing to do with it is to not have one.

What the product reports instead

Every control maps to a requirement somebody else published: an OWASP ASVS 5.0 requirement with its own identifier and level, an article of the GDPR or the EU AI Act, or an entry in the OWASP Top Ten for LLM Applications. A control that satisfies no published requirement is not in the catalogue, however good a practice it might be.

A requirement is met when every applicable control mapped to it is verified. The output is a plain fraction per framework and level, for example 53 of 56 ASVS Level 1 requirements met, with the three outstanding ones named. There is no weighting, because there is nothing to weigh. There is no severity of ours, because a control inherits its tier from the requirement it satisfies, and OWASP decided that.

The reviewer’s question now has a better answer than arithmetic. They can obtain the standard, read requirement V8.2.2, read the controls we map to it, and tell us the mapping is wrong. That is a real conversation. “Why 0.30 and not 0.22” never was.

And no launch verdict either

The same argument rules out the rule everyone expects next: an application is ready when every applicable Level 1 requirement is met, no prohibited AI practice is declared, and the repository host reports no open alert. It looks safe, because every condition in it belongs to somebody else.

It is not. Choosing which conditions to conjoin, and declaring their conjunction the moment an application may be shipped, is an authorial act with far more consequence than a severity weight. A weight that moves a number by under a point is a small claim. Telling a founder they are ready to expose an application to real users is a large one, and nothing we can observe supports it. We see the application and its code. We do not see their users, their data, their threat environment or their obligations, and readiness is a function of all four.

There is a structural tell as well. Every other output is falsifiable: get the standard, check the mapping, argue. A readiness verdict is not, because no external document defines it. It would be the one claim in the product that could only be accepted on our authority.

Where a model does help

None of this is an argument that models are useless here. Drafting a threat model from a project description, explaining what a finding means to someone who cannot read a CVE report, reading a repository to determine whether one specific control holds: these are language problems, and models are good at them.

The line is between producing evidence a human can check and grading a human. VibeLock does the first everywhere and the second nowhere. Every model-produced verdict is labelled as reasoned, bound to the commit it was read at, and attached to a single named control, so a reader who distrusts it can discount exactly that record and keep the rest.

What that leaves is smaller than a number out of a hundred. It is also the only version that survives the meeting it was made for.