#!/usr/bin/env python3 """stamp_gallery.py — bind an existing gallery to the embedder that built it. TRACES: GR-004 | SR-001 Galleries built before model binding carry no embedder stamp. They still load, but every consumer warns that it cannot tell whether the gallery and the embedder belong together — and under SAE_REQUIRE_GALLERY_STAMP=1 they refuse to run. This is the migration path, and the reason the unstamped case is a warning rather than a hard failure: re-binding an existing gallery costs one command and no re-embedding, so nobody has to choose between a bricked setup and a check they route around. python scripts/stamp_gallery.py --gallery gallery.h5 \\ --arcface models/LVFace-B_Glint360K.onnx The stamp is an ASSERTION: you are stating which model produced these vectors. Nothing can verify it from the vectors themselves, which is exactly why the stamp has to be written at build time going forward. Stamping the wrong model is worse than leaving it unstamped, because it converts a loud warning into a false all-clear — so --show it first if you are not certain. python scripts/stamp_gallery.py --gallery gallery.h5 --show """ from __future__ import annotations import argparse import sys from pathlib import Path import h5py sys.path.insert(0, str(Path(__file__).resolve().parent)) from sae_gallery import (describe_stamp, embedder_stamp, # noqa: E402 read_gallery_stamp) def main() -> int: p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) p.add_argument("--gallery", required=True, help="gallery .h5 to stamp in place") p.add_argument("--arcface", help="the ONNX that built it (hashed into the stamp)") p.add_argument("--show", action="store_true", help="print the current stamp and exit") p.add_argument("--force", action="store_true", help="overwrite an existing stamp (refused otherwise)") args = p.parse_args() path = Path(args.gallery) if path.suffix not in (".h5", ".hdf5"): return err(f"{path}: only HDF5 galleries can be stamped in place") current = read_gallery_stamp(path) print(f"{path}: current stamp = {describe_stamp(current)}", file=sys.stderr) if args.show: return 0 if not args.arcface: return err("--arcface is required (or use --show)") if current and not args.force: return err("gallery is already stamped — pass --force to overwrite, but be " "sure: a wrong stamp turns a warning into a false all-clear") stamp = embedder_stamp(args.arcface) if not stamp["model_sha256"]: return err(f"cannot hash {args.arcface} — refusing to write a name-only " "stamp, which would claim more certainty than it has") with h5py.File(path, "r+") as f: if "embedder" in f: del f["embedder"] g = f.create_group("embedder") g.attrs["model_name"] = stamp["model_name"] g.attrs["model_sha256"] = stamp["model_sha256"] g.attrs["embed_dim"] = stamp["embed_dim"] print(f"{path}: stamped with {describe_stamp(stamp)}", file=sys.stderr) return 0 def err(msg: str) -> int: print(f"[stamp_gallery] {msg}", file=sys.stderr) return 1 if __name__ == "__main__": raise SystemExit(main())