Metadata-Version: 2.5
Name: reward-lens
Version: 3.1.0
Summary: Audit a reward system, trace what it teaches, and write the result down as a record anyone can check
Project-URL: Homepage, https://github.com/reward-lens/reward-lens
Project-URL: Documentation, https://reward-lens.github.io
Project-URL: Changelog, https://github.com/reward-lens/reward-lens/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/reward-lens/reward-lens/issues
Author: Mohammed Suhail B Nadaf
License-Expression: MIT
License-File: LICENSE
Keywords: RLHF,RLVR,alignment,evaluation,measurement,reward-design,reward-hacking,reward-model
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: click>=8.5
Requires-Dist: coverage>=7.15.0
Requires-Dist: cryptography>=50.0.1
Requires-Dist: jsonschema-rs>=0.29
Requires-Dist: libcst>=1.9
Requires-Dist: pydantic-settings>=2.13
Requires-Dist: pydantic>=2.13
Requires-Dist: pyyaml>=6.0
Requires-Dist: rfc8785>=0.1.4
Provides-Extra: all
Requires-Dist: accelerate>=0.25.0; extra == 'all'
Requires-Dist: anyio>=4.9; extra == 'all'
Requires-Dist: cosmic-ray>=8.4.0; extra == 'all'
Requires-Dist: coverage>=7.15.0; extra == 'all'
Requires-Dist: crosshair-tool<0.1,>=0.0.109; extra == 'all'
Requires-Dist: datasets>=2.16.0; extra == 'all'
Requires-Dist: httpx2>=2.5.0; extra == 'all'
Requires-Dist: hypothesis>=6.100.0; extra == 'all'
Requires-Dist: jsonschema>=4.20.0; extra == 'all'
Requires-Dist: matplotlib>=3.7.0; extra == 'all'
Requires-Dist: mcp-types==2.2.0; extra == 'all'
Requires-Dist: mlflow<4,>=3.11; extra == 'all'
Requires-Dist: mutmut<4.0,>=3.6.0; extra == 'all'
Requires-Dist: numpy>=1.24.0; extra == 'all'
Requires-Dist: openenv==0.6.0; extra == 'all'
Requires-Dist: opentelemetry-api>=1.28.0; extra == 'all'
Requires-Dist: pandas>=2.0.0; extra == 'all'
Requires-Dist: peft>=0.7.0; extra == 'all'
Requires-Dist: pyarrow>=15.0; extra == 'all'
Requires-Dist: pydantic>=2.12.0; extra == 'all'
Requires-Dist: pyjwt[crypto]>=2.10.1; extra == 'all'
Requires-Dist: python-multipart>=0.0.9; extra == 'all'
Requires-Dist: safetensors>=0.4.0; extra == 'all'
Requires-Dist: salib>=1.5.0; extra == 'all'
Requires-Dist: scikit-learn>=1.3.0; extra == 'all'
Requires-Dist: scipy>=1.10.0; extra == 'all'
Requires-Dist: seaborn>=0.13.0; extra == 'all'
Requires-Dist: sigstore>=3.0; extra == 'all'
Requires-Dist: sse-starlette>=3.0.0; extra == 'all'
Requires-Dist: starlette>=0.27; extra == 'all'
Requires-Dist: torch<3.0,>=2.1.0; extra == 'all'
Requires-Dist: tqdm>=4.65.0; extra == 'all'
Requires-Dist: transformers<6.0,>=4.36.0; extra == 'all'
Requires-Dist: trl<2.0,>=1.9; extra == 'all'
Requires-Dist: typing-extensions>=4.13.0; extra == 'all'
Requires-Dist: typing-inspection>=0.4.1; extra == 'all'
Requires-Dist: uvicorn>=0.31.1; extra == 'all'
Requires-Dist: wandb<1,>=0.23; extra == 'all'
Provides-Extra: judge
Provides-Extra: mcp
Requires-Dist: anyio>=4.9; extra == 'mcp'
Requires-Dist: httpx2>=2.5.0; extra == 'mcp'
Requires-Dist: jsonschema>=4.20.0; extra == 'mcp'
Requires-Dist: mcp-types==2.2.0; extra == 'mcp'
Requires-Dist: opentelemetry-api>=1.28.0; extra == 'mcp'
Requires-Dist: pydantic>=2.12.0; extra == 'mcp'
Requires-Dist: pyjwt[crypto]>=2.10.1; extra == 'mcp'
Requires-Dist: python-multipart>=0.0.9; extra == 'mcp'
Requires-Dist: sse-starlette>=3.0.0; extra == 'mcp'
Requires-Dist: starlette>=0.27; extra == 'mcp'
Requires-Dist: typing-extensions>=4.13.0; extra == 'mcp'
Requires-Dist: typing-inspection>=0.4.1; extra == 'mcp'
Requires-Dist: uvicorn>=0.31.1; extra == 'mcp'
Provides-Extra: openenv
Requires-Dist: openenv==0.6.0; extra == 'openenv'
Provides-Extra: organisms
Requires-Dist: accelerate>=0.25.0; extra == 'organisms'
Requires-Dist: datasets>=2.16.0; extra == 'organisms'
Requires-Dist: numpy>=1.24.0; extra == 'organisms'
Requires-Dist: peft>=0.7.0; extra == 'organisms'
Requires-Dist: safetensors>=0.4.0; extra == 'organisms'
Requires-Dist: scikit-learn>=1.3.0; extra == 'organisms'
Requires-Dist: scipy>=1.10.0; extra == 'organisms'
Requires-Dist: torch<3.0,>=2.1.0; extra == 'organisms'
Requires-Dist: tqdm>=4.65.0; extra == 'organisms'
Requires-Dist: transformers<6.0,>=4.36.0; extra == 'organisms'
Provides-Extra: record
Requires-Dist: numpy>=1.24.0; extra == 'record'
Requires-Dist: pyarrow>=15.0; extra == 'record'
Requires-Dist: safetensors>=0.4.0; extra == 'record'
Provides-Extra: sigstore
Requires-Dist: sigstore>=3.0; extra == 'sigstore'
Provides-Extra: trace
Requires-Dist: pyarrow>=15.0; extra == 'trace'
Provides-Extra: trackers
Requires-Dist: mlflow<4,>=3.11; extra == 'trackers'
Requires-Dist: wandb<1,>=0.23; extra == 'trackers'
Provides-Extra: train
Requires-Dist: accelerate>=0.25.0; extra == 'train'
Requires-Dist: safetensors>=0.4.0; extra == 'train'
Requires-Dist: torch<3.0,>=2.1.0; extra == 'train'
Requires-Dist: transformers<6.0,>=4.36.0; extra == 'train'
Requires-Dist: trl<2.0,>=1.9; extra == 'train'
Provides-Extra: verifier
Requires-Dist: cosmic-ray>=8.4.0; extra == 'verifier'
Requires-Dist: coverage>=7.15.0; extra == 'verifier'
Requires-Dist: crosshair-tool<0.1,>=0.0.109; extra == 'verifier'
Requires-Dist: hypothesis>=6.100.0; extra == 'verifier'
Requires-Dist: mutmut<4.0,>=3.6.0; extra == 'verifier'
Requires-Dist: numpy>=1.24.0; extra == 'verifier'
Requires-Dist: salib>=1.5.0; extra == 'verifier'
Provides-Extra: viz
Requires-Dist: matplotlib>=3.7.0; extra == 'viz'
Requires-Dist: pandas>=2.0.0; extra == 'viz'
Requires-Dist: seaborn>=0.13.0; extra == 'viz'
Provides-Extra: white-box
Requires-Dist: accelerate>=0.25.0; extra == 'white-box'
Requires-Dist: numpy>=1.24.0; extra == 'white-box'
Requires-Dist: safetensors>=0.4.0; extra == 'white-box'
Requires-Dist: scikit-learn>=1.3.0; extra == 'white-box'
Requires-Dist: scipy>=1.10.0; extra == 'white-box'
Requires-Dist: torch<3.0,>=2.1.0; extra == 'white-box'
Requires-Dist: tqdm>=4.65.0; extra == 'white-box'
Requires-Dist: transformers<6.0,>=4.36.0; extra == 'white-box'
Description-Content-Type: text/markdown

