~/satyajit

Ultramarine 1 Flash: RL on a board memo, graded by 31 sentences

mdjsonmcp

2026-10-14 · 18 min · reinforcement-learning · post-training · agents · rl-environments · glm · benchmarks · synthetic-data · lora

Why read this

Notabletop 60%

Scores the blog's real 31-criterion rubric in a widget, reads the open rubric and Feather code it trains with, and maps the Fable 5 claim row by row.

  • Original analysis
  • A new technique
  • Concrete numbers to act on

Training & RLAPI onlyPractitioner model

How this was scored
Is it new?
2 of 3: A real new idea, method or capability
Can I trust it?
2 of 3: Measures key facts from files, code or configs
Can I run it?
1 of 3: API-only, gated or restrictive licence
Will I understand it?
2 of 3: Mechanism from first principles with figures
Can I act on it?
2 of 3: A concrete recipe, numbers or comparison
Will it last?
1 of 3: Relevant for months
Does it affect many?
1 of 3: A specialist community
Only here?
2 of 3: A teardown or measurement few others did

Score 60 of 100, ranked 325 of 577 rated articles. Each question is answered 0–3 by hand, and a 3 is rare. How articles are scored

Paper Instruments released Ultramarine 1 Flash today. It is GLM-5.3-Flash after a long run of reinforcement learning on knowledge work: diligence memos, board pre-reads, credit-agreement reviews, warehouse tickets. The launch post on X makes four claims. It says the model performs similarly to Claude Fable 5. It says it is 60x cheaper. It says it was "post-trained by a team of 5 for ~$300k all-in". And it calls the model open-source, with weights "releasing in 2 weeks".

The interesting part is the training signal. Coding RL has unit tests. A board memo has none. Ultramarine's reward is an LLM judge reading a weighted list of propositions, and most of the blog's engineering goes into keeping that signal honest. So I start there, with the blog's worked example and the open-source grader it uses. The claims come after.

Labels: measured means I computed it from a file, the released code or the blog's own data. Reported is Paper Instruments' number, not re-run. Reasoned is my arithmetic on the other two.

Basezai-org/GLM-5.3-Flash, 320B total and 18B active, MIT (site teardown); the same base became Tev-320B this week, with verifiable per-step rewards instead of a judge
MethodAgentic RL, rubric rewards from an LLM judge, CISPO loss, LoRA rank 64 (reported)
Curriculum4 domains, 19 practice areas, 88 environment types, all synthetic (reported; 88 measured from Table 1)
HarnessFeather: read, edit, write, grep, glob, bash, todo_write (reported, and in the released code)
Context, turns131,072 tokens, up to 250 agent turns (reported)
Out todayAPI, the Feather harness and a reference training recipe (MIT), the rubric grader (MIT)
Not outWeights, the task data, the snapshot builder, training length and compute

Why a memo is hard to reward

Policy-gradient RL needs one number per rollout. The model makes several attempts at a task, each gets a reward, and the update pushes up the attempts that beat their siblings. That number has to rank attempts the way an expert would.

For code the number is cheap and almost incorruptible: run the tests. For a board pre-read the only available grader is another model. That opens three failure modes.

The blog's first figure draws the last two as boundaries over six candidate answers.

Six candidate answers to a board-forecast task. Answers A, B and C are complete: each says the board can approve the v7 forecast now and that counsel must still clear external wording. Answers D, E and F each give only one piece. An overfit criterion, which demands the phrase sole forecast basis and a fixed ordering, rejects valid answers B and C. A vague criterion, provides a useful forecast update, also accepts the incomplete D, E and F. Criterion 13 of the example task, which states the substantive separation between what the board can approve now and what needs counsel clearance, accepts exactly A, B and C.
An overfit criterion rejects valid answers; a vague one accepts incomplete ones. The criterion they train with is written to match the boundary (Paper Instruments, Ultramarine blog, criterion-boundary figure).

Their rule is that a criterion tests "one coherent proposition", and names the entities, dates and thresholds needed to check it. Independent accomplishments get separate criteria so that partial work earns partial credit. A judge then marks each one met or unmet. That is the Rubrics as Rewards idea, pushed into long agentic tasks.

How 31 sentences become one reward

The blog publishes a complete training task. An agent gets a deal-room filesystem of 31 files (measured, from the listed tree), email and calendar MCP servers, and an instruction to update the forecast section of a board pre-read .docx in place. The grader is 31 weighted criteria in six groups. I summed them: positive weights total +247, negative weights total −210 (measured). Eight of the 31 are negative: things a careless memo does, such as quoting the stale 11.7x multiple or telling management it may use the new numbers on the roadshow before counsel clears them. That one costs 50.

