Why
The catalog already assigns stable ${packId}:${localId} level IDs, but the
application still carries the active proof as a mutable array index while
catalog access repeatedly clones every pack and level. Pack replacement,
removal, progress updates, and win handoff can therefore resolve different
levels after the catalog changes, while ordinary UI refreshes pay a full
catalog clone cost.
What Changes
- Make the canonical active-level identity the existing stable global level ID, while retaining numeric index arguments for compatibility.
- Define catalog read boundaries that resolve one level or the active level by stable ID and invalidate derived views after register, replace, and remove.
- Keep existing public clone and mutation-safety guarantees for
getLevels,getLevel, andgetPack; add focused cache and identity tests before changing callers. - Migrate application handoff, progress marking, level replacement, and pack removal flows to re-resolve by stable ID instead of retaining a stale index.
This change does not alter pack IDs, local level IDs, sharing payloads, save keys, solver state, or level ordering semantics.
Capabilities
New Capabilities
stable-active-level-identity
Modified Capabilities
None.
Impact
src/, src/, and their focused tests will change. Existing
catalog methods remain compatible and continue returning caller-owned data.
The implementation may add internal generation counters or immutable records,
but those details are not exposed in pack or level payloads.