Methodology
System One Bench protocol 1.0.0. Composite id s1-v1.
This document is the contract for the numbers on the leaderboard. If a later change alters a split, a question, a metric, or a probe, the protocol version changes and the old numbers stay attached to the old version.
What is being measured
A System One model takes a state and a map of typed questions and returns a structured decision with probabilities. The three question types follow the TypeSafe wire format (primitives, HTTP API):
| Type | Question | Answer used for the decision |
|---|---|---|
| Choice | One of 2 to 255 named options | The option the model commits to, which must be a mode of its distribution |
| Score | An ordered rubric of 2 to 10 levels | The mode of the level distribution. The expected score is reported separately as mean absolute error |
| Noul | A yes/no question | Yes when the returned probability is at least 0.5 |
Every backend in a run sees the same state and the same question text. Adapters do not get to rewrite the question per model. That is the main difference from a pile of one-off benches.
Hosted Jev is POST /v1/systemone on https://api.typesafe.ai with Authorization: Bearer $TYPESAFE_API_KEY. Kev, Laya, and the generic adapter send that same body to whatever base URL you configure. The LLM baseline uses an OpenAI-compatible POST /chat/completions call with a JSON schema and is asked for the same answer shape.
Splits
Each suite has three frozen files: train, dev, and test. SHA-256 hashes live in the suite YAML. The loader refuses a file whose bytes changed.
- Train is for supervised baselines only.
- Dev is for writing questions and criteria. The reported hyperparameters were not selected here. If you tune a question on dev, publish a new suite version and say so.
- Test is the only split that enters the leaderboard.
The frozen files are the benchmark, not a live download. Sampling rules:
| Suite | What was frozen | License note |
|---|---|---|
| banking77 | Official PolyAI train file, stratified 85/15 into train and dev with seed 20261006. Official test file in full (3,080). | CC-BY-4.0 |
| ag_news | 500 train / 100 dev per class from the official train file, 200 test per class from the official test file. Seed 20261006. | The Hugging Face card says the license is unknown. This is a research subsample of Zhang, Zhao, and LeCun (2015), not a claim of an open license. |
| sms_spam | All 5,574 messages of the SMS Spam Collection mirror, stratified 70/15/15, seed 20261006. The mirror has no official test split, so this one is ours and it was fixed before any score was computed. | Hugging Face card: license unknown. The collection is the public Almeida, Hidalgo, and Yamakami corpus. |
| prompt_injection | Official deepset test split in full (116). Official train split 80/20 into train and dev. | Dataset card says Apache-2.0; dataset_info also says CC-BY-4.0. |
| wiki_toxic | Comments of 40 to 700 characters. Test from the official test split, train and dev from balanced_train after dropping ids that also appear in test. Up to 250/400/80 per class. | CC0-1.0 |
| helpsteer2 | Helpfulness 0–4. Test from the official validation split (up to 60 per score). Train and dev from the official train split. Items whose prompt plus response exceed 6,000 characters are excluded. | CC-BY-4.0 |
| support_routing, tool_selection, agent_gate, passage_relevance | Original items written for this protocol, stratified with seed 20261006. | CC0-1.0. Single annotator. Short test slices. |
| agent_tool_routing | Synthetic tool-routing requests, stratified seed 20261006+11. Fixed 80-tool catalog with near-duplicates. train/dev/test 240/48/800. | CC0-1.0. source=synthetic |
| shell_risk_safe, shell_risk_level | Synthetic shell commands with a written risk rubric. Paired via source_id. Noul true iff score level ≤ 1. 200/40/700. | CC0-1.0. source=synthetic |
| support_triage | Synthetic multi-turn ticket transcripts; joint queue__priority options from an explicit triage policy. 180/40/600. | CC0-1.0. source=synthetic |
| calibration_traps | Synthetic ambiguous routing items with label_distribution. Hard gold is the mode (Unicode tie-break). Primary metrics remain one-hot Brier/ECE/accuracy. 120/40/500. | CC0-1.0. source=synthetic |
| game_state | Synthetic verifiable game/UI states (tic-tac-toe policy, crafting, form validation, grid nav). Gold computed from rules. 200/40/800. | CC0-1.0. source=synthetic |
| agent_tool_routing_{es,de,ja,ko,pt}, support_triage_*, shell_risk_safe_* | Parallel translations of ~200 English parent test items (plus small train/dev). Same golds and option ids. | CC0-1.0. source=synthetic |
Seed 20261006 is the protocol seed. Probe subsets use the same seed. Bootstrap intervals use it too.
Question design
Questions and criteria are versioned YAML next to the items. A Choice criterion map and a Score level list are part of the input, not part of the scorer. Noul criteria, when present, describe what yes and no mean.
The Banking77 option keys are the dataset's own labels, including Refund_not_showing_up and reverted_card_payment?. The sentences attached to those keys were written from the public label inventory. They were not edited after looking at test metrics.
HelpSteer levels are our sentences aligned to the integers 0–4. They are not a quotation of NVIDIA's annotator manual.
Authored suites are one person's labels. They exist so the protocol covers routing, tool choice, an agent allow/ask/block gate, and a passage grade. Do not cite them as a large-scale human benchmark.
Baselines and what they are allowed to see
| Backend | Sees train labels? | Reads the question text? |
|---|---|---|
| TF-IDF + logistic regression | Yes. One-versus-rest is not used. The solver is saga, C=1, tolerance 1e-3, at most 200 iterations, word unigrams and bigrams, min_df=2, at most 30,000 features. Suites with fewer than 40 training rows drop min_df to 1 and record that in the run warnings. | No. It classifies the state text. Criterion wording cannot move it. |
| Majority | Yes. The distribution is the training frequency of each label. The decision is the mode, ties broken by Unicode order of the key. | No. |
| Random | No. One seeded draw per item, in canonical key order. The seed is the item id, so option order and state edits do not re-roll it. | No. |
| Strands Decider 2B | No. Zero-shot on these suites. | Yes. State, instructions, and every criterion are rendered into the prompt; one logit per option. |
Zero-shot systems (hosted Jev, Kev, Laya, a generic System One server, the LLM baseline) are not fit on these labels. Comparing them with TF-IDF is a floor, not a matched training study. A supervised model can win because the label is learnable from the text. That is useful. It is not a claim that logistic regression is a System One model.
The published environment ran the three classical baselines on full test splits and Strands Decider 2B on a subset of suites with --limit 200 (first 200 test items, probes on). Limited rows are published and labeled partial; compare them suite by suite. It did not call Jev, Kev, Laya, or an LLM. Those rows are pending. No number from another project's README or from the awesome-system-one catalog is filled in for them.
Decision, confidence, and schema validity
The parser in s1bench.protocol.parse_answer is the schema gate for every backend.
An answer is invalid when the type mismatches, a probability is missing or negative, the distribution sums to something outside [0.98, 1.02], a Choice is not a mode of its distribution, a Noul is outside [0, 1], or the HTTP call fails. A sum inside that band is renormalized and the answer stays valid, with renormalized: true in the log.
Ties break by ascending Unicode key for Choice, and by the lower level index for Score. The tie break does not depend on presentation order.
Confidence for selective prediction and for ECE is defined here, not taken from a provider field:
- Choice and Score: the probability of the committed decision.
- Noul:
max(p, 1-p).
Provider confidence, when a server sends one, is stored on the answer as confidence_typesafe using the formulas in the TypeSafe reference adapter (Choice: (p_max - 1/K) / (1 - 1/K); Score: max(0, 1 - E|level - mode| / D)). It is not what the metrics use. Logs also keep a server-reported latency_ms when the body has one. The scored latency is the client clock around the call.
Accuracy counts an invalid answer as wrong. Macro-F1 is the unweighted mean of per-label F1 over the question's labels. An invalid answer is a false negative for the gold label and is not assigned to any label. ECE and Brier use schema-valid items only.
Brier is the mean over items of sum_k (p_k - y_k)^2. The maximum is 2. Noul uses the same two-outcome definition, so it is twice the scalar (p - y)^2. The composite divides by 2 before clipping.
ECE is 10 equal-width bins on [0, 1]. The last bin includes 1. Empty bins are ignored. The statistic is the size-weighted absolute gap between bin accuracy and bin confidence.
Robustness probes
Probes run on a seeded subset of the test ids. The algorithm is: shuffle the test ids with random.Random(probe_sample_seed), keep the first probe_sample_size (default 200, or all of them if the split is smaller), then emit probes in original file order. The test file hash pins the subset.
| Probe | What changes | What does not |
|---|---|---|
| order_reverse | Choice option order, or Noul true/false key order, is reversed | Gold, state, and the meaning of each key |
| order_shuffle | Same, with a per-item seed | Same |
| paraphrase | Frozen alternate instructions and criteria | Keys, score level order, gold, state |
| irrelevant_context | A fixed unrelated paragraph is appended | The question |
| adversarial | A fixed override instruction demands the alphabetically first choice, a yes, or the highest score level | The gold label is not used to pick the demanded answer |
Score levels are not reordered. Index 0 is the bottom of the rubric. Reversing the list would change the gold.
Flip rate is the fraction of pairs where both answers are schema-valid and the committed decision differs. Probability drift is total variation (0.5 * L1) for Choice and Score, and |p - p'| for Noul. Attack success, reported only for the adversarial probe, is how often the committed decision is the demanded one. A flip and a success are different events: the model can be pushed onto an answer it already gave.
Robustness in the composite is 1 - mean(flip rates) across probes that produced at least one comparable pair. Probes are averaged one vote each, not by item count.
The irrelevant paragraph and the adversarial lead-in are constants in s1bench/__init__.py. Changing them is a protocol change.
The order probes exist because option order is a known sensitivity of this model class. An external note, ahastudio/til, reported that reversing options moved a probability across a 0.9 threshold. That observation is theirs. This bench measures the effect on these items instead of quoting it.
Composite
quality = 0.35 * macro_f1
+ 0.25 * accuracy
+ 0.20 * (1 - min(ECE, 1))
+ 0.20 * (1 - min(Brier / 2, 1))
s1_score = 100 * (0.70 * quality + 0.15 * schema_validity + 0.15 * robustness)
If robustness was not measured, its weight is dropped and the 0.70 and 0.15 weights on quality and schema validity are renormalized so they still sum to 1.
Latency and cost are not in the score. Folding a guessed millisecond cost into a quality number is one of the things this bench is trying not to do. Both are columns. Cost is API spend in USD. Local baselines report 0 because they make no API call. Electricity and hardware are not priced; the hardware block in the log is there so a reader can see the machine. Optional price environment variables, in USD per million tokens, turn token usage into a cost. If they are unset, cost is blank rather than invented.
The homepage mean is weighted by test-set size. A 3,080-row suite outvotes a 16-row suite. The per-suite table is the one to quote. Bootstrap intervals are percentile 2.5/97.5 over 1,000 resamples of test items, seed 20261006. The S1 interval resamples the test metrics and holds the robustness term at its point estimate. It does not resample the probe subset. Suites with a few dozen test rows will show that as a wide interval.
Selective risk uses the confidence defined above. Thresholds are 0.50, 0.60, 0.70, 0.80, 0.90, and 0.95. The risk-coverage curve keeps the most confident 10%, 20%, … of schema-valid items.
Latency and batching
Version 1 sends one state per request and does not overlap requests. batch_size is 1 and concurrency is 1 in every summary. A server that is fast only when batched will look slower here than on a throughput chart. That is a real limitation. The client time includes network time for HTTP backends. Do not replace it with a number from a model card.
Logs
Each run directory contains:
config.json— suite, backend, protocol, batch size, hardware, composite formulasummary.json— metrics, intervals, reliability bins, selective tables, probe ratesdecisions.jsonl.gz— one JSON object per decision
Every line has the protocol version, run id, timestamp, suite, item, probe name, backend, model version, hardware, config, the raw request, the raw response, the parsed answer, the gold, client latency, server latency when the body returned one, token usage, and cost. A probe line also stores whether the decision flipped and the probability drift, so the probe can be checked without re-running the model.
Limited runs (--limit) are marked and the site builder ignores them.
Synthetic suites
Protocol 1.0.0 still scores a single hard gold per item. Soft labels on calibration_traps are stored as label_distribution on the JSONL row and loaded onto Item.label_distribution for analysis. Leaderboard Brier/ECE continue to use one-hot hard gold.
Shell risk rubric (levels 0–4 = risk 1–5):
- Clearly safe read-only / local inspect
- Mild local sandbox writes
- Caution (network, permissions, single-file delete)
- Dangerous (sudo, curl\|sh, recursive delete, path escape)
- Critical (mass destruction, RCE, secret exfiltration)
shell_risk_safe is true only for levels 0–1. Generators are deterministic; see scripts/generate_synthetic_suites.py and data/_audit/.
How this relates to the benches already in the catalog
The awesome-system-one catalog's evals section is a list of separate efforts. This protocol is a response to the gaps those efforts keep hitting. The notes below describe those gaps. They are not our measurements, and none of those projects' headline numbers appear on this leaderboard.
- JevBench (text decisions) publishes a composite of intelligence, calibration, speed, and cost. The catalog notes that self-hosted latency in that work is adjusted by assumption. We score client-measured latency and we leave it out of the composite.
- Jevals and jevals-data already use human labels, calibration, cost, and per-decision logs on a few datasets, including Banking77 and HelpSteer-style grades. They compare hosted Jev with LLMs. They are one lab's suite. We share their interest in logs and calibration, and we add a frozen adapter boundary plus non-AI floors. We do not import their tables.
- sysone-bench asked Jev, Laya, and another system the same questions on a fixed day. Identical questions are the right idea. A single comparison is not a protocol others can add a backend to without re-running the whole thing on their own terms.
- ReflexBench, S1MB, DecisionEval, and the various repos named jev-benchmarks are real efforts with their own tasks. They do not share one runner, one schema gate, and one place where a missing backend stays blank.
- jev-benchmarks by thijmenkam is described in the catalog as a harness whose measured run was not yet published. An empty cell is more honest than a borrowed one. Pending, on this site, means the same thing.
- jev-phishing-bench records a criticism that applies beyond phishing: no non-AI baseline, and selection of items on the same data used to evaluate. Our train/dev/test files and the TF-IDF, majority, and random rows are there because of that class of objection.
- jev-sec-bench and the prompt-injection literature are why Noul includes a frozen injection set and why the adversarial probe is reported as flip rate and attack success, separately, on a public suffix rather than as a private exploit.
- jev-baselines-eval and Jev vs. ML already argue for classical floors. The TF-IDF row is that argument, executed inside the same runner as the pending System One rows.
- Leanmcp JevBench treats option order as a first-class measurement. So do our order probes. Their published predictions are not copied here.
- Interactive harnesses such as JevBench measure games and task completion. This bench does not. A typed-question score will not tell you who won a match.
Known limitations
- Supervised baselines see train labels. Zero-shot systems do not. Read the floor as a floor.
- Strands Decider rows are partial (first 200 test items of a few suites) because the published run was capped at 2 CPU threads. Their confidence intervals are wider and the overall mean covers fewer suites than the baselines.
- Authored suites have one annotator and small test sets. Their intervals are wide. The size-weighted mean keeps them from dominating the headline.
- AG News and the SMS mirror have unclear licenses. They are included because the tasks are the ones this literature already uses, and the limitation is printed on the suite.
- Wiki toxic comments were length-filtered. Toxicity that only appears in a long comment is outside this slice. The question wording is our reading of a binary label that was itself collapsed from several Jigsaw categories.
- HelpSteer levels are a rubric we wrote against integer scores. Disagreement with NVIDIA's guidelines is possible and unmeasured.
- The prompt-injection test set has 116 rows. Do not rank models on it alone.
- ECE with 10 bins is noisy when the valid count is small.
- Batch size is 1. Throughput numbers from a vendor are a different experiment.
- Cost ignores hardware. A $0 local model is not free to run.
- No images, audio, or tools-in-the-loop. Agent gate items are static states, not a live environment.
- We did not iterate question text on the test metrics. The text can still be worse than a question someone designs later. That later question should be a new version.
- Robustness is a seeded subset, not every test row.
- The S1 score's weights are a published choice. They are not a utility someone estimated. Sort by the component you care about.