The grader is PerCriterionOneShotGrader from Paper Instruments' open rubric package, with a custom prompt they do not publish. I read the package. It asks the judge for a MET or UNMET verdict on every criterion in one call, then aggregates:

raw=∑i1[METi] wi,r=clip⁡ ⁣(raw∑imax⁡(0,wi), 0, 1)\text{raw} = \sum_{i} \mathbb{1}[\text{MET}_i]\, w_i, \qquad r = \operatorname{clip}\!\left(\frac{\text{raw}}{\sum_i \max(0, w_i)},\, 0,\, 1\right)

A negative criterion is phrased as the error, so MET means "the error is present" and its negative weight subtracts. The default prompt spends most of its length on that inversion, with examples such as "Avoid doing X because…" counting as not committing X.

Load the presets and three properties fall out.

  1. Correct numbers are not enough. The "right numbers, one track" memo gets every figure right and still scores 164 of 247, a reward of 0.664 (measured from the weights). It merges the board's approval with counsel's clearance, which costs 25, and so misses the 18-point criterion that rewards separating them. The reward is shaped around the judgement, not the arithmetic.
  2. The floor erases information. The stale-basis memo has a raw score of −71, which clips to zero (measured). So does an empty file. Below the floor, the optimiser cannot tell a bad answer from a worse one. That is a defensible choice, because clipping stops one catastrophic criterion from dominating a group's variance. It is still information thrown away.
  3. Criteria overlap. Criterion 14 ("v7 is the sole basis for Board, fairness, and transaction-valuation work", +10) and criterion 24 ("Uses Management Forecast v7 … as the forecast basis", +18) reward close to the same proposition. Criteria 11 and 16 both penalise presenting the stale v5 case. Getting the basis right is worth 28 points and getting it wrong costs 50 (reasoned, from the published rubric). The blog's own principle says independent accomplishments get separate criteria. These two pairs are not independent, so the rubric weights the forecast basis more heavily than the group totals suggest.

One quirk in the package matters for training. If the judge's JSON leaves a criterion out, the aggregator records it as UNMET (measured, per_criterion_one_shot_grader.py). For a positive criterion, that is a lost point. For a negative one, it is a penalty that silently never applies. A judge that drops items under a long context lets errors through. I cannot tell whether Paper Instruments' custom prompt or their retry logic guards against this. The released code does not show it.

The judge sees the deliverable "parsed and rendered as text". The post names neither the judge used in training nor its agreement with human experts; it points to a separate post, "Notes on Choosing a Rubric Judge", for the method.

Where 88 kinds of tasks come from

The blog rejects production traces, because a reward written from one user's request bakes in that user's unstated preferences ("top 10 medtech companies" by revenue, or by market cap?), and expert-written tasks, as expensive and narrow. It chose fully synthetic generation.

The curriculum spans finance (34 environment types), legal (15), consulting (28) and operations (11). That is 88, and the table lists exactly 88 named environments (measured from Table 1). Each practice area is a generation pipeline that samples a taxonomy: deliverable format, sources of complexity, stakeholders, conflicting sources, the stage of the deal. The blog puts each area's configuration space at 10⁷ to 10¹⁰ combinations (reported). An environment is a filesystem of real SEC filings and synthetic contracts and emails, plus live systems the agent changes (CRM, ERP, warehouse management), and a private ground-truth record only the task-proposer agents see.

The reward-hacking defence is mostly in how the tasks are made. Producing one task "involves several dozen independent agent loops and multiple rounds of review" (reported). Those rounds check grounding, realism, difficulty and whether the rubric matches the assignment. Classifiers screen for answer leakage and reward hacking, "iteratively added or refined in response to failures observed during training". A last filter drops tasks by base-model performance. Tasks the base model always solves or never solves give every rollout in a group the same reward, so their advantage is zero and they teach nothing.

The blog does not say how many tasks were generated, how many survived the filters, or what any of the hacking classifiers caught. Those are the numbers that would say whether the defence worked.

The harness is part of the reward

Ultramarine trains inside its own harness, Feather. Paper Instruments surveyed twelve coding harnesses (Claude Code, Codex, OpenCode, OpenHands, Qwen Code and others) and built one on their shared conventions instead of training on several. Three choices bear directly on reward integrity.

