# Jev as System One

> Grading code with Jev didn't work. Asking it concrete yes/no questions did: lint rules written as plain sentences, cheap and stable enough to run on every file and every pull request.

Published: 2026-10-15 | Author: Petro Lashyn
Canonical: https://welldigit.com/en/journal/jev-as-system-one

Recently, in September 2026, TypeSafe AI released Jev, a new intelligent AI classification model. Its main difference from classic LLMs is that it doesn't generate text (or any other kind of content). Instead, it responds in only three modes: **Noul**, a yes/no question that returns the probability that the answer is yes; **Choice**, which selects one option from a defined set of up to 255 and returns the selected option, a probability for each option, and a confidence value; and **Score**, which rates content against 2 to 10 ordered, descriptive levels you write and returns a score, a probability for each level, and a confidence value. At the same time, it can handle a lot of context: Jev 1.13 has a 64k-token total context limit, with a separate 32k limit for the state plus the longest question. And the interesting part is that it's extremely cheap and fast. Of course, there is no output token cost at all, because of the specific nature of its answer modes.

It was overhyped at the speed of a comet flying through space. Literally within 48 hours of the release, my Threads and LinkedIn feeds were booming with use cases, examples and experiments around it.

I was also interested in it from day one. Since I now work a lot on building different agentic flows and AI assistant flows, Jev became, right from the start, a real potential puzzle piece that fits into almost every pipeline and helps to leverage LLM requests.

In this sense, it sounds very logical that the idea is hidden in what TypeSafe calls it: a System One model. It's a clear reference to System One of human thinking from *Thinking, Fast and Slow*, the book by Nobel laureate Daniel Kahneman. I read this book some years ago, and it's genuinely interesting from the point of view of how the human brain runs the thinking process. According to Kahneman, there is System One (fast and automatic) and System Two (slow and deliberate).

System One is what answers 2 + 2 without any effort, notices anger in someone's voice, finishes the phrase "bread and…", or drives a car down an empty road while you talk to a passenger. System Two is what you need to multiply 17 × 24, fill in a tax form, squeeze the car into a narrow parking space, or follow one voice in a noisy room. System One runs all the time and hands System Two its impressions and signals; System Two steps in only when something is hard, surprising, or important.

Of course, an agent is not a human, an LLM is not a human brain, and MCP is not a nervous system, but it actually fits the same pattern pretty well. And it's obvious that Jev, as System One, is good at identifying the immediate signal that determines at which level System Two should handle the incoming payload, or whether it should participate at all. System One is perfect for signalling, routing, and setting the accents for what needs to come next.

And there are so many possible scenarios where it could be applied. The easiest example is just sorting out incoming inbox messages in a CRM: is this urgent; is this spam; which of the given categories does it belong to; who should it be assigned to; and so on. Or, for example, it could evaluate the potential severity of an error in a log: sometimes a 500 error in the log is less critical than a 422 or 403, depending on the context.

I actually added it to a real pipeline for our shop assistant, called Vendigit. It evaluates whether the next message is actually about shopping, small talk, off topic, abuse, or nonsense, and depending on this signal, the agent's next step (which tool to choose to build the response) differs.

Another interesting case is using it to evaluate and score different SEO aspects of our own websites. It shows us where we are missing something.

But in this article, I want to share my experiments with using Jev to build a tool for code quality evaluation. This question is more relevant than ever, because the volume of code we produce now is much more than any single developer or software engineer can handle and oversee.

So I set myself a problem: how do I evaluate the code that I write with AI? From experience, I had already solved the "skill" issue and organized playbooks, guidelines and rules. I added every possible architecture test, static analysis, linters, and so on. And it works pretty well: in most cases, I get very predictable, stable output, and the AI coding agent brings me code that follows all the conventions, patterns and structure I defined. But there can still be gaps, especially in logic and flows that go beyond simple functionality. And there is always room for a software engineer to strengthen their "carved in stone" conventions.

So I found that Jev is a good candidate to experiment with this.

## The idea: lint rules written as plain sentences

Static analysis (PHPStan, Larastan, Rector) is exact and free, but it only catches what can be written as a code rule. It can't tell you that "this class does too many things" or "this indirection is pointless". LLM code review (CodeRabbit, Copilot review, Claude) catches exactly these judgement problems, but it's expensive, slow, and gives a different answer on every run. That makes it hard to run on a whole codebase, and even harder to use as a CI gate.

