Close the self-learning loop: turn UNVERIFIED candidates into measurements.
`learn.py` will not score an observable that has not survived a change of grid
EXTENT (see learn.EXTENT_TOL). That is the right rule -- refinement at fixed
extent proved nothing, and occupancy proved less -- but on its own it only
*labels* the problem. This script is the other half: it finds the rows the
ledger most wants verified and emits the runs that would verify them.
python verify.py # show what needs verifying, and the commands
python verify.py --run --workers 6
THE ONE INVARIANT THAT MATTERS. `run_ensemble` builds `theta_hash` from every
design column EXCEPT row_id / cond_row_id / matrix / base_idx / param_j /
condition -- and `theta_id` IS included. A verification row must therefore be a
byte-for-byte copy of the original design row with ONLY row_id and cond_row_id
changed. Renumber `theta_id` and the hash changes, the pair never forms, and
the run is silently wasted. This is not hypothetical: the V12/V13/V15 designs
renumber theta_id and so cannot pair with their own parents.