--- name: hole-hunt description: Run a multi-lens hole hunt (audit) of the dmrgpy Python layer, or add a lens, a finding or a fix cluster to an existing one. Use this whenever the user asks to audit, hole-hunt, hunt for bugs, sweep for holes, cross-check the backends against each other, or look for silently-wrong numbers, and also when they ask to record or fix a finding in docs/audit_*_hole_hunt.md. This is the repository's established audit process, run in 2026-08 and 2026-09, and it has a fixed record shape and a fixed evidence standard that a free-form bug hunt will not reproduce. --- # Hole hunt A hole hunt is a parallel, multi-lens search for behaviour in the dmrgpy Python layer that is *silently* wrong: a number that is plausible and incorrect, a dispatch that answers a question nobody asked, a kwarg with no consumer. The previous hunts are `docs/audit_2026_08_hole_hunt.md` (five lenses, 21 findings), `docs/audit_2026_09_hole_hunt.md` (eight lenses, 36 findings), `docs/audit_2026_09_24_hole_hunt.md` (five lenses, 16 findings), `docs/audit_2026_09_24b_hole_hunt.md` (five lenses, 18 findings) and `docs/audit_2026_09_24c_hole_hunt.md` (four lenses, 18 findings), followed by `docs/audit_2026_09_25_open_items.md`, a fix pass over ten of their open items rather than a hunt, whose "Left open, and new leads" section belongs in the next brief next to every record's "New leads", and by `docs/audit_2026_09_25b_hole_hunt.md` (four lenses, 29 findings) over that fix pass. Read the scope section and the lens table of the most recent one before starting: a finding already recorded there is not a new finding. What makes this process worth following rather than improvising: every claim in the record was *executed*, and every claim was then handed to a second agent whose only brief was to refute it. That is what makes the record trustworthy enough that a later fix does not have to re-derive the evidence. Predicted output, remembered output and output from a stale `.so` all break that, so they are the failure mode to guard against throughout. ## 1. Fix the frame Record, and keep true for the whole hunt: - The commit (`git rev-parse --short HEAD`) and that the tree is clean. - Whether both compiled extensions are current. If a lens will touch C++, rebuild first, because a fix that lands mid-hunt and replaces `_dmrgcpp*.so` invalidates every other lens's measurements. The 2026-09 hunt took its one C++ fix by hand, separately, for exactly this reason. - When the hunt is scoped to one commit, a compiled snapshot of its parent, so every candidate runs on both trees and the record can say whether the commit brought the defect in. `git archive` of the parent without the vendored `ITensor`/`TDVP` folders, those linked back to this checkout's copies (check they are unchanged between the two commits), then `make pybind` in each `mpscppN`: about a minute, and it never touches the repo's own `.so`. The recipe and the two-runner setup are in the 2026-09-25b record's "Shared helpers". - The invocation every repro uses: ```bash MKL_NUM_THREADS=1 OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 NUMEXPR_NUM_THREADS=1 \ PYTHONPATH=/src python3