There is nothing in between. What I wanted was judgement-style checks that are cheap and stable enough to run on every file and every pull request.

It isn't a package yet. So far, I've built a small proof-of-concept snippet in Laravel to test the idea. The principle is simple: I write the questions, Jev answers each one with a probability, and my code turns the answers into findings. I evaluated it on our internal CRM, a production Laravel application, so every experiment below runs on real code.

## First attempt: asking Jev to grade code (it didn't work)

My first idea was the obvious one: ask Jev to grade each file from 0 to 100 on six criteria: SOLID, KISS, DRY, Laravel conventions, Atomic, and overall code quality.

The very first file showed the problem. `ProjectStateUpdate.php` is a 4-line action: set the state, save, return. Jev gave it a SOLID score of about 47. My own reading was around 90. On top of that, Jev was split almost 50/50 on whether SOLID could even be assessed for this file, so the answer flipped between runs.

I assumed it was missing context, so I tried again with the file's enum and its only caller attached. Context made Jev more *willing* to judge (the "can this be assessed?" probability rose from 0.46 to 0.79), but it barely changed *what* it judged. The bigger surprise was the six `#[]` metadata attributes on the class: Jev was reading them as complexity. Stripping them pushed the KISS score from 68 to 86. Even in the best setup, a trivial setter scored about 60. Jev simply marks down thin wrapper classes.

Then I needed a fair way to measure detection without scoring code by hand. I took 5 real files from our CRM and copied each one 6 times, planting one deliberate problem per copy: a missing transaction, a duplicated branch, `env()` in an action, a swallowed exception, needless closures, and extra side effects. Since I know the right answer for every copy, I can count exactly what gets caught.

The grades did detect something: 22 of 30 planted problems moved the scores. But three things made them useless as a lint tool:

- **The six scores moved together.** Whenever anything was wrong, all of them dropped. They behaved like one "overall quality" number with six names.
- **Clean code already looked broken.** Untouched files had "problem" probabilities of 0.7–0.8, so no fixed threshold could separate clean code from broken code.
- **Laravel conventions were nearly invisible.** `env()` and `request()` in domain code were missed in every case.

One result was very good news, though: run-to-run noise was under 1 point on the 0–100 scale. Jev is effectively deterministic. That turned out to matter a lot later.

## Second attempt: yes/no questions (this is where it clicked)

Then I went back to what Jev actually is: a System One model. System One doesn't write essays or give verdicts; it notices things. So instead of asking for grades, I asked concrete, checkable yes/no questions:

| Question | Jev's answer |
| --- | --- |
| Is a database query executed inside a loop? | 0.89 |
| Does the code create services with `new` instead of injecting them? | 0.94 |
| Is an exception caught and then ignored? | 0.03 |

I wrote 30 such questions: 21 concrete problem checks and 9 responsibility facts. For responsibilities, I never ask "is this class SOLID?". I ask what the class *does*: does it write to the database, call an HTTP API, send mail, write to a cache, format output? Then the package applies my own rule: two or more side effects in one class means mixed responsibilities. Jev reports facts; my code decides what is good or bad.

Same test files, same planted problems:

| | Grades | Yes/no questions |
| --- | --- | --- |
| Planted problems caught | 22/30 | **29/30** |
| Laravel conventions | 2/5 | **5/5** |
| KISS | 2/5 | **5/5** |
| How clear the signal is | score drops of 5–40 points | probability jumps from ~0.05 to ~0.95 |

The clarity of the signal is what makes it usable. A grade sliding from 72 to 64 needs interpretation. A probability jumping from 0.02 to 0.98 doesn't. `env_outside_config` went from 0.02 on the clean file to 0.98 on the broken copy; `swallowed_exception` from 0.05 to 0.98; `query_in_loop` from 0.09 to 0.95.

The only miss was a duplicated timing-and-log block inside an early return. Even the "false alarms" were instructive: two were caused by my own question wording (fixed afterwards), and the third, `broad_catch` on a file that really does catch `Exception`, was actually correct.

## Does it stay quiet on normal code?

