# an.bench.registry

The metric declaration table — what each number is, and which way it should move.

This is **data, not prose**, because an#41’s criterion is a query over it:
“>=3 metrics from >=3 distinct causal families, evaluated per mutation, with a
per-metric per-mutation sign declared in advance”. A second, hand-maintained
table of families is how that criterion silently stops being true.

Three things the research requires this table to carry, all three of which
invalidate every prior ledger row if retrofitted:

1. **A per-metric per-mutation direction**, two-sided where the optimum is
   interior. `edge_transition_width` has an interior optimum — under 1 is a
   staircase, 3+ is soft — and the sharpness family moves in *opposite*
   directions for the two mutations, so a single per-metric sign mis-reports
   one of them.
2. **\`\`null\`\` (gated) distinguished from “no change”.** “No change by
   construction” is a tautology and must never count as a satisfied
   prediction, or any pre-encode statistic pads the count for free. Four
   states, not two: `gated` (the reference moved, or the source hash
   differs), `unavailable` (the check could not run — a crashed check is not
   evidence anything is fine), `no_change` (tautology), `not_applicable`
   (wrong side of the encoder).
3. **The family letters**, so the redundancy rule is checkable. Family C
   counts as **one** until the correlation between `coded_luma_edge_error`
   and `chroma_edge_dCr` is measured across the encoder matrix — they were
   r=0.990 in their broken forms and the corrections are *expected* to
   decorrelate them, which is not the same as measured.

The invariants are enforced in `__post_init__`, not by convention.

### Module Attributes

| [`MUTATIONS`](#an.bench.registry.MUTATIONS)      | an encoder lever cannot touch a golden-frame metric because the corpus is UPSTREAM of the encoder, so requiring ">=3 metrics" from a CRF change alone would fail because of where the corpus sits, not because the instrument is blind — and that failure would be misdiagnosed as the harness being wrong.   |
|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`REFUSED_LEVERS`](#an.bench.registry.REFUSED_LEVERS) | Levers that were TRIED and refused, each with the measured reason — data, so `an bench --mutation <name>` answers with the reason instead of "unknown", and the next person meets the measurement before re-registering one.                                                                                  |
| [`REFERENCE_NOTE`](#an.bench.registry.REFERENCE_NOTE) | What an encode-side metric is measured AGAINST.                                                                                                                                                                                                                                                               |
| [`FAMILY_SIDE`](#an.bench.registry.FAMILY_SIDE)    | Which side of the encoder each causal family lives on.                                                                                                                                                                                                                                                        |
| [`METRICS`](#an.bench.registry.METRICS)        | The panel.                                                                                                                                                                                                                                                                                                    |
| [`TRIPWIRES`](#an.bench.registry.TRIPWIRES)      | Tripwires.                                                                                                                                                                                                                                                                                                    |

### Classes

| [`MetricSpec`](#an.bench.registry.MetricSpec)(key, family, unit, optimum, ...)     | One row of the panel.                                                            |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
| [`Optimum`](#an.bench.registry.Optimum)(kind[, expect, note])                   | Which way "better" points, and whether the optimum is interior.                  |
| [`Prediction`](#an.bench.registry.Prediction)(expect[, counts, gate, reason, ...]) | What one metric is expected to do under one mutation, declared in advance.       |
| [`Sweep`](#an.bench.registry.Sweep)(grid, shipped)                            | The grid of a threshold counter's OWN free parameters its verdict is checked on. |
| [`Touch`](#an.bench.registry.Touch)(path[, differs_only_in])                  | One environment key a lever is expected to change, and HOW.                      |

### Exceptions

| [`RegistryError`](#an.bench.registry.RegistryError)   | A metric declaration violates one of the table's invariants.   |
|------------------------------------------------------------------|----------------------------------------------------------------|

### an.bench.registry.FAMILY_SIDE *: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [str](https://docs.python.org/3/builtins/stdtypes.html#str)]* *= {'A': 'render', 'B': 'render', 'C': 'encode', 'D': 'encode', 'E': 'encode', 'F': 'encode', 'G': 'encode'}*

Which side of the encoder each causal family lives on. Render-side metrics
are computed on the pre-encode PNG and are blind to the encoder BY
CONSTRUCTION; encode-side metrics compare a decoded frame to its own source
and are structurally blind to render regressions, because the reference
moves with the mutation. They must never be mixed.

### an.bench.registry.METRICS *: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [MetricSpec](#an.bench.registry.MetricSpec)]* *= {'chroma_edge_dCr': MetricSpec(key='chroma_edge_dCr', family='C', unit='code values (8-bit Cr)', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=False, gate=None, reason='family C counts as ONE family until the correlation with coded_luma_edge_error is measured across the encoder matrix', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='reference_moved', reason='measured -0.7% on a faithful AA-off simulation; the claimed +10.7% was refuted. Predict no render-side direction.', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='reference_moved', reason='its subject IS the 4:2:0 subsampling of a conversion whose input this lever changes, so there is no fixed reference. Predict no render-side direction, exactly as for \`disabled_aa\`.', reference=None)}, sentence='How much the colour shifts on the pixels straddling a hard outline once the video is encoded.', role=None, reference='source_png', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'chroma_edge_dCr_over_dY': MetricSpec(key='chroma_edge_dCr_over_dY', family='C', unit='ratio', optimum=Optimum(kind='guard', expect=None, note="3.3 at qp0 yuv420p is real 4:2:0 bleed; 0.96 at crf51 is generic damage wearing the metric's name. The denominator IS \`coded_luma_edge_error\` — the research's \`chroma_edge_dY\` control is mean |dY| over the edge mask, which is that metric's definition verbatim. Measured identical (1.484149 for both on the first real row), so it is recorded once rather than twice: one signal under two names is exactly how a witness count is padded dishonestly."), predictions={'high_crf': Prediction(expect='decrease', counts=False, gate=None, reason='the chroma claim collapses as damage becomes generic', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None)}, sentence='dCr/dY on the edge mask: large means real chroma bleed, ~1 means generic blocking.', role='diagnostic', reference='source_png', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'chroma_edge_dY': MetricSpec(key='chroma_edge_dY', family='C', unit='code values (8-bit Y)', optimum=Optimum(kind='guard', expect=None, note="Read only as the ratio's denominator. NOT a second name for \`coded_luma_edge_error\`: that one references the lossless leg and this one references the PNG conversion, so they differ by exactly the conversion term. They were identical (1.484149) while both referenced the PNG conversion, which is why one of them was removed and then restored when the references diverged."), predictions={'high_crf': Prediction(expect='increase', counts=False, gate=None, reason='control for the ratio below', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None)}, sentence='The luma error on the SAME mask and the SAME reference as \`chroma_edge_dCr\` — a control, not a quality metric.', role='control', reference='source_png', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'coded_luma_edge_error': MetricSpec(key='coded_luma_edge_error', family='C', unit='code values (8-bit Y)', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=True, gate=None, reason="family C's witness", reference='0.419 (qp0) -> 1.875 (crf23) -> 41.2 (crf51)'), 'disabled_aa': Prediction(expect=None, counts=False, gate='reference_moved', reason='the source PNG moves with the mutation, so the delta is uninterpretable', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='reference_moved', reason='same gate, same mechanism as \`disabled_aa\`: the source PNG moves with the mutation. A render lever of EITHER sign disqualifies it — and this one is the reason to say so out loud, because a softer source shrinks the edge mask to its easiest members and the number improves MECHANICALLY. Ungated it is one of the 7 unearned improvements a \`mutation=None\` diff reports for this change (an#56).', reference=None)}, sentence="How much the encoder's quantiser roughens the brightness step at a line's edge, measured on the codec's own luma plane.", role=None, reference='lossless', provisional=False, unreviewed=False, tripwire=False, requires='', notes=("Read the coded luma plane; NEVER recompute Y from decoded RGB. The RGB round trip clips at saturated edges, and ~83% of the broken form's baseline was chroma leakage.",), sweep=None), 'edge_masked_distinct_colours': MetricSpec(key='edge_masked_distinct_colours', family='A', unit='count', optimum=Optimum(kind='guard', expect=None, note="A guard, not a dial, for the exact reason Wave 2 deleted the ONE-SIDED \`edge_distinct_colours\`: a 3x3 blur raised that 9.2x and +/-3-LSB noise 55x, and BOTH degradations read as 'AA restored'. What the mask buys is narrower than an#55 assumed, and the difference was MEASURED before this row shipped: an INTERIOR-ONLY change cannot reach the number, but a whole-frame blur can, because the mask is recomputed from the frame being measured and a blur widens the edge band. 3x3 box blur on the six committed goldens, ratio against k=1, whole-frame vs edge-masked: aa_probe 10.25x/9.50x, graded_field 2.04x/2.35x, multi_shot 7.92x/4.63x, promote_demo 1.25x/0.83x, saturated_outline 1.49x/1.14x, single_character 8.60x/5.70x — damped on four of six, WORSE on one, blind on none. So the metric that separates a blur from a supersample is \`edge_transition_width\` (2.1x-3.4x under the same blur against +2.6% to +8.0% under an exact k=2 resolve), and this row is the second half of that reading, not the first. \*\*The pair is evidence for a human reader and NOT a gate\*\* — an#41's criterion counts metrics independently and cannot express a conjunction, so nothing here may be read as one. No figure for THIS metric under a lever exists yet, which is why \`reference\` is unset rather than borrowed from \`frame_distinct_colours\` (an#55)."), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='pre-encode, and blind to the encoder BY CONSTRUCTION like every family A row: both the mask and the colours come from the source PNG, which sits upstream of the encoder', reference=None), 'disabled_aa': Prediction(expect='decrease', counts=False, gate=None, reason="the same direction as \`frame_distinct_colours\`, deliberately: for flat cutout art essentially all colour variety lives at edges, so the mask is close to a no-op for the COUNT (wave2 research §1.3 measured the two within 6%). The whole-frame count under the lever on \`aa_probe\` goes 7.6 -> 3.0 at k=1 and 21.7 -> 6.9 at k=2 (wave3 research §5) — those are \`frame_distinct_colours\` numbers, NOT this metric's, and \`reference\` is deliberately left unset until a real row measures THIS one. NOT counted: family A spends its one witness on \`edge_transition_width\` and this is the same family. NOT gated either, and the distinction is the one most likely to be flipped by a later reviewer: the mask does move with the lever, but the mask and the number come from the SAME frames, so there is no reference to move. That is what makes \`flat_field_deviation\` further down gated and this one not.", reference=None), 'supersample': Prediction(expect='increase', counts=False, gate=None, reason="MEASURED under the lever before it was declared, on all six scenes, because this metric's whole-frame sibling has a scene-dependent sign and there was no reason to assume the masked one would not. Up on four: \`aa_probe\` +184.6%, \`single_character\` +179.3%, \`multi_shot\` +146.3%, \`graded_field\` +13.6%. Down on the two colour-rich scenes: \`saturated_outline\` -12.0%, \`promote_demo\` -7.6% — where 1x MSAA already emits many one-off blend values and an exact 2x resolve replaces them with fewer, more regular ones, so the picture gets better and the count goes down. \`increase\` is declared because the criterion is evaluated PER SCENE and met on four. NOT counted: family A spends its one witness on \`edge_transition_width\` and this is the same family — read the two together (aa_probe +184.6% colours with +7.4% width is gradation added; the same 3x3 blur that raises this metric 9.5x doubles the width) and the pair separates gradation from softening. It is evidence for a human, never a gate: an#41's criterion counts metrics independently and cannot express a conjunction.", reference='7.58 -> 21.58 on \`aa_probe\`; 422.25 -> 371.75 on \`saturated_outline\`')}, sentence='How many different colours sit ON the edges — the row above, restricted to the edge mask.', role=None, reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=("Its mask is NOT the \`masks.edge\` block the encode-side rows use. That one is ffmpeg's limited-range Y; this one is full-range BT.709 luma from the source RGB, so at the shared threshold of 40 it is the wider mask. The row records it separately as \`masks.render_edge\`, with its own operator.",), sweep=None), 'edge_transition_width': MetricSpec(key='edge_transition_width', family='A', unit='px', optimum=Optimum(kind='interior', expect=None, note='Two-sided: both lost AA and accidental softening (blur, non-integer canvas scale, LINEAR texel filtering) are failures. The absolute value is scene-dependent — a deliberately 3px black outline is legitimately non-flat — so compare deltas on a fixed scene, never absolutes across scenes.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='computed on the pre-encode PNG; the encoder cannot move it', reference=None), 'disabled_aa': Prediction(expect='decrease', counts=True, gate=None, reason="family A's single witness. Holds on five of six corpus scenes; on \`promote_demo\` it moves +0.0001 the OTHER way, because the descriptor path is nearly blind to MSAA (96 differing pixels of 12.4M — an SVG sprite is a pre-rasterised texture, and multisampling applies to WebGL geometry). A \`contrary\` verdict at that magnitude is the lever not reaching the scene, which is why the comparison reports the relative delta beside the direction (an#41).", reference='2.88 -> 2.00 on \`aa_probe\`; 5.6368 -> 5.6369 on \`promote_demo\`'), 'supersample': Prediction(expect='increase', counts=True, gate=None, reason="family A's witness for THIS lever, and scene-dependent by measurement in the exact inverse of \`disabled_aa\`. Holds on the five procedural scenes (\`graded_field\` +8.0%, \`aa_probe\` +7.4%, \`saturated_outline\` +5.2%, \`multi_shot\` +5.1%, \`single_character\` +2.6%) and is \`contrary\` on \`promote_demo\` at -34.8%. That inversion is REAL, not the +0.0001 nothing \`disabled_aa\` produces on the same scene: the SVG sprite rasterises AT 2x instead of being stretched up from a 1x texture, so the descriptor path is the one scene this lever reaches hardest and the AA lever cannot reach at all. The two render levers reach complementary scenes. \`increase\` is declared because the criterion is evaluated PER SCENE and met on at least one — the same shape \`video_stream_bytes\` already carries under \`disabled_aa\`. An increase here is not a regression: the optimum is interior, and this walks TOWARD a measured ceiling (2.5846 \`saturated_outline\`, 2.9167 \`graded_field\`, ~2.452 \`multi_shot\`, ~2.140 \`single_character\`, ~3.503 \`promote_demo\`). \`aa_probe\` has NO ceiling — its diagonals land the block-mean grid differently at every k, so it oscillates +/-5-8% with no settling — and gets no declared target, because a value nobody measured is not a value (research §3a).", reference='2.3685 -> 2.4921 on \`saturated_outline\`; 5.6368 -> 3.6775 on \`promote_demo\`')}, sentence='The average thickness, in pixels, of the fuzzy band between two flat colour areas — under 1 is a jagged staircase, ~1 is clean AA, 3+ means the picture has gone soft.', role=None, reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'encode_flicker_on_held_pixels': MetricSpec(key='encode_flicker_on_held_pixels', family='E', unit='fraction of held px moving >=2', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=True, gate=None, reason="family E's witness — and the least reliable of the four. It is NON-MONOTONE across the CRF ladder on the real corpus (0.000648 / 0.007018 / 0.000985 / 0.000916 / 0.001137 / 0.001685 over crf 18/23/28/33/40/51 on \`single_character\`, peaking at crf23), because at high CRF the whole frame flattens into large uniform skip regions and held pixels stop moving — the same mechanism the \`disabled_aa\` gate below documents. At the crf23 -> crf40 step the lever uses it holds on five of six scenes and inverts on \`single_character\`, so it is kept and not leaned on: C, D and F are monotone across the whole ladder and satisfy the criterion on all six scenes without it (an#41).", reference='0.0113 -> 0.0243 on aa_probe; 0.0070 -> 0.0011 on single_character'), 'disabled_aa': Prediction(expect=None, counts=False, gate='source_hash_differs', reason="excluded from EVERY renderer mutation's witness count: without the source gate, half-res-then-nearest-upscale — the most visible possible flat-art regression — reports a 7.1x IMPROVEMENT, because a flattened render gives x264 large uniform skip regions.", reference=None), 'supersample': Prediction(expect=None, counts=False, gate='source_hash_differs', reason="'excluded from EVERY renderer mutation's witness count' is what the declaration beside \`disabled_aa\` says, and this is the second renderer mutation it was written for. Worth restating because THIS lever is the exact shape of the failure that gate exists for: without it, half-res-then-nearest-upscale — the most visible possible flat-art regression — reports a 7.1x improvement, because a flattened render gives x264 large uniform skip regions. A block-mean resolve flattens the source in the same direction, so ungated this metric would reward the improvement for the identical wrong reason and nobody could tell the two apart.", reference=None)}, sentence='The fraction of pixels the animator held perfectly still that moved by at least 2 code values in the delivered video.', role=None, reference='lossless', provisional=False, unreviewed=False, tripwire=False, requires='', notes=("The panel's other hard-threshold counter, so its row carries the count at every tol of \`metrics.FLICKER_DELTA_TOL_SWEEP\` and \`an bench-compare\` reports a direction that grid disagrees with as \`unstable\` (an#140). Measured: under \`high_crf\` \`graded_field\` reads -9% at tol 1 and +29% at tol 2; under 4:2:0 -> 4:4:4 \`single_character\` reads +25% at tol 2 and -15% at tol 3.",), sweep=Sweep(grid=(('tol', (1, 2, 3, 4)),), shipped=(('tol', 2),))), 'encode_ringing_excess': MetricSpec(key='encode_ringing_excess', family='G', unit='code values', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=False, gate=None, reason='provisional; kept out of the witness count until open question 4 is settled', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='source_hash_differs', reason="declared 'both legs rise together by construction'; measured moving on ALL SIX corpus scenes under the real MSAA lever (an#41). The cancellation is exact only when both legs share a FIXED source, and a renderer mutation moves the source — so what is left is uninterpretable rather than zero.", reference=None), 'supersample': Prediction(expect=None, counts=False, gate='source_hash_differs', reason='the cancellation is exact only when both legs share a FIXED source; this lever moves it. Measured moving on all six scenes under \`disabled_aa\`, and nothing about the sign of the render change makes it hold still.', reference=None)}, sentence='How much more the encoder overshoots around outlines than a mathematically lossless encode of the same frames does.', role=None, reference='source_png', provisional=True, unreviewed=False, tripwire=False, requires='', notes=('Provisional pending a cheap comparison against plain edge-band MAE over the identical mask. \`edge_band_mae\` is recorded beside it so the first ledger row answers that question.',), sweep=None), 'expression_min_pairwise_changed_px': MetricSpec(key='expression_min_pairwise_changed_px', family='B', unit='pixels', optimum=Optimum(kind='guard', expect=None, note="Not a quality dial: larger is not better beyond 'the presets are apart'. It exists so a regression that makes two expressions render alike moves a ledger number instead of waiting for someone to look."), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='computed on the pre-encode PNGs; no encode change can reach it', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate="AA-off moves every edge on every pinned frame, so the count of differing pixels between two frames moves with it in an undeclared direction — measured on the lane: it MOVED under \`supersample\` when first declared \`not_applicable\`. Gated, not predicted: the delta is uninterpretable, not good or bad. Family B's witness is \`min_ssim_win8_vs_golden\`.", reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='same as disabled_aa: an edge-quality lever softens every edge on every pinned frame and the pairwise count moves with it; not a face-solver lever, no declared sign', reason='', reference=None)}, sentence="The smallest number of pixels by which any two of the scene's pinned frames differ in TODAY'S render — on \`expressions\`, the closest pair of presets; a collapse of two emotions onto one face drives it to zero (an#98). On a two-frame scene it is that pair's own change, measured rather than withheld: a render-side row is never null on a real capture.", role='diagnostic', reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=('Measured at the first bless (an#98): 106 px between \`thinking\` and \`skeptical\`, the two asymmetric presets, and 384 px at the far end. \`tests/test_expression_goldens.py\` pins half the minimum on the COMMITTED goldens; this row reports the same quantity on the live render, so the ledger sees it before a re-bless does.',), sweep=None), 'file_bytes': MetricSpec(key='file_bytes', family='F', unit='bytes', optimum=Optimum(kind='guard', expect=None, note='Contaminated by the audio cache: the renderer always emits an AAC track, silent or not. Prefer video_stream_bytes.'), predictions={'high_crf': Prediction(expect='decrease', counts=False, gate=None, reason='', reference=None), 'disabled_aa': Prediction(expect='increase', counts=False, gate=None, reason='companion to \`video_stream_bytes\`, SCENE-DEPENDENT in the same way, and additionally contaminated by the audio track. Measured AA-on -> off across the corpus: +3.6% / -2.7% / +7.0% / -0.0% / +4.0% / -2.9%, so it is \`contrary\` on half of it. Counts nothing; kept only as the companion the sentence above calls it (an#41 review).', reference=None), 'supersample': Prediction(expect='decrease', counts=False, gate=None, reason='companion to \`video_stream_bytes\`, contaminated by the AAC track the renderer always emits, silent or not, and therefore scene-dependent in the same way and then some. MEASURED alongside it rather than assumed to follow: it does follow, on every scene and with the same three-three split — \`single_character\` -5.9%, \`multi_shot\` -4.8%, \`saturated_outline\` -2.4%; up and small on \`promote_demo\` +0.6%, \`aa_probe\` +0.5%, \`graded_field\` +0.4%. Counts nothing — prefer \`video_stream_bytes\`, as its own \`optimum\` note says.', reference=None)}, sentence='The whole mp4 on disk, audio track included.', role='companion', reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'flat_field_deviation': MetricSpec(key='flat_field_deviation', family='D', unit='fraction of flat px with |d|>6', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=True, gate=None, reason="family D's witness; monotone over a 133x span", reference='0.0003 / 0.0005 / 0.0035 / 0.0127 / 0.0399 (crf18->51)'), 'disabled_aa': Prediction(expect=None, counts=False, gate='source_hash_differs', reason="The research measured this flat across a SIMULATED AA matrix and called the orthogonality 'the metric's whole value'. Run against the real MSAA lever it moves on ALL SIX corpus scenes, in both directions (an#41). The mechanism is structural rather than surprising: the flat mask is derived from the SOURCE frames, which this lever changes, so the mask itself moves and the comparison has no fixed reference. That is the definition of gated — uninterpretable, not good or bad — and it is the same gate \`encode_flicker_on_held_pixels\` already carries for every renderer mutation, for the same reason.", reference=None), 'supersample': Prediction(expect=None, counts=False, gate='source_hash_differs', reason='the flat mask is derived from the SOURCE frames, which this lever changes, so the mask itself moves and the comparison has no fixed reference — structurally identical to \`disabled_aa\`, and the DIRECTION of the render change is irrelevant to it. Note the gate is \`source_hash_differs\` and NOT \`reference_moved\`: an#56 describes every C/D/E/G row as \`reference_moved\`, which is right for 5 of the 9 and wrong for this one, \`flat_field_p99_dev\`, \`encode_flicker_on_held_pixels\` and \`encode_ringing_excess\`. The two gates are recorded separately on purpose: one says the reference moved, this one says the MASK moved.', reference=None)}, sentence='Of the pixels the renderer painted inside a large flat colour field, what fraction came back more than 6 code values off.', role=None, reference='lossless', provisional=False, unreviewed=False, tripwire=False, requires='', notes=('Covers the ~90% of the frame no edge metric touches. Banding regressions are invisible without it.', 'A hard-threshold count over a mask eroded by a second free parameter, so its row carries the count at every (dilate_k, tol) of \`metrics.FLAT_DILATE_K_SWEEP\` x \`FLAT_DEV_TOL_SWEEP\`, and \`an bench-compare\` reports a direction the grid disagrees with as \`unstable\` — neither counted nor contrary (an#140). Measured under 4:2:0 -> 4:4:4: 3 of 6 scenes reverse on that grid (\`graded_field\` +84.2% at tol 6, -81.6% at tol 8), and so does \`graded_field\` under \`high_crf\` (tol 5). No scalar replacement was stable on the same grid — mean excess over tol, the threshold-free mean, p99 and p99.9 each reverse on at least one scene — because the two deviation distributions CROSS (16 of 18 scene x k cells): some deviations shrink and others grow, and any scalar then encodes a choice of weighting as a direction.'), sweep=Sweep(grid=(('dilate_k', (1, 3, 5)), ('tol', (4, 5, 6, 7, 8))), shipped=(('dilate_k', 3), ('tol', 6)))), 'flat_field_p99_dev': MetricSpec(key='flat_field_p99_dev', family='D', unit='code values', optimum=Optimum(kind='one_sided', expect='minimize', note=''), predictions={'high_crf': Prediction(expect='increase', counts=False, gate=None, reason='companion to the rate above', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='source_hash_differs', reason='gated for the same structural reason as the rate above: the flat mask moves with the source. Measured moving on one of six scenes and holding on five, which is what a metric with no fixed reference looks like — not evidence of orthogonality (an#41).', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='source_hash_differs', reason='gated for the same structural reason as the rate above: the flat mask moves with the source, under a render lever of either sign.', reference=None)}, sentence='The 99th percentile of the same deviation, in human units.', role='companion', reference='lossless', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'frame_distinct_colours': MetricSpec(key='frame_distinct_colours', family='A', unit='count', optimum=Optimum(kind='guard', expect=None, note='No predicted direction on AA changes. A guard, not a dial.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='pre-encode', reference=None), 'disabled_aa': Prediction(expect='decrease', counts=False, gate=None, reason='do not count it alongside off_palette_pixel_fraction; same family', reference=None), 'supersample': Prediction(expect='increase', counts=False, gate=None, reason="do not count it alongside \`edge_transition_width\`; same family. SCENE-DEPENDENT and measured (research §4): +197% \`single_character\`, +186% \`aa_probe\`, +184% \`multi_shot\`, +10% \`graded_field\` — and DOWN 18% on \`saturated_outline\` and 23% on \`promote_demo\`. On a scene that already carries a lot of colour, 1x MSAA emits many one-off blend values and an exact 2x resolve replaces them with fewer, more regular ones: the picture gets BETTER and the count goes DOWN. This is what refutes epic #9's 'edge distinct-colour count materially up on every corpus scene' — the statistic has a scene-dependent sign, which is not a magnitude problem and cannot be fixed by rendering harder. (The metric that done-when literally names, \`edge_distinct_colours\`, does not exist: refuted and deleted in Wave 2.) Read as a PAIR with \`edge_transition_width\` — colours up + width up slightly = gradation added; colours +3600% + width +45% = lanczos ringing; colours down + width down = sharpened. an#41's criterion counts metrics INDEPENDENTLY and cannot express that conjunction, so the pair is evidence for a human reader and is NOT a gate.", reference='7.6 -> 21.7 on \`aa_probe\`; 478.2 -> 392.3 on \`saturated_outline\`')}, sentence='How many different colours are in the frame at all.', role=None, reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'min_ssim_win8_vs_golden': MetricSpec(key='min_ssim_win8_vs_golden', family='B', unit='ssim', optimum=Optimum(kind='one_sided', expect='maximize', note='SIGN AMBIGUITY, recorded deliberately: a supersampling IMPROVEMENT moves this away from 1.0 exactly as an AA regression does, and in changed-pixel terms reports the improvement as the LARGER change. It is a change detector, and must be paired with the no-reference family to say whether a change was good.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='the golden corpus is UPSTREAM of the encoder; no encode change can reach it', reference=None), 'disabled_aa': Prediction(expect='decrease', counts=True, gate=None, reason="family B's single witness. \`golden_identity\` is the tripwire beside it and counts ZERO — one family, at most one witness, and a boolean change detector is not it.", reference='0.9999 -> 0.279 at 1080p / 0.063 at native for a total eye-blink'), 'supersample': Prediction(expect='decrease', counts=True, gate=None, reason="family B's single witness, and THIS lever is what the SIGN AMBIGUITY note above was written about: a supersampling IMPROVEMENT moves this away from 1.0 exactly as an AA regression does, and reports the improvement as the LARGER change. It counts as evidence the render CHANGED, which is what family B measures; it is NOT evidence the change was good, and the note beside \`optimum\` is the standing disclaimer that must be read with it. Fires on all six scenes: the committed baseline is 1.0 on every one, and research §2/§4 measured a real pixel move on every one — including \`promote_demo\`, which \`disabled_aa\` cannot reach at all. The magnitude is the lever's own, from the exam run recorded in the an#56 PR body — not a figure lifted from a research table, which is the an#41-review defect this panel already caught once.", reference="1.0 -> 0.4380 on \`single_character\`, 0.4449 on \`promote_demo\`, 0.6144 on \`saturated_outline\`, 0.7756 on \`aa_probe\`, 0.7969 on \`multi_shot\`, 0.8201 on \`graded_field\` — every scene, because every scene's pixels move")}, sentence='The worst small window in the frame, scored against the committed golden — magnitude AND location of a golden failure.', role='diagnostic', reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=('The metrics survey concluded SSIM should be excluded because whole-frame SSIM scores a total eye-blink at 0.9989. That was REFUTED: only the global-moment reduction is blind. Killing SSIM outright would have discarded the best numpy-only detector available.',), sweep=None), 'off_palette_pixel_fraction': MetricSpec(key='off_palette_pixel_fraction', family='A', unit='fraction', optimum=Optimum(kind='one_sided', expect='minimize', note='Honest caveat: a blur, drop shadow, gradient or sub-pixel offset moves this UP, indistinguishably from better AA. It is a change detector on that axis. Its floor is scene-dependent and is NOT zero on the SVG-sprite path.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason="pre-encode. NOT MEASURED — which is not the same as 'no change'", reference=None), 'disabled_aa': Prediction(expect='decrease', counts=False, gate=None, reason='family A already supplies edge_transition_width as its witness', reference=None), 'supersample': Prediction(expect='increase', counts=False, gate=None, reason="family A already supplies \`edge_transition_width\` as its witness — count at most one per family. \`increase\` and NOT \`not_applicable\`: this is a render lever and the metric is render-side, so \`not_applicable\` would make every scene report \`unexpected_movement\` for a metric doing exactly what it should. An exact block-mean resolve replaces hard edge pixels with blends, and a blend is off-palette by definition. MEASURED on the corpus and scene-dependent, like everything else this lever touches: \`single_character\` +28.9%, \`multi_shot\` +24.2%, \`aa_probe\` +21.8%, \`graded_field\` +0.0%; contrary on the two scenes whose k=1 frames are already the most off-palette, \`promote_demo\` -22.8% and \`saturated_outline\` -9.9%, where an exact resolve REPLACES many one-off MSAA blends with fewer, more regular ones. It counts nothing either way. And the optimum says \`minimize\` while this improvement moves it UP, which is the metric's own caveat stated in its \`note\`: on this axis it is a change detector, not a quality dial.", reference=None)}, sentence='The fraction of the frame whose pixels are not exactly one of the colours the compiler declared for this shot.', role=None, reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'ring_band_mae': MetricSpec(key='ring_band_mae', family='G', unit='code values', optimum=Optimum(kind='one_sided', expect='minimize', note="Research §1.8 calls this 'plain edge-band MAE over the identical mask'. Named for the mask it actually uses, because MAE over the EDGE mask is \`coded_luma_edge_error\`'s definition verbatim — measured identical on the first real row — and recording it twice would answer open question 4 with a tautology."), predictions={'high_crf': Prediction(expect='increase', counts=False, gate=None, reason='the comparison arm', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='reference_moved', reason='', reference=None)}, sentence='Plain mean absolute luma error over the RING band — the simpler rival to \`encode_ringing_excess\`, on the same mask and with no second encode.', role='q4_comparator', reference='source_png', provisional=False, unreviewed=False, tripwire=False, requires='', notes=(), sweep=None), 'stage_min_plane_ratio_gap': MetricSpec(key='stage_min_plane_ratio_gap', family='B', unit='ratio', optimum=Optimum(kind='guard', expect=None, note='Not a quality dial: a larger gap is not a better picture, it is a fixture whose depths are further apart. It exists so a regression that flattens the parallax moves a ledger number instead of waiting for someone to look at a GIF.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='computed on the pre-encode PNGs; no encode change can reach it', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate="AA-off changes which pixels carry a plane's exact colour along its edges, so a centroid can shift by a fraction of a pixel and the mask COUNT can change — which the measurement refuses outright as a clipped plane. Gated, not predicted: the outcome is 'the instrument declines', which is neither better nor worse.", reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate="same as disabled_aa: an edge-quality lever moves the exact-colour mask's boundary, and this measurement is defined on exact colours", reason='', reference=None)}, sentence="The smallest gap between any two planes' displacement RATIOS on a panning multiplane stage (an#111). Each plane's centroid displacement is divided by the reference plane's, so a stage that parallaxes gives the declared depths back — on \`stage_pan\`, 0.25 / 1.0 / 2.0 — and a stage that flattened gives every plane 1.0 and this row zero. \`unavailable\`, never zero, for a scene with fewer than two colour-filled planes: a scene with nothing to compare has no ratio, and reporting that as flattened would fire on every other fixture.", role='diagnostic', reference='none', provisional=False, unreviewed=False, tripwire=False, requires='a multiplane stage: two or more colour-filled planes', notes=("The trap this metric is shaped around: today's centre-anchored zoom ALREADY gives unequal per-plane displacements, so 'the planes moved at different rates' is satisfied by a scene with no parallax at all. The JSON half of the measurement probes at scene-space x = 0, where the zoom term cancels exactly; the pixel half cannot (a centroid sits at the plane's own offset), so the \`stage_pan\` fixture holds zoom CONSTANT instead.", 'Ratios are taken against the LARGEST mover, always. The pixel half cannot see a \`depth\`, so a depth-aware reference makes the two halves report different numbers for one stage — measured while this landed: 0.75 against the \`depth == 1\` plane and 0.375 against the largest mover, for the same measurement.', "Measured at the first bless: 0.375, the far/mid gap on depths 0.25 / 1.0 / 2.0 (reported as ratios 0.125 / 0.5 / 1.0). The \`stage_planes_parallaxed\` tripwire's floor is half of it, which is the \`expression_min_pairwise_changed_px\` precedent followed literally."), sweep=None), 'stage_planes_parallaxed': MetricSpec(key='stage_planes_parallaxed', family='B', unit='boolean', optimum=Optimum(kind='guard', expect=None, note='A change detector. Counts zero toward any criterion.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='computed on the pre-encode PNGs', reference=None), 'disabled_aa': Prediction(expect=None, counts=False, gate='see stage_min_plane_ratio_gap', reason='', reference=None), 'supersample': Prediction(expect=None, counts=False, gate='see stage_min_plane_ratio_gap', reason='', reference=None)}, sentence='True when the planes moved at DIFFERENT rates — i.e. the stage parallaxed rather than panning as one rigid image. The same measurement as \`stage_min_plane_ratio_gap\`, read as a verdict: a boolean and the number beside it must be the same evidence, or a reader has to reconcile them.', role='tripwire', reference='none', provisional=False, unreviewed=False, tripwire=False, requires='a multiplane stage: two or more colour-filled planes', notes=("There is deliberately NO \`flat_camera\` mutation lever to prove this fires. A compile-time parallax change moves the scene's contract hash, so \`bench-compare\` refuses the row at comparability before any family is examined — the recorded \`step_hz\` verdict, verbatim. The proof belongs in \`an bench-mutants\` as a declared guard mutant.",), sweep=None), 'video_stream_bytes': MetricSpec(key='video_stream_bytes', family='F', unit='bytes', optimum=Optimum(kind='guard', expect=None, note='Not a quality dial in either direction — a cross-check that the metrics read the file they think they do.'), predictions={'high_crf': Prediction(expect='decrease', counts=True, gate=None, reason='free fourth cross-check', reference='x1.18 to x1.77 at crf23 -> crf40; x2.07 across the whole ladder'), 'disabled_aa': Prediction(expect='increase', counts=True, gate=None, reason="hard edges cost more to code. THE WEAKEST of this mutation's three witnesses, the only unreviewed metric in the set — and SCENE-DEPENDENT, measured. It holds where the lever has non-axis-aligned edges to change (aa_probe +6.6%, multi_shot +9.7%, saturated_outline +6.9%) and INVERTS where it does not (single_character -6.1%, graded_field -5.7%, promote_demo -0.1%), because AA-off on axis-aligned art removes intermediate colours and the picture gets CHEAPER instead of harder. So this mutation's criterion is met per scene, on the scenes the lever can reach — which is the measured reason \`aa_probe\` is in the corpus at all (an#38, an#41).", reference='+6.6% / -6.1%, scene-dependent'), 'supersample': Prediction(expect='decrease', counts=True, gate=None, reason="family F's witness, and the ONLY third family available to a render lever: A and B can count, C/D/E/G are all gated because their masks and references derive from the source frames, and F is the one encode-side family whose reference is \`none\` — a property of the encoded file rather than a comparison against a moving source. So an#41's three-family criterion for this lever is A + B + F, forced, with no substitute. MEASURED before it was declared, because two mechanisms fight here and guessing was not available: a block-mean resolve ADDS distinct values at edges (+184-197% on the three colour-poor scenes) and it LOWERS edge frequency, which is cheaper for the DCT. The second wins where there is geometry to smooth. Scene-dependent, the same shape this row already carries under \`disabled_aa\` — and \`decrease\` is declared because that is the sign that holds on the scenes where family A also holds, and because it is the side carrying the magnitude: the three down-moves are -4.0% to -12.2% and the three up-moves are +0.8% to +2.8%.", reference='single_character -12.2%, multi_shot -6.6%, saturated_outline -4.0%; contrary and small on graded_field +2.8%, promote_demo +1.1%, aa_probe +0.8%')}, sentence='How large the encoded video stream is, with the audio track excluded.', role=None, reference='none', provisional=False, unreviewed=True, tripwire=False, requires='', notes=('The one metric in the panel that went through NO adversarial pass.',), sweep=None)}*

The panel. Order is display order; the ledger sorts keys anyway.

### an.bench.registry.MUTATIONS *: [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), ...]* *= ('high_crf', 'disabled_aa', 'supersample')*

an
encoder lever cannot touch a golden-frame metric because the corpus is
UPSTREAM of the encoder, so requiring “>=3 metrics” from a CRF change alone
would fail because of where the corpus sits, not because the instrument is
blind — and that failure would be misdiagnosed as the harness being wrong.

`supersample` is the third and it is the odd one out on purpose: the other
two make the picture worse and it makes the picture BETTER. A panel that has
only ever been shown degradations cannot tell an improvement from a
regression — run as a plain commit-to-commit diff this change reports 2
false regressions and 7 unearned improvements (an#56). Declaring it is how
that gets found before it is believed.

* **Type:**
  The levers an#41 and an#56 use. At least one per SIDE is mandatory

### *class* an.bench.registry.MetricSpec(key, family, unit, optimum, predictions, sentence, role=None, reference='none', provisional=False, unreviewed=False, tripwire=False, requires='', notes=<factory>, sweep=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

One row of the panel.

#### requires *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

What a scene must HAVE for this row to exist at all, or `""` when the
row applies to every scene (an#111).

The render-side panel rule is “nothing may be null on a real capture,
because a null render-side row is a blind panel”. That rule assumes
every metric could have been measured. `stage_min_plane_ratio_gap`
could not: a displacement ratio needs two planes moving at different
depths, and `single_character` has no planes at all — so its null is
structural, not a gap in the instrument.

Declared rather than hardcoded in the test, so the panel rule keeps
naming its own exceptions instead of a test file carrying a list the
registry does not know about.

#### sweep *: [Sweep](#an.bench.registry.Sweep) | [None](https://docs.python.org/3/builtins/constants.html#None)*

Set only on a hard-threshold counter (an#140); see [`Sweep`](#an.bench.registry.Sweep).

### *class* an.bench.registry.Optimum(kind, expect=None, note='')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Which way “better” points, and whether the optimum is interior.

### *class* an.bench.registry.Prediction(expect, counts=False, gate=None, reason='', reference=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

What one metric is expected to do under one mutation, declared in advance.

`expect=None` means **gated**: the number is uninterpretable rather than
good or bad, and `gate` says why. It is not “no change”.

### an.bench.registry.REFERENCE_NOTE *: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [str](https://docs.python.org/3/builtins/stdtypes.html#str)]* *= {'lossless': 'the decode of a -qp 0 encode — the plane libx264 received', 'none': 'a property of the encoded file, not a comparison', 'source_png': 'an explicit RGB->YUV conversion of the pre-encode PNGs'}*

What an encode-side metric is measured AGAINST. Two answers, and the choice
is per metric rather than global:

- `lossless` — the decode of a `-qp 0` encode of the same frames. That IS
  the plane libx264 received, on any build, so the metric is pure quantiser
  damage with no colour-conversion term. The default, and what every
  counting encode-side metric uses.
- `source_png` — an explicit RGB->YUV conversion of the pre-encode PNGs.
  Required by exactly two things. The chroma metric’s subject IS the 4:2:0
  subsampling that happens during that conversion – the term the lossless
  leg cancels, so a lossless-referenced version is blind to it (it does NOT
  read ~0; measured, it reads 1.7-2.5 against this metric’s 2.9-9.3, because
  it measures chroma quantiser damage instead – an#72). And `encode_ringing_excess`
  cancels a term that only exists when BOTH its legs share this reference —
  against the lossless leg it degenerates to raw overshoot, which is the
  refuted form.

The distinction became visible when CI measured the PNG conversion to be
build-dependent (exact on ffmpeg 8.1, mean 0.63 / max 5 on the Linux
runner’s older build). It is recorded per metric so a reader can tell which
numbers carry that term.

### an.bench.registry.REFUSED_LEVERS *: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [str](https://docs.python.org/3/builtins/stdtypes.html#str)]* *= {'flat_camera': 'a compile-time change to the plane-compensation channels, refused at comparability for the same reason as \`step_hz\`; the parallax claim is carried render-side by \`stage_min_plane_ratio_gap\` (an#111).', 'pix_fmt': "4:2:0 -> 4:4:4 at fixed CRF fails its own exam on the machine it was designed on, not only on Linux (an#72). Re-measured 2026-09-30 on macOS/arm64, ffmpeg 9.0.1, lossless leg tracking the delivered format (an#138) and with an#140's robustness gate: the three-family criterion is met on 1 of 10 scenes (\`dialogue\`); the pre-an#138 'four scenes' was taken against a contaminated reference. Three reasons, each measured: (1) the lever is not one variable — at fixed CRF 4:4:4 encodes at a coarser quantiser (I-frame Avg QP +2.9 to +9.5) and spends fewer bits, so every encode-side direction is the sum of two opposed effects; (2) family D cannot carry it — the flat-field deviation distributions CROSS (16 of 18 scene x dilate cells on the six lever scenes), so its direction is \`unstable\` over its own tol/dilate grid on 5 of 10 scenes; (3) family E's held mask is derived from the lossless leg, which moves with the format (0.02-2.65% of held pixels), so E has no fixed mask under this lever. The one witness whose subject IS chroma, \`chroma_edge_dCr\`, references \`source_png\` and may not count. The knob ships (\`an render --pix-fmt\`); a QUANTISER-matched lever is the route the evidence leaves open.", 'step_hz': 'moves \`scene_contract_sha256\` on every scene with a tween, so \`bench-compare\` refuses the row before any family is examined; the instrument is per-frame and stepping is a temporal choice (an#89).'}*

Levers that were TRIED and refused, each with the measured reason — data, so
`an bench --mutation <name>` answers with the reason instead of “unknown”,
and the next person meets the measurement before re-registering one. Never
pulled, never predicted for; disjoint from `MUTATIONS` by test.

### *exception* an.bench.registry.RegistryError

Bases: [`ValueError`](https://docs.python.org/3/builtins/exceptions.html#ValueError)

A metric declaration violates one of the table’s invariants.

### *class* an.bench.registry.Sweep(grid, shipped)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

The grid of a threshold counter’s OWN free parameters its verdict is checked on.

Declared rather than merely written by `run.py`, so a row says a metric
SHOULD carry a sweep: a sweep deleted from a row is then refused by
`an bench-compare` instead of silently reading as “never had one” (an#140).
`shipped` names the cell that IS the metric’s value.

### an.bench.registry.TRIPWIRES *: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [MetricSpec](#an.bench.registry.MetricSpec)]* *= {'golden_identity': MetricSpec(key='golden_identity', family='B', unit='boolean', optimum=Optimum(kind='guard', expect=None, note='Full-frame, never edge-masked.'), predictions={'high_crf': Prediction(expect='not_applicable', counts=False, gate=None, reason='the corpus is UPSTREAM of the encoder; no encode change can reach it', reference=None), 'disabled_aa': Prediction(expect='decrease', counts=False, gate=None, reason='it FAILS — a change detector firing, not a quality measurement, which is why it counts ZERO. Spelled \`decrease\` (True -> False) rather than \`no_change\`: the prediction was \`no_change\` while this very sentence said it fails, so the row reported \`unexpected_movement\` on every scene for a tripwire doing exactly its job. Found by \`an bench-compare\` (an#41).', reference=None), 'supersample': Prediction(expect='decrease', counts=False, gate=None, reason='it FAILS — \`True -> False\` — on all six scenes, because a block-mean resolve changes pixels on all six and the committed baseline is \`True\` on all six. A change detector firing, not a quality measurement, which is why it counts ZERO — and under THIS lever that distinction is the whole point: the tripwire fires identically for an improvement and for a regression, so it can never be the evidence that a supersample was worth shipping. Spelled \`decrease\` rather than \`no_change\` for the reason recorded beside \`disabled_aa\`.', reference=None)}, sentence="Today's frame is pixel-for-pixel the committed golden frame.", role=None, reference='none', provisional=False, unreviewed=False, tripwire=True, requires='', notes=('Compare sha256 of DECODED pixels, never file bytes: Chromium 1187 -> 1223 changes 144/144 PNG files and zero pixels.',), sweep=None)}*

Tripwires. A separate block from `METRICS` because they count ZERO toward
any criterion — they fire on improvements and regressions alike.

### *class* an.bench.registry.Touch(path, differs_only_in=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

One environment key a lever is expected to change, and HOW.

`differs_only_in` names the argv flags whose values the lever may move.
Without it the exemption is by PATH, and `x264_argv` is the whole encode
command — so a `-preset medium` -> `-preset veryslow` change, which moves
every encode-side number, rode in on the CRF lever’s exemption and was
reported as “the lever moved it — expected” (an#41 review). `None` means
any difference is the lever’s, which is right for an opaque digest.

#### is_the_levers_change(before, after)

True when the observed difference is the one this lever makes.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)
