How we reviewed this: on four CPU cores in python:3.12-slim, no GPU, --network none, with the published JevForge-0.8B checkpoint from a local cache. We ran its server, sent the example from its own README, walked the validation paths, watched what it writes to disk, and ran its tests. This is an open model — our own run of their model, with no Jev calls.
What it does
An end-to-end toolkit for the other direction: synthesise decision records, fine-tune an 0.8B backbone on them with cross-entropy and Brier objectives, calibrate the result, evaluate on frozen splits, then serve it behind POST /v1/systemone. The worked example is web navigation — a task, a list of DOM elements, and a typed question about which element to use next.
Setup
pip install -r requirements.txt and one command. The checkpoint directory can be the Hugging Face snapshot as it downloads, and --device cpu works:
GET /health {"ready": true, "model": "jevforge/Qwen3.5-0.8B", "calls": 0}
GET /v1/models {"data":[{"id":"jevforge/Qwen3.5-0.8B","owned_by":"jevforge","temperature":0.9717}]}
Publishing the fitted temperature in /v1/models is a small thing that more of these should do: the number that shapes every probability you receive is visible to the client without reading the checkpoint.
Using it
The README’s own example runs as printed. On our CPU it answered in about 1.4 seconds, with the full distribution:
Task: open privacy settings. Elements: [e1] Settings, [e2] Submit, [e3] Privacy
→ choice "e2" e1 0.154 · e2 0.663 · e3 0.183 confidence 0.494
That is the answer the shipped checkpoint gives for the example in its own README, and e3 is the element the task names. We report it because it is the documented demonstration, not because a 0.8B picking the wrong DOM node is surprising; the project’s own model card is clear about the size it is.
Validation is strict, specific, and refuses rather than guesses. Seven malformed bodies, seven 422s naming the rule — an unknown type, missing instructions, a one-option choice, an unexpected top-level field, no questions at all, an unsupported field inside a question, and a 97th question against a documented cap of 96. Best of them is the length check:
question team: longest candidate path 835 exceeds max_length=768; refusing to truncate
Permissions and data
This is the part to read before you point it at anything real. Every answered request is appended to a JSONL log — the full state, every question, and the full response — with no redaction and no sampling:
-rw-r--r-- 1 root root logs/jev_requests.jsonl
{"ts": …, "latency_ms": 1403.3, "request": {"state": "Task: open privacy settings. Elements: … CANARY-STATE",
"questions": {…}}, "response": {…}}
The module docstring says why in its second paragraph — “so live traffic can be turned into training records, the data flywheel the project is built around” — so this is a design decision, honestly stated, not an accident. It is still a plaintext transcript of everything your users asked, at default file permissions, on by default. --log-file /dev/null turns it off and the server starts fine that way; there is no flag to redact or sample.
Two smaller things. usage.input_tokens is not a token count — it is the number of candidate paths, which we confirmed by holding the state still and varying the questions:
1 choice (3 options), 47-char state input_tokens 3
+ 1 noul on the same state input_tokens 5
1 noul, state eight times longer input_tokens 2
A client that reads that field to estimate input size gets a number that falls as the state grows. Reported, with a PR offered either way — count real tokens, or keep the path count under a name of its own. And --allow-cors is off by default (we checked: no CORS headers on a cross-origin request), but when you turn it on it sets allow_origins=["*"], all methods, all headers and allow_private_network=True — that last one lets a public web page reach a server on your LAN.
Maintenance
Apache-2.0, a model card, a dataset-format document, a reproduction recipe and a web demo. Two test files, five tests, and they pass in a container with no GPU. There is no CI workflow, so nothing runs them on a push.
Verdict
The most complete “make your own decision model” pipeline we have run, and the serving end is better behaved than most: strict validation, a published temperature, and an explicit refusal instead of silent truncation. Use it to train and serve something small on your own data.
Before production, decide about the log. It is the project’s whole premise and it is off by one flag — but whoever operates it needs to know that logs/jev_requests.jsonl is a complete, readable copy of every state your users sent.
For the same wire format from published weights, see JevK5 and AgentJev; for turning a model you already serve into typed answers, jevify.
See how it compares with other tools in Best Jev tools, tested hands-on.
Review updated Sep 25, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.