The json-images job on macos-14 has been hitting timeout-minutes: 30 on
cold cache (runs 25854199999, 25854000503, plus concurrency-cancelled
runs like 25848174628). Two root causes, both addressed here.
1. The HF_HOME cache for gemma-4-E2B-it never lands on macOS.
`gh api repos/unslothai/unsloth/actions/caches` shows a 3344 MB
Windows entry for the same key on main but no macOS entry at all.
The save step was gated on `prime-hf.outcome == 'success'`; when
prime is killed by the job timeout or by `concurrency:
cancel-in-progress`, outcome becomes `cancelled` and the save is
skipped. Cold cache then primes again next run, times out again,
never saves. Self-perpetuating on busy branches.
On top of that, the HF_HOME layout (xet chunks + blobs + snapshots)
inflates ~3.6x off-disk per the job 2 comment, pushing a single
entry close to the 10 GiB per-cache cap.
2. macos-14 NAT egress is slow for multi-GB downloads. The workflow
already calls this out and goes parallel + authenticated, but 3.4
GiB (gemma-4-E2B Q4_K_XL ~2.4 GiB + mmproj-F16 ~986 MiB) still
doesn't reliably fit in 30 min when starting from cold.
Changes
* Job 3 (json-images) switches from HF_HOME to the flat `--local-dir
gguf-cache` pattern that Job 2 already uses. Cache key swaps from
`${runner.os}-hf-${REPO}-${VARIANT}-${MMPROJ}-v1` to
`${runner.os}-gguf-${REPO}-${FILE}-${MMPROJ}-v1`. mmproj is
auto-detected as a sibling of the .gguf in the same dir by
`detect_mmproj_file` in studio/backend/utils/models/model_config.py,
so no API surface change is needed on the inference/load route.
* Load step posts `model_path` as a local file path and drops
`gguf_variant`. With a local file the variant is encoded in the
filename, and passing it would route through
`_find_local_gguf_by_variant` which expects a directory.
* All three jobs' save guards relaxed from
`outcome == 'success'` to `outcome != 'skipped' && hashFiles(...) != ''`.
Cache-hit fast path stays a no-op (restore hit -> download skipped
-> save skipped). On cancel/timeout/failure the save still runs as
long as at least one .gguf landed, so the next run resumes via
hf download's content-hash resume.
* Top-of-file and `workflow_dispatch` comments updated from
"HF_HOME caches" to "model caches" so they remain accurate now that
two of three jobs use flat-file caching.
This builds on the cache hardening already landed in #5396 and #5399.