Feather's edit tools also fingerprint each file on read and refuse an edit if it changed since, and Office files are edited through Paper Instruments' MIT forks paper-docx, paper-pptx and paper-xlsx, which refuse operations they cannot do safely. A silently corrupted workbook would otherwise reach the judge as a quality failure.

The optimiser

The loss is a modified CISPO, from MiniMax-M1. For rollouts ii in a group gg on one task:

L(θ)=−1N∑i,tmi,t sg⁡ ⁣[min⁡ ⁣(ρi,t,5)]Ailog⁡πθ(ai,t∣hi,t),Ai=r~i−1∣g∣∑j∈gr~j\mathcal{L}(\theta) = -\frac{1}{N}\sum_{i,t} m_{i,t}\,\operatorname{sg}\!\left[\min\!\left(\rho_{i,t}, 5\right)\right] A_i \log\pi_\theta(a_{i,t}\mid h_{i,t}), \qquad A_i = \tilde r_i - \frac{1}{|g|}\sum_{j\in g}\tilde r_j

Here ρi,t\rho_{i,t} is the probability ratio between the current policy and the policy that sampled the rollout. mi,tm_{i,t} masks to model-generated tokens and NN counts them. sg⁡\operatorname{sg} is stop-gradient. Unlike PPO's clip, CISPO caps the importance weight and stops its gradient, so a token whose ratio runs high still receives a gradient. It just gets less weight. The released recipe defaults to the same cap: clip_high_threshold: 5.0 (measured).

The other pieces, all reported:

What the table does not give is the length of training: no step count, no GPU type, no GPU-hours. "Through prolonged training" in the thread is all there is. So the "~$300k all-in" from the tweet, which is not in the blog, cannot be checked against anything (reasoned).

Checking "similar performance to Fable 5"

The blog's Table 8 has six knowledge-work rows and two coding rows "for reference". Every model ran at its highest reasoning setting.

Six horizontal bar charts. JobBench: Ultramarine 1 Flash 62.9, Gemini 3.8 Flash 60.6, DeepSeek V4.1 Flash 60.4, Claude Fable 5 57.4, GLM-5.3 Flash 56.3, Kimi K3 54.3, GPT-5.6 Sol 45.4. PI Knowledge Work (internal): Ultramarine 59.3, Fable 5 57.8, GPT-5.6 Sol 55.1, GLM-5.3 Flash 52.0, Kimi K3 51.2, Gemini 3.8 Flash 49.4, DeepSeek V4.1 Flash 47.9. FrontierFinance: Ultramarine 53.3, GLM-5.3 Flash 50.7, Gemini 50.0, Fable 5 49.2. AutomationBench: DeepSeek V4.1 Flash 51.3, Ultramarine 50.2, GLM-5.3 Flash 48.8, Fable 5 46.2. DiligenceBench: Gemini 53.1, Fable 5 52.9, Ultramarine 50.6, GLM-5.3 Flash 48.2. APEX-Agents 1.1: Gemini 64.3, Fable 5 63.6, Ultramarine 57.0, GLM-5.3 Flash 52.8.
The six knowledge-work benchmarks. Ultramarine leads four, but two of the six, PI Knowledge Work and DiligenceBench, are Paper Instruments' own (Paper Instruments, Ultramarine blog, Table 8 charts).

Against Claude Fable 5, Ultramarine is ahead on four rows: JobBench (+5.5), PI Knowledge Work (+1.5), FrontierFinance (+4.1) and AutomationBench (+4.0). It is behind on four: DiligenceBench (−2.3), APEX-Agents 1.1 (−6.6), Terminal-Bench 2.1 (−1.1) and DeepSWE (−8.4). All measured from Table 8. Across the six knowledge-work rows the mean gap is +1.0 (reasoned). "Similar" is a fair word for that. "Fable-class", as the product page puts it, depends on which rows you read.

Three caveats sit in the table's footnotes.

Against its own base, the story is cleaner. Ultramarine improves on GLM-5.3-Flash on all six knowledge-work rows, by 4.1 points on average (reported; my recomputation from Table 8 gives 4.08). PI Knowledge Work gains the most (+7.3), AutomationBench the least (+1.4). Both coding rows fall slightly: Terminal-Bench 2.1 from 84.3 to 83.2, DeepSWE from 63.4 to 61.5 (measured from Table 8). The base-model figures for Terminal-Bench, DeepSWE and AutomationBench (84.3, 63.4, 48.8) match the numbers in the GLM-5.3-Flash card as this site's teardown recorded them (measured). Targeted RL moved the domains it targeted and cost a little elsewhere. That is the honest result, and the blog's table shows it rather than hiding it.

