1. Stable content model
- [x] 1.1 Define normalized pack and level records with authored stable lowercase ids, version, origin metadata, ordered levels, vocabulary, and palette; reject generated identity fallbacks.
- [x] 1.2 Assign stable pack and level ids to the three MIAU teaching levels without changing their authored puzzle behavior.
- [x] 1.3 Define and validate the additional curated basic packs and their level ids.
2. Pack registry
- [x] 2.1 Implement atomic registration, active selection, origin tracking, and lookup by
{ packId, levelId }. - [x] 2.2 Retain multiple valid bundled and imported packs and preserve earlier packs after failed registration.
- [x] 2.3 Implement duplicate pack collision rejection and explicit atomic replacement.
- [x] 2.4 Add registry fixtures for same level ids across different packs, duplicate pack ids, unknown selection, and replacement failure.
- [x] 2.5 Add explicit
Keep both as a copyfork handling with suffixed id,forkOf, and fresh progress identity.
3. CommonJS pack compatibility
- [x] 3.1 Adapt the existing validated local CommonJS manifest to include stable level ids and normalized pack identity.
- [x] 3.2 Keep local CJS import explicitly trusted and preserve existing pack content after module errors or unsupported imports.
- [x] 3.3 Add fixtures for loading two valid modules, malformed modules, duplicate pack ids, and palette/vocabulary retention.
4. Data-only sharing and export
- [x] 4.1 Implement canonical authored-pack serialization that excludes current positions, move history, win state, and UI state.
- [x] 4.2 Implement deterministic
.cjsexport and trusted local import round-trip verification. - [x] 4.3 Implement
#pack=<versioned-payload>URL-safe data encoding with a 16 KiB encoded payload cap. - [x] 4.4 Decode and validate hash payloads without invoking CommonJS evaluation, imports, or hooks.
- [x] 4.5 Add fixtures for valid URL round trips, malformed encoding, unknown versions, tampering, oversized payloads, and code-execution isolation.
- [x] 4.6 Define the forward-version policy for the documented v1 share schema: keep v1 decoding compatible, reject unknown future versions before registration, and add adapters/fixtures only when a later schema is documented.
5. Browser integration and feedback
- [x] 5.1 Route bundled pack and level selection through the registry while retaining keyboard/touch movement, dynamic rule changes, and undo behavior.
- [x] 5.2 Add the E4 service hooks:
listPacks,importPackText,exportPack,packLink,decodePackLink,installPack, andremovePack; keep URL intake separate from CJS execution. - [x] 5.3 Normalize preview and installed views, return duplicate
conflictmetadata before installation, and make every player-facing hook return structured no-throw{ok, errors}results with readable messages and raw details. - [x] 5.4 Move URL intake to a pending Gift confirmation and provide Workshop operations for Import, Play, Share link, Export, and Remove; keep interim sidebar controls behind
?dev. - [x] 5.5 Add browser checks for built-in pack startup, level selection, rule editing, undo/reset, multi-pack retention, trusted CJS import, URL import, export, and failure feedback.
6. Verification
- [x] 6.1 Run the full Node test suite and production build with all bundled packs registered.
- [x] 6.2 Verify engine behavior remains deterministic after pack selection and imported level normalization.
- [x] 6.3 Review serialized output for stable ordering and absence of transient engine or UI state.
Stage, scene, and visual layout work for Workshop/Gift remains a separate follow-up change owned by the designer.