# reward-lens

`reward-lens` turns a reward system into an auditable assay record and an offline report. It is for work where the reward written in code may differ from the objective a policy learned to optimize.

<!-- 3.1.0-route -->
## 3.1.0: audit a reward system

reward-lens 3.1.0 audits a reward system and writes an assay record and an offline report. This is the active 3.1.0 product route. For an unreleased source checkout, run `pip install .`. The installation section distinguishes source builds from published packages.

```bash
reward-lens init --example code-reward ./demo
reward-lens audit ./demo
reward-lens doctor
```

The example has deliberate defects: its audit exits 2 with an unresolved decision. Add `--format json` to receive the command envelope. `trace`, `compare`, `forecast`, and `improve` require their declared inputs; missing access produces a refusal. Compatibility with the inherited 3.0 library surface is documented below.
<!-- /3.1.0-route -->

## Versions and installation

Release availability is recorded on [PyPI](https://pypi.org/project/reward-lens/) and
[GitHub Releases](https://github.com/reward-lens/reward-lens/releases). Once the
3.1.0 release is published, install its exact version with:

```bash
python -m pip install reward-lens==3.1.0
```

To build this source revision before or after publication, use a checked-out commit:

```bash
python -m pip install .
```

Python `3.11` or newer is required. The base package does not require Node or a model runtime. Optional extras in `pyproject.toml` cover integrations that need them.

## First audit

```bash
reward-lens init --example code-reward ./demo
reward-lens audit ./demo
reward-lens doctor
```

`init` writes the example project. `audit` writes a record and report in that project. `doctor` reports the measurements available from the supplied inputs and what further access would be required. The bundled example includes deliberately wrong tasks. Its audit produces a report with blocking findings and exits 2; this smoke check is not an all-clear result. `trace`, `compare`, `join`, `forecast`, and `improve` consume their own declared inputs. Use `reward-lens <command> --help` to see them. Missing inputs and unavailable optional capabilities remain explicit refusals.

Open the saved report locally with `reward-lens open <record.assay.json> --workbench`; the command prints an authentication URL. Export a signed portable bundle with `reward-lens export --record <record.assay.json> --kind bundle --dest ./bundle`, then verify it with `reward-lens import ./bundle --verify --save-to ./imported`. Verification preserves an unresolved decision; it does not turn it into a pass.

## What is here

- `src/reward_lens/`: the installable library, CLI, schemas, report renderer, adapters, and optional integrations.
- `schema/` and `spec/`: public schema and catalogue sources used by the package.
- `frontend/`: source for the offline report and local authenticated workbench. The built JavaScript and stylesheet are committed under the Python package so normal package builds do not require Node.
- `tests/`: reusable contract, API, CLI, packaging, and compatibility tests. [`TEST_STATUS.md`](TEST_STATUS.md) states which broader suites remain incomplete or need optional dependencies.
- `docs/`: API, schema, command, and method documentation.

The accompanying [GRPO Reward Trace](https://github.com/reward-lens/grpo-reward-trace) repository contains protocol and fixture code for studying how GRPO rewards become update pressure and learned behavior. Both source imports became public on 24 September 2026 (Asia/Kolkata). The independently installed public study fixture produced 2 pass, 1 fail, 1 defect, and 32 unrun rows; those are routing outcomes, not a completed GPU experiment.

## Compatibility and history

The 3.1.0 source keeps the supported `reward_lens` import name, the `reward-lens` and `rlens` command names, and established serialized keys. [`docs/compatibility.md`](docs/compatibility.md) records the six retained v3 behavior fixes and their public tests.

This repository was assembled from reviewed source snapshots. [`docs/publication-history.md`](docs/publication-history.md) explains the reconstructed import history, source revisions, and its limits. Commit dates in that import history are not evidence of public preregistration, experiment execution, or package release dates.

## Limits

The repository contains reusable code, small fixtures, and documentation. It excludes private fleet records, raw run outputs, local provider configuration, credentials, and large captured research material. A clean fixture or package check does not establish that an unfinished empirical study ran or that a reward mechanism was validated on a new model.

Contributors install the development group with `uv sync --group dev`. For the supported checks, read [CONTRIBUTING.md](CONTRIBUTING.md) and [TEST_STATUS.md](TEST_STATUS.md).

Historical [development snapshots](https://github.com/reward-lens/reward-lens/blob/5ece0eb5d3e85fa275decaedc0841a8181708f3a/development-snapshots/README.md) preserve selected unfinished alternatives in public history. The [C1 dependency snapshot](https://github.com/reward-lens/reward-lens/blob/5ece0eb5d3e85fa275decaedc0841a8181708f3a/reproducibility/c1-reward-lens-snapshot/README.md) records the isolated library source used by that historical research.