Catching planted bugs is only half the job. A linter that cries wolf on healthy code gets switched off within a week. So I ran the questions on 50 clean files sampled across every layer: actions, pipelines, services, controllers, queries, observers, jobs, commands, models, and more.

Eight checks never fired on clean code at all, while still catching about 95% of planted problems: `needless_indirection`, `functional_overcomplication`, `query_in_loop`, `dispatch_before_commit`, `external_call_in_transaction`, `swallowed_exception`, `env_outside_config` and `missing_types`. Those are ready to be CI gates as they are.

The duplication checks fired on 24–30% of files. But every one I checked was real, for example three near-identical log blocks in one observer. So that's a question of severity, not a detection error.

And the most useful finding: **every verified false alarm had the same cause.** The flagged files didn't contain the problem; their *context files* did. I send dependencies alongside each file so Jev understands the types it works with, and Jev sometimes answered about that context instead of the file itself. The fix is to send dependencies as signatures only (class names and public method signatures, no code bodies), so there is simply no foreign code to flag.

## The full codebase: 2,437 files, 80 seconds, 56 cents

Finally, I pointed it at the whole CRM codebase: `app/`, `src/`, `routes/` and `database/`, with 8 parallel processes.

| | |
| --- | --- |
| Files | 2,437 |
| Time | ~80 seconds (~0.3 s per call) |
| Tokens | 13.4M |
| Cost | **≈ $0.56** |
| Findings | 2,290 in 956 files |

The cost follows a simple pattern: about 3,390 tokens for the 30 questions, plus roughly 0.28 tokens per byte of code. Funnily enough, the questions cost more than the code itself. With signatures-only context, the same scan would cost about $0.43. In total, every experiment I ran during this proof of concept, around 15M tokens, cost me under a dollar.

The files with the most findings were exactly where you'd expect trouble: the large integration, sync and orchestration services. I spot-checked the top one, a 646-line `OutreachSyncService`. Jev flagged a service created with `new` instead of injected (0.94) and a database query inside a `foreach`, a classic N+1 (0.89). Both were correct.

And because the answers are stable (the same file gets the same answers on every run), one run is enough, and any change in the answers means the code changed. That's what makes it cacheable and usable in CI.

## What the package could look like

If I turn this snippet into a real package, every lesson maps directly to a feature:

- **A fixed question set** of 21 problem checks and 9 responsibility facts, each with a default severity.
- **Custom questions in config**, so a team can write its own playbook as sentences: *"Is data fetched outside a Query class?"*, *"Is there business logic in the controller?"*
- **Attribute stripping** before sending, so metadata isn't read as complexity.
- **Signatures-only context**, to remove the one source of false alarms.
- **A fingerprint cache** (file contents + dependency signatures + question-set version + model version), so only what changed gets checked again.
- **`code:scan --since=main`**, which checks only the files changed in a branch, for CI.

Adding a team rule is just one more config entry:

```php
'custom_checks' => [
    'data_outside_query_class' => [
        'question' => 'Is data fetched from the database outside a Query class?',
        'severity' => 'warning',
    ],
],
```

That's the whole pitch: **your team's coding rules, written as plain sentences, enforced at linter cost.**

## Limits worth being honest about

Jev tells you *whether* a problem exists, never *where* or *why*. On a 600-line file, you still have to find it yourself. This is the main weakness, and the fix fits the System One / System Two pattern perfectly: Jev triages the whole codebase for under a dollar, and only the handful of flagged files go to an expensive LLM for line numbers and explanations.

There are other limits. Jev only finds what you ask about. It's an early-access model from a single vendor, and answers can shift between versions, so a package would need to pin the model version and include it in the cache fingerprint. Your code leaves your machine, which some teams can't allow. And all of this was tested on one codebase, our CRM, with one coding style, so other projects may behave differently.

## Conclusion

The biggest lesson for me goes beyond code quality. A System One model is a poor judge but an excellent witness. Ask it for a verdict and you get a vague score where everything moves together. Ask it for facts, one simple question at a time, and you get a sharp, stable and almost free signal that your own rules can turn into decisions.

That's exactly how Kahneman describes our own minds: System One notices, System Two decides. In my pipeline, Jev notices, my rules and static analysis decide, and an LLM steps in only where real thinking is needed. Nobody needs to read every file anymore. You just need to ask the right questions.
