"""Phase 5: the final weights -> a public model repo with a card that only states measured facts. Everything quoted in the card is read back off the Hub at run time — the mix manifest, `audit.json`, the trainer's `run_summary.json` — rather than retyped from memory, because the card is the artifact a stranger will trust and `final-report.md` will cite (§3.12: the claim and the evidence must be the same object). Gate 5 is not this script: it is `--verify-only` running on a *fresh instance with an empty cache*, which is the only way to prove nothing the model needs lives on a Kaggle disk. This script therefore ends by printing the exact command for that second job. """ import argparse import hashlib import json import os import shutil import struct import sys import urllib.request MIX = "Cion-lab/ounce100m-mix-v1" # A default, not a constant: this run's checkpoint repo, hard-coded as the only source, let the publisher # fetch `latest.json` from a repo the operator never pointed at -- for a second model that is publishing one # run's weights into another run's repo. Override with --ckpt-repo, or bypass it with --from-dir. CKPT = "Cion-lab/ounce100m-ckpt" CARD_FILES = ("config.json", "model.safetensors", "tokenizer.json", "tokenizer_config.json", "special_tokens_map.json", "vocab.json", "merges.txt", "cursor.json", "run_summary.json", "generation_config.json") def sha(p): h = hashlib.sha256() with open(p, "rb") as fh: for c in iter(lambda: fh.read(1 << 20), b""): h.update(c) return h.hexdigest() def safetensors_counts(p): """(n_tensors, n_params, dtypes) straight from the file header — no torch, so this check runs on a CPU box and on any image, and it proves the *published bytes* have the parameter count the card claims.""" with open(p, "rb") as fh: (n,) = struct.unpack("