> ## Documentation Index
> Fetch the complete documentation index at: https://docs.while.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Install with `uv add whileai`; import as `import whileai as wai`.
> Run the offline path first (`simulator=False`, `wai.seeded_agent`, a callable judge); no key is needed for it.
> Report every pass rate with its interval and n, as `scored.pass_at` prints it.

# Papers

> One directory per paper.

<Note>The scripts are in the repository, not in the installed package. Clone it,
then `cd recipes/papers` before running the commands below. [Browse this recipe on GitHub](https://github.com/whilehq/whileai-sdk/tree/main/recipes/papers).</Note>

One directory per paper. A recipe here is a recent post-training paper's idea
cut down to a run that fits in under an hour on one GPU, with the number it
moved and the number it did not. The building blocks are the step recipes next
door (`../04-train/grpo`, `../04-train/dpo`, `../04-train/text-to-sql`,
`../04-train/hosted-loop`); a paper recipe copies one of them and changes one
thing.

Every recipe answers the same five questions in the same order: which paper,
what it claims, the steps, one command, what happened.

| Recipe                                                         | Paper                                                                                    | Base                             | Metric  | Baseline -> Recipe                                               | Verified   |
| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------- | ------- | ---------------------------------------------------------------- | ---------- |
| [adaptive-clip](/recipes/papers/adaptive-clip)                 | [2609.00444](https://arxiv.org/abs/2609.00444)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.47 -> 0.52 (+0.05 \[+0.00, +0.10], unresolved, 1 seed per arm) | 2026-09-18 |
| [bpco-bounded-critic](/recipes/papers/bpco-bounded-critic)     | [2608.23566](https://arxiv.org/abs/2608.23566)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.43 -> 0.41 (-0.02 \[-0.07, +0.04], unresolved, 1 seed per arm) | 2026-09-22 |
| [endpoint-sft](/recipes/papers/endpoint-sft)                   | [2609.07103](https://arxiv.org/abs/2609.07103)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.29 -> 0.28 (-0.01 \[-0.07, +0.05], unresolved, 1 seed per arm) | 2026-09-17 |
| [filter-metric](/recipes/papers/filter-metric)                 | [2609.13866](https://arxiv.org/abs/2609.13866)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.39 -> 0.46 (+0.07 \[+0.02, +0.11], unresolved, 1 seed per arm) | 2026-09-17 |
| [flash-reinforce](/recipes/papers/flash-reinforce)             | [FlashREINFORCE.pdf](https://yifanzhang-pro.github.io/FlashREINFORCE/FlashREINFORCE.pdf) | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.47 -> 0.41 (-0.07 \[-0.11, -0.03], unresolved, 1 seed per arm) | 2026-09-22 |
| [gmts-token-select](/recipes/papers/gmts-token-select)         | [2608.30632](https://arxiv.org/abs/2608.30632)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.49 -> 0.18 (-0.31 \[-0.38, -0.24], unresolved, 1 seed per arm) | 2026-09-18 |
| [harness-and-weights](/recipes/papers/harness-and-weights)     | [2607.03935](https://arxiv.org/abs/2607.03935)                                           | Qwen/Qwen2.5-Coder-1.5B-Instruct | pass\@1 | 0.03 -> 0.09 (+0.06 \[+0.03, +0.09], unresolved, 1 seed per arm) | 2026-09-21 |
| [sao-single-rollout](/recipes/papers/sao-single-rollout)       | [2607.07508](https://arxiv.org/abs/2607.07508)                                           | Qwen/Qwen2.5-1.5B-Instruct       | pass\@1 | 0.46 -> 0.46 (-0.00 \[-0.04, +0.03], unresolved, 1 seed per arm) | 2026-09-22 |
| [zero-rl-format-reward](/recipes/papers/zero-rl-format-reward) | [2503.18892](https://arxiv.org/abs/2503.18892)                                           | Qwen/Qwen3.5-4B-Base             | pass\@1 | 0.63 -> 0.72 (+0.09 \[+0.05, +0.14], unresolved, 1 seed per arm) | 2026-09-18 |

The table is generated: `python recipes/papers/check.py --write` reads every
`results.json`. Do not edit it by hand.

One paper here is a loop, not a trained arm:
[`meta-harness`](/recipes/papers/meta-harness) (Lee et al. 2026, arXiv:2603.28052) searches
over harness code, scores every candidate on one frozen task set, and gates
the pick on held-out tasks and held-out models. It is in the step-recipe
shape (`run.py --dry-run`, `smoke.sh`, a flags table), runs offline with
scripted candidates, and `check.py` leaves it out of the table above
because it has no `results.json`: the live run is the replication and no
number from it is claimed until one is measured.
[`harness-and-weights`](/recipes/papers/harness-and-weights) (Luo et al. 2026,
arXiv:2607.03935; Hebbar et al. 2026, arXiv:2605.27276; Karten et al. 2026,
arXiv:2608.23552) puts that loop and a GRPO arm under one optimizer: four
arms (`neither`, `harness`, `weights`, `both`) on one holdout of seeded quant
coding tasks. It is in the same step-recipe shape (`recipe.py --dry-run`,
`smoke.sh`, a flags table) and writes a `results.json` only when the full
live run has been measured; its README says what ran.

## Run one

```bash theme={"theme":"vitesse-dark"}
# datasets: every recipe builds its train/holdout split locally, before Modal.
# the modal extra: needed when outbound traffic goes through an HTTPS proxy,
# harmless when it does not.
uv add whileai datasets 'modal[api-proxy-support]'
export WHILEAI_API_KEY=...        # run page + datasets at while.ai/platform
modal token set --token-id ... --token-secret ...   # or MODAL_TOKEN_ID / _SECRET in the environment
cd recipes/papers/<slug>
python recipe.py --selftest         # free: the pure functions the change lives in; needs modal installed, not a token
python recipe.py                    # both arms, writes results.json
```

No `smoke.sh` in this directory: `recipe.py` is one file and imports `modal`
at the top, which CI does not install, so `--selftest` is the offline check
and you run it yourself.

## The contract

* `README.md` in the shape of [`_template/README.md`](https://github.com/whilehq/whileai-sdk/blob/main/recipes/papers/_template/README.md): Paper, Claim, The change, numbered steps, one command, the Result table, the Climb table, three Learned bullets, the Verified line, the References list.
* `recipe.py`: one file. Data, then train, then eval, then `results.json`. Two arms on the same holdout: the baseline and the paper's change. Paired delta with a 95% interval (`wai.compare`).
* `results.json`: the numbers the table above reads. Shape in [`_template/results.json`](https://github.com/whilehq/whileai-sdk/blob/main/recipes/papers/_template/results.json).
* Default run: under 60 GPU minutes, under \$10. Bigger runs behind a flag.
* Public data or a seeded environment that lives in the recipe directory. No customer data.
* A flat result is a result. Say so in the table.
* One training seed per arm is never "moved": the verdict is "unresolved" until both arms have `MIN_TRAIN_SEEDS` (2) independent seeds, and the README's result line says in one sentence what would resolve it. `results.json` records the seeds per arm in `checks.train_seeds`.
* `python recipes/papers/check.py --write` passes (`tests/recipes/test_papers.py` runs it in CI).
* `post.md`: the result as a post, once the recipe is verified. Under 280
  characters, plain words, the metric with its interval, the arXiv link
  and the recipe link, nothing invented and nothing rounded. A flat result
  is posted as flat. Replicated papers are how we market
  ([CONSTITUTION.md](https://github.com/whilehq/whileai-sdk/blob/main/CONSTITUTION.md), belief 2); the post is the
  last artifact of a recipe, not a separate job.

## The science bar

Every recipe is held to the same science bar. The README names the source
each check rests on, and the `## Checks` table is run, not ticked:

| Check               | Source                        | What `check.py` enforces                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Eval noise          | \[1]                          | the base is evaluated `run_std_runs` times (3 by default, more with `--base-runs`); `eval_variance` run\_std and `run_std_runs` are both recorded; "moved" needs a delta over `wai.noise_band(run_std, df=run_std_runs - 1)` = t x run\_std x sqrt(1/n\_a + 1/n\_b), which is t x sqrt(2) x run\_std with one run per side (a delta is the difference of two re-run draws). t is the two-sided 95% quantile at df = run\_std\_runs - 1 because run\_std is an estimate, not the eval's exact spread: 4.30 from 3 re-runs, 2.26 from 10; the old 1.96 read a three-run estimate as exact and let about one pure-noise delta in five through. `wai.compare(run_std=, run_std_runs=)` applies the same quantile. Both resolve from `import whileai as wai`; `compare` is `delta_report` in `whileai.simulations`, one call under two names |
| Paired interval     | \[2]                          | "moved" needs a 95% interval that excludes zero, from `wai.compare` over the same holdout tasks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Training seeds      | \[1], \[2]                    | the claim is a delta between two separately trained models, and the two checks above measure only the eval: "moved" and "flat" need `MIN_TRAIN_SEEDS` (2) independent training seeds on both trained arms, recorded as `checks.train_seeds`; at one seed per arm the only verdict is "unresolved" (one training seed per arm; add a seed to resolve). With two or more seeds, `wai.compare(train_runs={"before": [...], "after": [...]})` widens the interval by the between-seed spread (each arm's std² / n, t at the seed df) and "moved" needs that interval to exclude zero too. One recipe flipped sign between two runs at one seed (-0.065 \[-0.117, -0.013] then +0.050) while every eval check stayed green                                                                                                                   |
| Clean holdout       | \[3]                          | `decontaminate(train, against=holdout)` runs before training; dropped rows are counted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Reward is a program | \[3]                          | a verifier or a public gold answer; a judge only when the paper is about judges                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Proxy vs target     | \[4]                          | the training reward is named as `proxy=`; an over-optimized verdict forbids "moved"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Length              | \[4]                          | mean completion length before and after, per arm, in the table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Hack scan           | \[4]                          | `hack_scan` on the last training batch; the top feature is named                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Pinned              | [the contract](#the-contract) | seed and library versions in results.json                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

## Maintenance

A daily agent re-runs the recipe with the oldest verified date, refreshes its
numbers, fixes what broke, and adds one new recipe from recent post-training
research. The default pick is a paper from the last 60 days; an older paper is
allowed when the PR says what it is the baseline for (SimpleRL-Zoo, March 2025,
is the zero-RL baseline). The table's Paper column dates every one. Everything
arrives as a pull request. One comment per run on
the issue titled "Recipe log". Several agents can work at once: each recipe is
its own directory and the table is generated, so two new recipes never touch
the same line.

## References

1. Lambert, N. Reinforcement Learning from Human Feedback. arXiv:2504.12501, 2025. Chapter *Evaluation*.
2. Miller, E. Adding Error Bars to Evals. arXiv:2411.00640, 2024.
3. Lambert, N. et al. Tülu 3: Pushing Frontiers in Open Language Model Post-Training. arXiv:2411.15124, 2024.
4. Gao, L., Schulman, J., Hilton, J. Scaling Laws for Reward Model Overoptimization. ICML 2023. arXiv:2210.10760.

<CardGroup cols={2}>
  <Card title="adaptive-clip" href="/recipes/papers/adaptive-clip">
    Paper: Group Adaptive Clipping Policy Optimization, Sheng Jia et al., arXiv:2609.00444, August 2026.
  </Card>

  <Card title="bpco-bounded-critic" href="/recipes/papers/bpco-bounded-critic">
    Paper: Best Practice Critic Optimization, Penghui Qi, Xiangxin Zhou, Wee Sun Lee (NUS / Tencent Hunyuan), arXiv:2608.23566, August 2026.
  </Card>

  <Card title="endpoint-sft" href="/recipes/papers/endpoint-sft">
    Paper: Revisiting Complete Reasoning Traces for Post-Training, Jaehui Hwang et al., arXiv:2609.07103, September 2026.
  </Card>

  <Card title="filter-metric" href="/recipes/papers/filter-metric">
    Paper: The Filter Metric is Safety-Critical: Phantom Advantages in Group-Relative RL under Shaped Rewards, Juntao Yu, arXiv:2609.13866, September 2026.
  </Card>

  <Card title="flash-reinforce" href="/recipes/papers/flash-reinforce">
    Paper: FlashREINFORCE: Critic-Free Single-Rollout Asynchronous RL for Agentic Language Models, Yifan Hu et al., NVIDIA, September 2026 (no arXiv id yet).
  </Card>

  <Card title="gmts-token-select" href="/recipes/papers/gmts-token-select">
    Paper: GMTS: Gradient Magnitude-based Token Selection Improves RLVR Training, Outongyi Lv et al., arXiv:2608.30632, August 2026.
  </Card>

  <Card title="harness-and-weights" href="/recipes/papers/harness-and-weights">
    Paper: Harness-Aware Self-Evolving: Co-Evolving Model Weights, Harness, and Task Solutions (HASE), Haochen Luo et al., arXiv:2607.03935, July 2026.
  </Card>

  <Card title="meta-harness" href="/recipes/papers/meta-harness">
    An outer loop over harness code.
  </Card>

  <Card title="sao-single-rollout" href="/recipes/papers/sao-single-rollout">
    Paper: Single-Rollout Asynchronous Optimization for Agentic Reinforcement Learning, Hou, Li, Tang, Dong (Tsinghua), arXiv:2607.07508, July 2026.
  </Card>

  <Card title="zero-rl-format-reward" href="/recipes/papers/zero-rl-format-reward">
    Paper: SimpleRL-Zoo: Investigating and Taming Zero Reinforcement Learning for Open Base Models in the Wild, Weihao Zeng et al., arXiv:2503.18892, March 2025.
  </Card>
</CardGroup>
