API reference
Studies
Who decides whether a result confirmed the hypothesis, the author or the spec? In reward_lens.studies it is the spec, and it decides before the data exists. You write down the hypothesis, the predictions, and the kill criteria, freeze that into a content-hashed artifact, then run it. The run adjudicates the frozen predictions, not whatever the analysis wishes it had predicted. The discipline is studies and preregistration.
The spec
A StudySpec collects a Hypothesis, its Predictions, the KillCriterions that would sink it, and a SubjectQuery naming what to run it on. A prediction knows how to check a value against itself; a kill criterion knows when it has fired.
reward_lens.studies.spec.StudySpec
@dataclass(frozen=True)
The full specification of a confirmatory study (section 2.14).
Attributes
| Name | Type | Default |
|---|---|---|
id | str | |
title | str | |
science | str | |
hypotheses | tuple[Hypothesis, ...] | |
analysis | str | |
subjects | SubjectQuery | field(default_factory=SubjectQuery) |
kill_criteria | tuple[KillCriterion, ...] | () |
oracle_budget | Cost | None | None |
version | int | 1 |
notes | str | '' |
reward_lens.studies.spec.Hypothesis
@dataclass(frozen=True)
A hypothesis with its registered prediction and the scoreboard row it addresses.
Attributes
| Name | Type | Default |
|---|---|---|
id | str | |
statement | str | |
prediction | Prediction | |
scoreboard_row | str | None | None |
reward_lens.studies.spec.Prediction
@dataclass(frozen=True)
A registered, checkable prediction (R12).
metric names the quantity the analysis will compute; comparator and threshold state
the predicted relationship (for example metric="spearman_chi_vs_drift", comparator=">", threshold=0.3). effect and ci_excludes optionally register a point effect size and a
value the CI should exclude. This is what makes a claim uneditable after seeing the data: the
prediction is hashed into the frozen study.
Attributes
| Name | Type | Default |
|---|---|---|
metric | str | |
comparator | Comparator | |
threshold | float | |
effect | float | None | None |
ci_excludes | float | None | None |
rationale | str | '' |
Methods
check(value: float) -> bool
src
reward_lens.studies.spec.KillCriterion
@dataclass(frozen=True)
A schema-fielded kill criterion (R12, section 2.14).
If metric stands in comparator relation to threshold after the run, the criterion
fires and the study produces a first-class negative-result report rather than a hidden failure.
The description states, in one sentence, what a fired criterion means scientifically.
Attributes
| Name | Type | Default |
|---|---|---|
id | str | |
metric | str | |
comparator | Comparator | |
threshold | float | |
description | str | '' |
Methods
fired(value: float) -> bool
src
reward_lens.studies.spec.SubjectQuery
@dataclass(frozen=True)
A declarative description of the study’s subjects (signals, organisms, datasets).
Held as ids/specs so the frozen study names exactly what it ran on. The runner resolves these to concrete objects at run time; the engine test injects them directly.
Attributes
| Name | Type | Default |
|---|---|---|
signals | tuple[str, ...] | () |
organisms | tuple[str, ...] | () |
datasets | tuple[str, ...] | () |
extra | dict[str, Any] | field(default_factory=dict) |
Freeze and run
freeze stamps the spec with its content hash and the git sha into a FrozenStudy, giving it an identity of the form study:{id}@v{version}#{hash8}. run_study then executes it and adjudicates the frozen predictions, returning an outcome of confirmed, refuted, or inconclusive. Only a study that predated its data can reach the REGISTERED rung of trust. The worked version is freeze and run a study.
reward_lens.studies.freeze.freeze
freeze(
spec: StudySpec,
repo_dir: str | None = None,
frozen_at: str | None = None
) -> FrozenStudy Freeze a study spec, computing its StudyID and recording the git sha (gate 3).
The StudyID is study:{spec.id}@v{spec.version}#{hash8} where the hash is the first 8 hex
characters of the spec’s content hash. Two specs that differ in any registered field (a
prediction threshold, a kill criterion, the analysis path) get different ids, which is exactly
the property that makes post-hoc editing visible as a new version.
reward_lens.studies.runner.run_study
run_study(
spec_or_frozen: StudySpec | FrozenStudy,
*,
subjects: dict[str, Any] | None = None,
store: EvidenceStore | None = None,
analysis_fn: Callable[[StudyRun], StudyResult] | None = None
) -> tuple[FrozenStudy, StudyResult] Run a study end to end: freeze if needed, execute the analysis, adjudicate against the spec.
The study must be frozen before it runs (a spec is frozen here if a raw spec was passed, so the freeze provably predates the evidence). The analysis function (resolved from the spec’s dotted path, or supplied directly for tests) computes the metrics its predictions named. The runner then checks each hypothesis’s prediction and each kill criterion against those metrics, sets the outcomes, and returns the StudyResult with its adjudicating evidence ids attached. Refutations and fired kill criteria are recorded as prominently as confirmations (I4).
The scoreboard
Scoreboard collects the standing claims, the theorems and the candidate laws, and their current status as registered evidence accrues for or against each one.
reward_lens.studies.scoreboard.Scoreboard
Scoreboard(path: str | Path | None = None) A persisted registry of theorem rows and their status (section 2.14).
Methods
save() -> None
src
register_row(row: ScoreboardRow) -> None
src
update_from_result(study_id: str, spec_hypotheses, result: StudyResult) -> None
src
A hypothesis maps to a scoreboard row via scoreboard_row. Confirmed and refuted outcomes
update the row’s status; a row that receives both confirming and refuting evidence across
hypotheses or studies becomes “mixed”. The adjudicating Evidence ids are recorded so the row
can cite exactly what settled it.
render_markdown() -> str
src