active-level-identity Specification
Purpose
TBD - created by archiving change stabilize-active-level-identity. Update Purpose after archive.
Requirements
Requirement: The active level SHALL use a stable catalog identity
The application SHALL use the existing ${packId}:${localId} level ID as the
canonical active-level identity. Numeric indexes MAY select a level but SHALL
not be used as the durable identity across catalog mutations.
Scenario: Selection survives unrelated registration
- WHEN the active level is selected and another pack is registered before it
- THEN the same stable active level ID remains selected and resolves to the same level
Scenario: Replacement preserves an existing local level
- WHEN a pack is replaced with the same pack ID and still contains the active local level ID
- THEN the active stable ID is preserved and resolves to the replacement level
Scenario: Replacement removes the active local level
- WHEN a pack replacement omits the active local level
- THEN selection falls back to the replacement pack's first level or the first available catalog level, and no stale ID remains active
Requirement: Catalog reads SHALL preserve clone safety without repeated full clones
Single-level and active-level reads SHALL resolve directly from normalized catalog records. Full-list compatibility methods SHALL continue returning fresh caller-owned data, while internal derived views SHALL be invalidated on pack register, replacement, and removal.
Scenario: A caller cannot mutate a cached catalog record
- WHEN a caller mutates a level returned by a catalog read
- THEN a later read returns the normalized authored value
Scenario: Replacement invalidates level and pack views
- WHEN a pack is replaced with changed metadata or levels
- THEN subsequent reads return only replacement data and no stale cached level, pack, or level count
Scenario: Removal invalidates active and list views
- WHEN an imported pack is removed
- THEN subsequent reads omit its levels and the active ID resolves to a
remaining level or
null
Requirement: Progress and win handoffs SHALL resolve by stable identity
Progress marking, win promotion, continue navigation, and pack refresh SHALL re-resolve the captured stable level ID before acting. A catalog mutation or level transition SHALL not allow an old numeric index or reused authored ID to promote the wrong level.
Scenario: A win callback cannot promote a replaced level
- WHEN a level is won and its pack is replaced before the delayed win handoff runs
- THEN the callback promotes only the still-resolved stable level ID or safely abandons the stale handoff
Scenario: Progress remains attached to pack and local IDs
- WHEN levels are reordered by registration or an unrelated pack changes
- THEN solved progress remains attached to the original
packIdandlocalId
Requirement: Cache invalidation SHALL be observable at mutation boundaries
Catalog mutations SHALL invalidate all derived active-level, pack-summary, and level-lookup views that can contain changed records. The invalidation SHALL occur before the mutation result is returned to application callers.
Scenario: Replace refreshes summaries immediately
- WHEN a pack replacement changes its name, world metadata, or level count
- THEN the next pack and level reads expose replacement summaries without a refresh-only workaround