- commit
- 308c2d4e65c990aeab5843f19aee97dd5f352a0a
- parent
- ffac560c01710c33893036b274873ae0d393dc0d
- author
- Dami <dami.etoile@gmail.com>
| M | docs/ | 5 | +++-- |
| M | openspec/ | 15 | ++++++++++++++ |
| M | openspec/ | 32 | ++++++++++++++++++++---------- |
@@ -164,8 +164,9 @@ object fields and falsey explicit kinds so normalization cannot silently drop
164164 authored data. Catalog and Gift preview metadata cross a separate165165 `playableLevelFromView()` adapter before game creation. The full 388-test Node166166 suite, production build, D20 world-index browser flow, and Gift/Workshop/share167-browser flow pass without page errors; the sequential world solver is the168-remaining release gate.167+browser flow pass without page errors. The sequential world solver also solved168+all 30 Core, Crossword, Crate Works, Tidewater, and Clockwork proofs with no169+issues or warnings.169170 170171 The next bounded implementation is the accepted declarative mechanic171172 foundation. Its registry must distinguish derived projections from truly@@ -111,3 +111,18 @@ is not mutated and that malformed data fails before catalog installation.
111111 before it is removed?112112 - Which profile should own limits for mechanic metadata once gates and113113 one-step tiles become authored content?114+115+## Boundary inventory and implementation evidence116+117+| Input | Authored fields and policy | Adapter |118+| --- | --- | --- |119+| Direct engine | Board size, objects, optional ID/title/hint/lesson metadata and automata; no pack ID or pack size cap | `createGame()` uses the standalone profile and preserves issue code/path on level-labeled errors. |120+| CommonJS pack | The same level structure, plus required stable local level ID, 128×128 board, 4096 objects, 32 automata, 64-character title, and 1–64 levels per pack | `loadMod()` retains `ModValidationError` and source context; normalized levels contain explicit kinds/actions. |121+| Data-only share/export | The pack profile plus the existing payload and schema revision limits | `encodeSharedPack()`, `decodeSharedPack()`, and `exportCommonJS()` revalidate canonical data without executing shared code. |122+| Catalog and Gift views | Catalog identity, origin, palette, and preview fields are host metadata | `playableLevelFromView()` removes known view fields before `createGame()`; unknown authored fields still fail schema validation. |123+| Solver | Level gameplay data and authoritative object/automaton state | `checkLevel()` uses the normalized engine path; no presentation or catalog metadata enters the state key. |124+125+`mechanics`, object `channel`, and object `leaves` remain intentionally126+unsupported until the declarative mechanic-state, gate, and FRAIL changes add127+their schema and state contracts. The boundary reports them as128+`unsupported-field` instead of losing them during normalization.@@ -1,32 +1,42 @@
11 ## 1. Canonical boundary22 3-- [ ] 1.1 Inventory current direct engine, CommonJS, share, catalog, and solver3+- [x] 1.1 Inventory current direct engine, CommonJS, share, catalog, and solver44 level fields and write the canonical normalization API and context profiles.5-- [ ] 1.2 Add a pure level schema module with cloned canonical output, stable5+- [x] 1.2 Add a pure level schema module with cloned canonical output, stable66 issue codes/paths, explicit object kinds, uppercase tokens, and explicit77 automaton actions.8-- [ ] 1.3 Preserve and test the documented legacy shorthand as input-only;8+- [x] 1.3 Preserve and test the documented legacy shorthand as input-only;99 ensure export and shared encoding emit canonical action objects.10-- [ ] 1.4 Keep pack-only identity, count, and size limits as explicit profile10+- [x] 1.4 Keep pack-only identity, count, and size limits as explicit profile1111 adapters around the shared structural validator.1212 1313 ## 2. Integrations1414 15-- [ ] 2.1 Route `createGame()` through the canonical boundary while preserving15+- [x] 2.1 Route `createGame()` through the canonical boundary while preserving1616 its current level-labeled error types and standalone fixtures.17-- [ ] 2.2 Route CommonJS validation/normalization through the boundary while17+- [x] 2.2 Route CommonJS validation/normalization through the boundary while1818 preserving `ModValidationError`, source context, and atomic registration.19-- [ ] 2.3 Route CommonJS export and data-only share encode/decode through the19+- [x] 2.3 Route CommonJS export and data-only share encode/decode through the2020 canonical boundary and preserve current schema/revision behavior.2121 2222 ## 3. Verification2323 24-- [ ] 3.1 Add parity fixtures for valid data, legacy shorthand, malformed24+- [x] 3.1 Add parity fixtures for valid data, legacy shorthand, malformed2525 coordinates/tokens/actions, duplicate IDs, and source immutability.26-- [ ] 3.2 Add CommonJS and shared round-trip assertions for canonical gameplay26+- [x] 3.2 Add CommonJS and shared round-trip assertions for canonical gameplay2727 data, automata metadata, and first-transition parity.28-- [ ] 3.3 Run focused engine/mod/share tests, full Node tests, production build,28+- [x] 3.3 Run focused engine/mod/share tests, full Node tests, production build,2929 world solver, and browser import/share flows.30-- [ ] 3.4 Run strict OpenSpec validation, document any deferred metadata fields,30+- [x] 3.4 Run strict OpenSpec validation, document any deferred metadata fields,3131 and archive this change only after all adapter and round-trip evidence is3232 complete.33+34+## Verification evidence (2026-09-24)35+36+- `npm test`: 388 passed, 0 failed after the canonical boundary and conflicting-field follow-up.37+- `npm run build`: Vite production build passed, 73 transformed modules.38+- `npm run check:worlds`: 30/30 Core, Crossword, Crate Works, Tidewater, and Clockwork proofs solved with no issues or warnings.39+- Local browser `tests/browser/world-index.mjs`: desktop/mobile, Workshop PLAY, Q/E, and reduced-motion checks passed without page errors.40+- Local browser `tests/browser/share-flow.mjs`: Gift, Workshop, CommonJS import/export, data-only sharing, proof/Win, and mobile checks passed without console errors.41+- `openspec validate consolidate-level-schema-boundary --strict --no-interactive`: valid.42+- Independent read-only release review found no remaining P0/P1 regression. Unknown future `mechanics`, `channel`, and `leaves` fields intentionally fail as `unsupported-field` until their concrete host contracts land.