API reference
Measure and indices
What turns a signal into a measurement you can file? One runner. reward_lens.measure holds the observable protocol, the eleven white-box instruments of the battery, and the eighteen scalar indices, and every one of them returns Evidence through the same gate-enforcing runner. The narrated tour is under instruments.
The runner
An Observable declares the capability it needs and the gauge status of what it returns. run enforces the capability and the frame requirement before the observable is allowed to touch a signal, and threads the calibration and study facts through so the resulting evidence comes out with its trust level already computed. A Context carries the signal, the data view, and any comparison target.
reward_lens.measure.base.run
run(observable: Observable, ctx: Context) -> Evidence Run an Observable under the gates (section 2.8.1).
Enforces R3 (the signal must declare the required capability) and gate 2 (a covariant
cross-signal comparison requires a frame) before delegating to measure. Gates 1 and 3 are
applied inside ctx.emit. The result is a fully gated Evidence; there is no path that
returns an ungated number.
reward_lens.measure.base.Context
@dataclass
Everything an Observable needs to run, plus the machinery to emit gated Evidence.
signal is the primary subject; others names additional signals for cross-signal
comparisons (an effective-angle Observable puts the second model here). view is the
DataView; readout selects which readout to read; frame supplies the gauge frame for
covariant/invariant observables; study is the frozen StudyID when the run is registered
(gate 3). regime describes the data regime for the calibration lookup (gate 1).
Observables call emit to build their Evidence; emit applies gates 1 and 3 centrally so
an Observable cannot forget them. The runner (run) applies the capability check and gate 2.
Attributes
| Name | Type | Default |
|---|---|---|
signal | RewardSignal | |
view | Any | None |
readout | str | 'reward' |
others | tuple['RewardSignal', ...] | () |
frame | FrameID | None | None |
study | str | None | None |
is_comparison | bool | False |
regime | dict[str, Any] | field(default_factory=dict) |
stats | dict[str, Any] | field(default_factory=dict) |
Methods
subject(extra: dict | None = None) -> SubjectRef
src
emit(
value: Any,
*,
uncertainty: Uncertainty | None = None,
gauge: GaugeStatus | None = None,
parents: tuple[EvidenceID, ...] = (),
cost: Cost | None = None,
subject_extra: dict | None = None
) -> Evidence
src
Applies gate 1 (looks up a calibration reference for this observable and subject; absent
means EXPLORATORY) and gate 3 (a frozen study makes it REGISTERED). Gate 2’s gauge status
is taken from the Observable’s declaration unless overridden. The trust level falls out of
make_evidence, never set here directly.
reward_lens.measure.base.Observable
@runtime_checkable
Bases: Protocol
A measurement (section 2.8.1).
requires is the capability the signal must declare; gauge_status is how the value
transforms under the gauge group; faithful_to names the Appendix A theory object it
instantiates (or None), and deviations lists explicit departures from it. measure
computes the Evidence, calling ctx.emit to build it so gates 1 and 3 are applied centrally.
Attributes
| Name | Type | Default |
|---|---|---|
name | str | |
version | str | |
requires | Capability | |
gauge_status | GaugeStatus | |
faithful_to | str | None | |
deviations | tuple[str, ...] |
Methods
measure(ctx: Context) -> Evidence
src
The battery
Eleven observables, imported from reward_lens.measure.battery. The first few read the reward geometry directly off activations and the linear readout, and are gauge-invariant. The last few compare readouts or SAE features and are RAW_ONLY or need a frame, so they refuse a cross-model claim without one.
LensCrystallization finds the depth where the chosen-versus-rejected margin reaches half its final value: the layer the model made up its mind. See reward lens and crystallization.
reward_lens.measure.battery.lens.LensCrystallization
Bases: BaseObservable
Layer-by-layer preference formation and its crystallization depth (E02).
Requires activation capture and a linear readout. The crystallization fraction is a depth in
[~0, 1] and is gauge-invariant (comparable across signals), which is why E02 headlines the
per-model mean fraction directly.
Methods
measure(ctx: Context) -> Evidence
src
DirectLinearAttribution splits the reward differential into a signed share per component. It reads where the reward is visible, which is not the same as what causes it; that gap is the subject of observational versus causal.
reward_lens.measure.battery.dla.DirectLinearAttribution
Bases: BaseObservable
Signed per-component reward attribution for preference pairs (E03/E04).
Requires activation capture and a linear readout. The contributions are in reward units and sum to the reward differential; the invariant scientific summary is their ranking, which E04 compares to the patching ranking. Marked INVARIANT because the reward is gauge-fixed by the head and the faithfulness statistic is rank based.
Methods
measure(ctx: Context) -> Evidence
src
PatchGrid is the causal counterpart: the effect on the reward of patching a component or head. PathEffect measures a two-hop sender-to-receiver path. Both are gated to a real model at head granularity.
reward_lens.measure.battery.patch.PatchGrid
Bases: BaseObservable
PatchGrid(granularity: str = 'component') -> None Causal patch effects for every component (or head) on preference pairs (E15).
granularity is "component" (attention and MLP sublayers, the default) or "head" (every
attention head). Requires activation capture and a linear readout. Patch effects are in reward
units and are gauge-invariant within a signal.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.battery.path.PathEffect
Bases: BaseObservable
Two-hop head-to-receiver path effect on reward for preference pairs (E15).
Requires activation capture and a linear readout. The path effect is in reward units and gauge-invariant within a signal.
Methods
measure(ctx: Context) -> Evidence
src
ConceptDoseResponse measures a concept direction’s reward alignment and its causal dose-response slope: push the activation along the concept, watch the reward move.
reward_lens.measure.battery.concept.ConceptDoseResponse
Bases: BaseObservable
Concept direction, its reward alignment, and its causal dose response (E08).
Requires activation capture and a linear readout. The concept is read from the pairs in the view (chosen positive, rejected negative). Marked RAW_ONLY because the direction, its alignment, and the dose are all in raw residual-stream coordinates.
Methods
measure(ctx: Context) -> Evidence
src
BiasBattery reports a standardized reward bias per axis with a lineage-honest sample size, and PromptSNR the power signal-to-noise of the reward delta.
reward_lens.measure.battery.bias.BiasBattery
Bases: BaseObservable
Per-axis standardized reward bias with lineage-honest effective sample size (E06).
Requires only scores. The view is grouped by each pair’s axis; each axis reports its reward
delta effect size and the honest ESS of its seeds. INVARIANT (Cohen’s d is standardized).
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.battery.snr.PromptSNR
Bases: BaseObservable
Per-axis reward signal-to-noise ratio (E16).
Requires only scores. The view is grouped by each pair’s axis. INVARIANT (a dimensionless
power ratio).
Methods
measure(ctx: Context) -> Evidence
src
ConflictMatrix reads the cosine geometry between per-axis reward terms, and CircuitJaccard the top-component overlap between two models.
reward_lens.measure.battery.conflict.ConflictMatrix
Bases: BaseObservable
Inter-axis reward-term conflict geometry (E09).
Requires activation capture and a linear readout. The view must span at least two axes. Marked RAW_ONLY because the term cosines are in raw residual-stream coordinates.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.battery.circuit.CircuitJaccard
Bases: BaseObservable
Top-component circuit overlap between two reward models (E05).
ctx.others[0] is the second signal to compare against ctx.signal; both are attributed on
the same view. top_k (from ctx.regime['top_k'], default 5) sets the circuit size. Requires
activation capture and a linear readout. INVARIANT: the overlap is a set membership over named
components, not a covariant geometric quantity.
Methods
measure(ctx: Context) -> Evidence
src
FeatureRewardAlignment asks which SAE features drive the reward, and MultiObjectiveGeometry reads the per-objective readout geometry of a multi-objective head like ArmoRM.
reward_lens.measure.battery.feature.FeatureRewardAlignment
Bases: BaseObservable
Per-feature reward alignment of an SAE over a signal (E12).
The SAE comes from ctx.regime['sae'] (a TopKSAE whose d_model matches the signal). When
absent, a small random SAE is built so the mechanics run and the result is flagged untrained.
Requires a linear readout. RAW_ONLY: alignments depend on the SAE and residual bases.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.battery.geometry.MultiObjectiveGeometry
Bases: BaseObservable
The cosine geometry of a multi-objective reward head (E18).
Requires a linear readout with more than one objective row. Marked RAW_ONLY because the cosines are in raw residual-stream coordinates; they are a single-model internal geometry and are not cross-model comparable without a frame.
Methods
measure(ctx: Context) -> Evidence
src
The index library
Eighteen scalar diagnostics, imported from reward_lens.measure.indices. Each pairs a definition with a pure-numpy function and returns Evidence. All of them default to EXPLORATORY: there is no calibration provider wired for the index library yet, so they name a quantity honestly without claiming a validated regime. Sixteen are gauge-invariant; VCE and Contested are covariant and need a frame to compare. The narrated version is the index library.
reward_lens.measure.indices.kui.KUI
Bases: BaseObservable
KUI(
properties: Sequence[Property] | None = None,
*,
null_draws: int = 10000,
seed: int = 0
) -> None A1 Knowledge-Utilization Index: the (decode, mediate) plane and the diagonal distance.
Requires activations and a linear readout on the production path (a probe reads decodability from
h and a direction gives the mediation proxy). The battery of properties is injected (each a
Property with a decodability and either a measured Δr or a direction w_P); the concept
layer supplies probes and directions in production. When the mediation proxy is used, the cosine is
read against a random-direction null so a “represented-but-unpriced” flag beats the high-dimensional
cosine noise floor. Gauge is INVARIANT: the plane is a within-battery, within-signal object.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.distortion.Distortion
Bases: BaseObservable
Distortion(
directions: np.ndarray | None = None,
*,
coverage: Sequence[float] | None = None,
curvature: Sequence[float] | None = None,
names: Sequence[str] | None = None
) -> None A2 per-dimension distortion v2, with KUI supplying the coverage term.
Requires activations and a linear readout. Takes a battery of property directions and their KUI
mediation-percentile coverage (injected; the concept layer and the KUI index supply both in
production), computes the linear sensitivity |w_r · v_P| (or uses an injected Hessian curvature),
and reports the per-dimension distortion. Gauge is INVARIANT: distortion is a within-signal
per-direction magnitude.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.coverage_disparity.CoverageDisparity
Bases: BaseObservable
CoverageDisparity(coverage: Sequence[float] | None = None) -> None v1’s coverage statistic, kept reproducible under its honest name (not Wang-Huang distortion).
Takes a battery of per-property coverage values (injected; the concept/KUI layer supplies them in
production) and reports their disparity. faithful_to is None on purpose: this instantiates no
Appendix A theory object, it preserves a v1 statistic, and the deviation note says so. Gauge is
INVARIANT.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.teacher_compatibility.TeacherCompatibility
Bases: BaseObservable
A3 induced reward variance w_rᵀ Σ_π w_r, layer- and spectrum-decomposable.
Requires activation capture and a linear readout. Reads w_r off the readout, captures the
on-policy final-token activations at the readout site (and at every residual layer when the signal
reports its depth, for the layer decomposition), and reports the total with its spectral split.
Gauge is INVARIANT: it is a single-signal functional, not a cross-signal comparison. It carries
reward-scale² units, so a cross-model magnitude comparison first needs the two rewards on a common
scale; that caveat is stated as a deviation rather than silently ignored.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.tail.TailIndex
Bases: BaseObservable
TailIndex(
feature_bank: FeatureBank | None = None,
*,
quantile: float = 0.9,
bootstrap: int = 500,
ci: float = 0.95,
seed: int = 0
) -> None A4 right-tail exponent of the reward, aggregate and per-feature.
Requires scores (and activations plus a linear readout for the per-feature tails). Scores the base
policy samples, estimates the aggregate tail with a bootstrap CI on the shape, and, when a feature
bank is available, estimates each feature’s tail as the proxy for its contribution to r. Gauge
is INVARIANT: the tail regime and the dimensionless shape are scale-free properties of one signal,
though τ and λ_c carry reward-scale units, which is noted as a deviation.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.verification_score.VerificationScore
Bases: BaseObservable
VerificationScore(
dr_total: float | None = None,
dr_error_span: float | None = None
) -> None A6 causal fraction of the correctness reward gap that lives at the labeled error span.
Requires prefix scores (the process/verifier reward) on the production path, plus the interventions
subsystem for the clean-twin span patch. Here the measured deltas are injected (dr_total,
dr_error_span) so the attribution arithmetic is exercised without waiting for interventions; the
production path substitutes the patched deltas. Gauge is INVARIANT: VS is a fraction.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.receipt_reliance.ReceiptReliance
Bases: BaseObservable
ReceiptReliance(dr_receipt: float | None = None, dr_total: float | None = None) -> None A7 fraction of the corruption reward effect the reward reads off receipt spans.
Requires span-typed inputs and prefix scores on the production path (the receipt-span patch and the
falsify-receipt/falsify-narrative arms). Here the arm deltas are injected so the attribution
arithmetic runs directly. Gauge is INVARIANT: RRS is a fraction.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.skepticism.Skepticism
Bases: BaseObservable
Skepticism(
r_receipt_absent: np.ndarray | None = None,
r_receipt_failure: np.ndarray | None = None
) -> None A8 whether the reward treats a missing receipt as failure (skeptical) or reward (credulous).
Requires span-typed inputs on the production path (the receipt-absent and receipt-failure conditions
of matched narratives). Here the two score vectors are injected so the difference is exercised
directly. Gauge is INVARIANT with respect to representation, though S carries reward-scale units,
noted as a deviation.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.coherence.Coherence
Bases: BaseObservable
Coherence(
directions: np.ndarray | None = None,
*,
spectrum: Any = None,
null_draws: int = 5000,
seed: int = 0
) -> None A9 cross-criterion coherence, contamination, Welch floor, and d_eff.
Requires a multi-readout signal (a reward exposing several criterion directions). The criterion
directions are taken from the signal’s criterion:k readouts (ArmoRM’s objectives are first-class,
never a row mean), or injected directly for the synthetic test. Reports the coherence matrix, the
Welch bound and whether the criteria are over-packed past d_eff, and the mean contamination, with
the mean coherence read against a random-direction null so “the criteria are more aligned than
chance” beats the high-dimensional noise floor. Gauge is INVARIANT: the Gram of one signal’s own
criteria is invariant under a shared orthogonal transform of the representation; a cross-signal
criterion comparison would be COVARIANT and frame-gated, which is noted as a deviation.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.dark_reward.DarkReward
Bases: BaseObservable
DarkReward(named_contributions: np.ndarray | None = None) -> None A10 fraction of reward variance mediated by no named channel.
Requires scores. The named-channel contributions are injected (the concept/criterion layer supplies them in production; the causal reading uses steering-measured contributions). Reports the dark fraction. Gauge is INVARIANT: a variance fraction is scale-free.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.interp_coverage.InterpCoverage
Bases: BaseObservable
InterpCoverage(
feature_contributions: np.ndarray | None = None,
error_contributions: np.ndarray | None = None
) -> None A11 fraction of reward routed through interpretable features rather than error nodes.
Requires activations on the production path (the attribution graph is built from them). The feature and error-node contributions are injected here; the production path supplies them from an attribution graph with a scalar reward sink. Gauge is INVARIANT: a coverage fraction is scale-free.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.chi.Chi
Bases: BaseObservable
Chi(
feature_bank: FeatureBank | None = None,
*,
gold: Any = None,
null_draws: int = 2000,
seed: int = 0
) -> None A12 susceptibility spectrum χ_i = Cov_0(f_i, r) over a feature bank on base-policy samples.
Requires activation capture, scores, and a linear readout. Captures the base-policy activations,
turns them into feature values through the feature bank (injected, else the concept layer’s default,
else a graceful no-bank report), scores the same samples, and reports the χ spectrum with a
per-feature shuffle null. When a gold signal is supplied it also scores the gold objective and
flags the predicted hack modes (χ_i > 0 with χ_gold_i ≤ 0).
Gauge is INVARIANT: χ is a within-signal spectrum relative to a fixed feature bank. Comparing
individual χ_i across signals requires the same bank read in a shared frame; that is a
cross-signal comparison the caller must set up, and is noted as a deviation.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.vce.VCE
Bases: BaseObservable
VCE(
reward_alignment: float | None = None,
capability_alignment: float | None = None,
*,
d: int | None = None,
k: int | None = None,
null_draws: int = 1000,
seed: int = 0
) -> None A14 Value Convergence Excess: reward-subspace agreement beyond capability agreement.
A cross-signal comparison: COVARIANT and frame-gated (the reward and capability alignments must be
computed on frame-canonicalized subspaces of the RM pair). The two same-metric alignment scalars are
injected here (with the ambient d and subspace k for the null); the production path computes
them through geometry.subspace in a shared frame. Reports VCE against the RUM-identifiability
null.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.legibility.Legibility
Bases: BaseObservable
Legibility(
predicates: np.ndarray | None = None,
costs: Sequence[float] | None = None,
*,
budgets: Sequence[float] | None = None
) -> None A15 legibility frontier fidelity(K), its knee K*, and the tacit residual.
Requires scores. The predicate library and description-length costs are injected (the concept layer’s difference dictionary supplies them in production). Reports the fidelity curve over the budget, the knee, and the illegible tacit residual. Gauge is INVARIANT: fidelity is a rank agreement, and the tacit residual’s variance fraction is scale-free.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.eval_awareness.EvalAwareness
Bases: BaseObservable
EvalAwareness(
is_benchmark: np.ndarray | None = None,
*,
steering_delta_r: float | None = None,
null_draws: int = 2000,
seed: int = 0
) -> None A17 balanced accuracy of a benchmark-vs-organic probe on reward activations, with a null.
Requires activations. Labels marking which inputs are benchmark-style are injected (the data plane
supplies them in production); the causal Δr from steering the recognition direction is injected
and is the production path. Reports the held-out balanced accuracy against a label-permutation null.
Gauge is INVARIANT: balanced accuracy is a within-signal classification quality.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.snr.RobustnessSNR
Bases: BaseObservable
RobustnessSNR(groups: Any = None) -> None Robustness SNR: between-condition reward signal over within-condition paraphrase noise.
Requires scores. The paraphrase-cluster labels are injected (or read from the view’s group ids); the production path scores paraphrase clusters through the signal. Gauge is INVARIANT: a variance ratio is scale-free.
Methods
measure(ctx: Context) -> Evidence
src
reward_lens.measure.indices.contested.Contested
Bases: BaseObservable
Contested(
delta_h: np.ndarray | None = None,
disagreement: np.ndarray | None = None
) -> None Contested direction: the representation axis annotators disagree along.
Requires activations. The per-pair Δh and the disagreement signal are injected (the data plane’s
annotator records supply disagreement in production). The direction is COVARIANT: comparing contested
directions across signals requires a shared frame (gate 2). Within one signal the recovered axis and
its correlation are reported directly.
Methods
measure(ctx: Context) -> Evidence
src