Skip to content
MrJev

System One Harness

Turns a decision model into an agent loop: it compiles the environment's finite action space into typed questions, gates each step by confidence, and records the trace.

View on GitHub →

Hands-on review

Compiles an environment's actions into typed questions, then gates each one by risk: read at 0.5, write at 0.7, destructive at 0.9.

Good for

  • An agent loop where nothing is generated: every step is a pick from a finite list
  • Risk tiers taken from the tool's own MCP annotations, not guessed
  • A gate measured on the weakest judgment an action depends on

Watch out for

  • Thresholds are in code, not on the command line
  • The observation and the whole action space go out every step
  • Version 0.3.1, fourteen commits, one author

Tested Sep 21, 2026 at 5768c4b8177e · Python 3.12 in Docker; its 40 tests, the built-in order environment run live, and an MCP server compiled to an action space

How we reviewed this: we installed it in Docker on Python 3.12, ran its tests, ran the built-in order-fulfilment environment against the real API, and compiled an MCP server’s tools into an action space to see what the harness makes of them. We don’t publish our own measurements of Jev’s speed or cost.

What it does

Most agent loops ask a model to write the next action. This one refuses to: it takes an environment with a finite action space, compiles it into typed questions, and asks which action and which arguments — from lists. Then code executes the pick and observes the result.

The built-in environment, live:

0  add_note(note='gift')              p=0.98 weakest=0.98
1  pick_item(item='scarf')            p=1.00 weakest=1.00
2  pack()                             p=0.99 weakest=0.99
3  choose_carrier(carrier='express')  p=0.98 weakest=0.98
4  ship()                             p=0.98 weakest=0.98

The environment reached a terminal state after 5 actions.
status=completed reason=environment_terminal steps=5 executed=5  goal_met=True

Five steps, one decision each, the goal met. Nothing in that trace was generated text.

The gate is the interesting part

gate.py opens with the clearest statement of purpose we have read in this directory:

The model reports a distribution; the gate decides whether it is enough for the action’s risk. A read-only action may run at 0.5, a destructive one waits for 0.9. The measure is the weakest judgment the action depends on (the action’s own confidence and each parameter’s probability), not their product: the question is “is there one shaky judgment”.

The defaults are {"read": 0.5, "write": 0.7, "destructive": 0.9, "finish": 0.5}, and the verdict is one of run, refused, finish or escalate — with escalate described as “No available action fits the situation; ask for help and stop”. A loop that can say “none of these” is a loop that can be trusted with a list.

Using the weakest link rather than a product is the right call and worth copying: multiplying four 0.9s gives 0.66 and tells you nothing about which judgment was shaky.

Where the risk tier comes from

Not from a guess. s1 tools compiles a live MCP server and shows what it made of each tool:

6 actions, 0 unsupported
  pick_item        write        item: candidates
  pack             write        (no parameters)
  choose_carrier   write        carrier: candidates
  ship             destructive  (no parameters)
  cancel_order     destructive  reason: choices
  add_note         read         note: choices

The tier comes from the tool’s own declaration when it has one, otherwise from MCP’s annotations — readOnlyHint becomes read, destructiveHint becomes destructive, and anything unannotated is treated as write. This is the first project we have reviewed that consumes those annotations for safety rather than ignoring them, and it is a good argument for MCP authors to start setting them.

Being able to print the compiled action space before running anything is the other half: you can see which of your tools the harness considers destructive, and fix the annotation if you disagree.

What to know

The thresholds are not on the command line. --max-steps, --timeout, --model and --json are; the gate values live in actions.py as DEFAULT_GATE. For a value that decides whether a destructive action runs, we would want it in the run command and printed in the trace header.

Every step sends the observation and the action space. That is inherent — the question is “which of these, given this” — but it means the state of whatever you are driving goes to your provider once per step.

Environments. A YAML file, a Python class, an MCP server, or a browser through browser-use. We ran the first and compiled the third; the browser path needs Chrome and a heavier install.

Maintenance

Created 19 September, fourteen commits, Apache-2.0, systemone-harness 0.3.1, one author. 38 tests pass with 2 skipped. Two runtime dependencies (httpx, pyyaml), with MCP and browser support as extras — a dependency footprint you can read in a sitting.

Verdict

If you want an agent loop where the model never writes an action, this is the reference implementation to read. The compile step, the risk tiers from annotations, and the weakest-link gate are three ideas most of the agent projects in this directory would be better for stealing.

Put the gate thresholds in your own configuration before you point it at anything that can spend money, and print them next to the trace so the number that let an action through is visible afterwards.

For the same shape on a robot see RoboJEV; in a browser, fastbrowse and jev-ultrafast.

See how it compares with other tools in Best Jev tools, tested hands-on.

Review updated Sep 21, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.

More in Libraries & Integrations

agentrun

★ 423▲ 13

Parcha-ai/agentrun

A workflow DSL for agents with a Jev package for the steps that are decisions rather than generation.

TypeScript

switch

★ 420▲ 170

osolmaz/switch

TypeScript framework for decision-model harnesses: your program offers a short list of next steps and the model picks one at a time until it can answer, with chess, wikirace and rubric-judge examples run on Jev.

TypeScript

Ten Levels of Jev

★ 264▲ 10

disler/ten-levels-of-jev

Thirty worked uses arranged in ten levels, from one if statement to an agent that reaches for Jev itself, with a video walkthrough.

TypeScriptReviewed

Get new Jev projects every week

New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.

Powered by Buttondown. See our privacy policy.