The blog also reports 6.5% fewer output tokens than the base across the six benchmarks: 30.5M against 32.7M. Those two rounded totals give 6.7% (reasoned), which is consistent within rounding.

Checking "60x cheaper"

The cost claim comes from one chart. It plots PI Knowledge Work score against cost per task at each developer's official API price as of October 2026.

Scatter plot of PI Knowledge Work score against cost per task on a log axis from one cent to ten dollars. Ultramarine 1 Flash at max reasoning is highlighted at 59.3 and 13 cents. A frontier line runs from GPT-6 Luna low at under a cent through GPT-6 Luna max, Ultramarine, GPT-6 Astra low and medium, GPT-6 Sol max, Claude Opus 5.5 high, GPT-6 Astra max and up to Claude Fable 5.1 max at 65.5 near ten dollars. Claude Fable 5 max sits at 57.8 near eight dollars, inside the shaded region of runs that cost more and score less than Ultramarine.
PI Knowledge Work, score against cost per task. The shaded region is every run that costs more and scores less than Ultramarine; this is Paper Instruments' internal suite (Paper Instruments, Ultramarine blog, cost-quality chart).

$8.19 for Fable 5 at max reasoning divided by $0.13 for Ultramarine is 63x (reasoned). The "60x" is that, rounded down. Four things qualify it.

The Pareto claim does hold on the published points. Of the 39 other runs, 27 cost more and score lower (reported, and measured from the chart labels). No run is both cheaper and better (measured). Ultramarine is on the frontier of this chart. The chart is Paper Instruments' benchmark, judged by a model they chose. The blog's one external anchor is a correlation of r = 0.81 between PI Knowledge Work and the Artificial Analysis Intelligence Index, over the 24 runs both measured (reported). That supports the suite as a general-capability ranking. It says nothing about whether a model trained on the suite's own domains is advantaged on it.

What "open-source" means today

I checked Hugging Face (api/models?search=ultramarine, and the obvious author names) and found no weights (measured, 2026-10-14). The thread says weights will be linked "within 2 weeks". What is public:

paper-instruments/feather@d864944 · snapshot 2026-10-14
tracked files
2,822
license
MIT
branch
main
tests
130 files
source
1.3 MB
commit date
2026-10-13
source by language
Python1.3 MB(224)Shell7.6 kB(7)Dockerfile1.8 kB(4)

by size of tracked source at this commit, file counts in brackets; docs, data and vendored trees excluded

local clone, 2026-10-14 at d864944 — branch, commit, commitDate, fileCount, hasTests, languages, license, licenseFile, shallow, testFileCount

shallow clone: counts describe the pinned tree, not the history

Not public: the weights, the 88 environment pipelines, the tasks and rubrics beyond the one worked example, the custom judge prompt, and the training logs. Without the tasks, the recipe cannot be reproduced, only re-implemented. "Team of 5" and "~$300k" appear only in the tweet. They are reported, unverifiable, and absent from the technical post.

What I take from it

The model is a careful but unremarkable result: a strong open MoE, RL-tuned toward one domain, gains about four points there and gives up one or two on code. The recipe is the contribution. It treats non-verifiable RL as data engineering: the reward is only as good as the boundary each criterion draws, so the effort goes into adversarial criteria, task filtering and walling the grader off from the policy, not into a stronger judge.

What the post does not yet show is evidence that the defences held: reward-versus-human-agreement curves over training, the hacking classifiers' catch rate, any held-out grader. The tweet's claims to check are mostly about the bill and the comparison. The ones I would want the tech report to answer are about the reward.

Other GLM-5.3-Flash derivatives this site has measured: the MLX port and the abliterated FP8 variant. For the verifiable side of the problem, see Scaling agentic RL and MiMo's graded environments; for the road not taken here, multi-harness RL.

Cite this article

For attribution, please use the following reference or BibTeX:

Satyajit Ghana, "Ultramarine 1 Flash: RL on a board memo, graded by 31 sentences", ai.thesatyajit.com, October 2026.

bibtex
@misc{ghana2026ultramarine1flash,
  author = {Satyajit Ghana},
  title  = {Ultramarine 1 Flash: RL on a board memo, graded by 31 sentences},
  url    = {https://ai.thesatyajit.com/articles/ultramarine-1-flash},
  year   = {2026}
}
share