- commit
- 5b2bcefa35669fac6163b124847a3d54e3cc2d8d
- parent
- 65f109cb6b522250840b2cf4df0b22af1509fb0b
- author
- Dami <dami.etoile@gmail.com>
No content changes.
No content changes.
No content changes.
No content changes.
No content changes.
No content changes.
@@ -13,4 +13,4 @@
1313 ## 3. Verification and release1414 1515 - [x] 3.1 Run Node and browser checks for local import, shared Gift, core play, rule edits, and Undo; verify Clockwork's current pack still loads.16-- [ ] 3.2 Strictly validate and archive OpenSpec, commit in focused units, and update the stable public preview after design review.16+- [x] 3.2 Strictly validate and archive OpenSpec, commit in focused units, and update the stable public preview after design review.@@ -45,3 +45,46 @@ The loader SHALL report a valid module whose pack id is already registered to th
4545 - **WHEN** the player chooses `Keep both as a copy` for a duplicate local module4646 - **THEN** the registered pack receives a suffixed id with `forkOf` provenance and progress is keyed by the new id4747 48+### Requirement: Pack validation SHALL distinguish unknown rule words from unsupported mechanics49+The loader SHALL accept optional `manifest.features` as a list of unique supported feature identifiers and SHALL reject unknown required features before registration with an upgrade message. A level SHALL reject an object noun equal to a custom property implemented by that level. A word SHALL count as a known noun when it is placed or named as an automaton subject in that proof, or listed in the pack's palette or vocabulary. Other words that are neither core words nor implemented properties in that proof SHALL receive a nonfatal note with word and proof context, whether or not they currently complete a sentence. A word declared as a property in one proof and used as an object noun in another SHALL receive an ambiguity note even if it is in the pack palette or vocabulary. Existing packs with automata and no feature list SHALL remain valid.50+51+#### Scenario: Unknown predicate receives a note52+- **WHEN** a proof contains `DOOR IS SHUT` with `SHUT` absent from that proof's implemented properties and nouns53+- **THEN** local preview succeeds, reports a note identifying `SHUT`, the proof, and the noun-transform consequence, without blocking installation54+55+#### Scenario: Loose unknown word receives a note56+- **WHEN** a proof places a loose `SHUT` word that can be moved into a sentence but declares no `SHUT` behavior or noun in that proof57+- **THEN** preview reports a note for `SHUT` even before the sentence is formed58+59+#### Scenario: Known noun transformation remains valid60+- **WHEN** a proof contains `ROCK IS MIAU` and places a `MIAU` object in that proof61+- **THEN** no unknown-word note is returned for `MIAU`62+63+#### Scenario: Pack-defined transformation target is known64+- **WHEN** one proof contains `ROCK IS GEM`, the pack palette or vocabulary defines `GEM`, and no GEM object starts in that proof65+- **THEN** no unknown-word note is returned for `GEM`66+67+#### Scenario: Pack-wide property and thing ambiguity receives a note68+- **WHEN** one proof declares `SHUT` as a custom property and another proof uses `SHUT` as an object noun and places its word69+- **THEN** preview reports a nonfatal ambiguity note for `SHUT` even if the pack palette or vocabulary names it70+71+#### Scenario: Declared automaton property remains semantic72+- **WHEN** a level declares `TICK` through `automata[].property` and contains `MOUSE IS TICK`73+- **THEN** no unknown-predicate warning is returned for `TICK`74+75+#### Scenario: Property declared only in another proof receives a note76+- **WHEN** one proof declares `TICK` through automata and another proof contains `CLOCK IS TICK` without a TICK automaton77+- **THEN** the second proof reports that TICK has no property behavior there unless the pack defines TICK as a noun78+79+#### Scenario: Property noun collision is rejected80+- **WHEN** a level declares `TICK` as an automaton property and places an object whose noun is `TICK`81+- **THEN** the loader rejects the level with the object's path and does not register part of the pack82+83+#### Scenario: Unsupported feature is rejected84+- **WHEN** a pack declares `manifest.features: ['pairs']` in a host that supports only `automata`85+- **THEN** the loader rejects the pack with a readable newer-version message before any level is installed86+87+#### Scenario: Legacy automata pack remains usable88+- **WHEN** a valid existing pack contains automata but omits `manifest.features`89+- **THEN** the current loader accepts it and preserves its automata behavior90+@@ -95,3 +95,18 @@ The app SHALL report success or failure for pack selection, URL copy, URL decode
9595 - **WHEN** the browser denies clipboard access9696 - **THEN** the app reports the failure and exposes the generated URL for manual copying9797 98+### Requirement: Pack previews SHALL expose nonfatal rule warnings without serializing them99+Local CommonJS previews and data-only shared-link previews SHALL apply the same supported-feature and property validation. A successful preview SHALL return a bounded `warnings` collection separate from `errors: []`, with `word`, `levelId`, `levelTitle`, optional `sentence`, a player-language `message`, and technical `detail`. Warnings SHALL not prevent installation and SHALL not be serialized into exported CommonJS source, shared payloads, installed pack data, or engine snapshots. Unknown required features SHALL fail atomically before installation.100+101+#### Scenario: Local and shared preview agree on warnings102+- **WHEN** the same valid pack with an initially formed unknown predicate is previewed from a local module and a shared link103+- **THEN** both previews succeed and expose the same warning context without installing the pack104+105+#### Scenario: Diagnostics stay outside portable data106+- **WHEN** a warned pack is exported as CommonJS or encoded into a share URL and decoded again107+- **THEN** the authored data remains valid, the warning is recomputed on preview, and no transient diagnostic field appears in the exported data108+109+#### Scenario: Unsupported shared feature fails before Gift installation110+- **WHEN** a shared payload declares a feature unsupported by the current host111+- **THEN** the decoder returns a player-readable error and Gift cannot install partial content112+