Follow-up from #139 (schema-driven FK target resolution, v1.6.2).
Context
v1.6.2 added CommandModel.format_version and made CacheStore.load() reject entries whose version is older than MODEL_FORMAT_VERSION, so a one-time rebuild picks up new model metadata after an upgrade. The online path self-heals immediately: _build_and_cache rebuilds and overwrites the stale file on first invocation.
Defect (bounded, self-healing — not a blocker)
When the only cached entry is format-stale-but-hash-fresh and NetBox is unreachable:
_find_fresh_cached / _find_any_cached reject the stale entry (single load() chokepoint), the fetch fails, and resolution falls to _load_bundled_command_model() — rebuilding from the bundled schema on every invocation (~180ms), because nothing re-saves on the offline branch.
- Tab-completion (
completion/cache_probe.load_cached_model_for_profile) has no rebuild fallback, so it returns nothing for that profile until the first online command rewrites the cache — a brief completion blackout.
No crash, no infinite loop; both self-correct once connectivity returns. Found by adversarial review of #139.
Suggested fix
On the offline _find_any_cached path, when load() rejects an entry purely on format_version (hash + JSON otherwise valid), rebuild from the bundled/cached schema and re-save under the profile so the next invocation hits the fast path. (The cache stores the built model, not the raw schema body, so the cleaner route is to have the offline/bundled branch persist the rebuilt model under the profile.)
Follow-up from #139 (schema-driven FK target resolution, v1.6.2).
Context
v1.6.2 added
CommandModel.format_versionand madeCacheStore.load()reject entries whose version is older thanMODEL_FORMAT_VERSION, so a one-time rebuild picks up new model metadata after an upgrade. The online path self-heals immediately:_build_and_cacherebuilds and overwrites the stale file on first invocation.Defect (bounded, self-healing — not a blocker)
When the only cached entry is format-stale-but-hash-fresh and NetBox is unreachable:
_find_fresh_cached/_find_any_cachedreject the stale entry (singleload()chokepoint), the fetch fails, and resolution falls to_load_bundled_command_model()— rebuilding from the bundled schema on every invocation (~180ms), because nothing re-saves on the offline branch.completion/cache_probe.load_cached_model_for_profile) has no rebuild fallback, so it returns nothing for that profile until the first online command rewrites the cache — a brief completion blackout.No crash, no infinite loop; both self-correct once connectivity returns. Found by adversarial review of #139.
Suggested fix
On the offline
_find_any_cachedpath, whenload()rejects an entry purely onformat_version(hash + JSON otherwise valid), rebuild from the bundled/cached schema and re-save under the profile so the next invocation hits the fast path. (The cache stores the built model, not the raw schema body, so the cleaner route is to have the offline/bundled branch persist the rebuilt model under the profile.)