loadMeta returned the parsed JSON verbatim. A valid JSON file that lacked the
last_refresh map made three consumers (isStale, cmdInvalidate, refreshEntity)
throw a TypeError dereferencing meta.last_refresh — the sibling last_attempt was
already guarded, last_refresh wasn't.
Fix in loadMeta:
- Shape-guard: JSON.parse can return null/array/string/number; non-object → fresh meta.
- Normalize ONLY the dereferenced maps (last_refresh, last_attempt).
- Deliberately do NOT default schema_version/endpoint_hash. Leaving them absent
makes schemaVersionMismatch()/endpointSwitched() force a rebuild (missing
identity = mismatch = safe); defaulting them would suppress cache invalidation
and trust a stale file of unknown provenance.
Tests: missing last_refresh no longer throws; null/array/primitive treated as cold;
missing schema_version forces rebuild instead of a trusted warm hit.
Reported by @jbetala7.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>