- commit
- 0d18c4ad62fe99e821eda64cadc715c45cf43d7c
- parent
- 323b79a3ad90a40d6734b0e522a66b5d5b482d1e
- author
- Dami <dami.etoile@gmail.com>
@@ -0,0 +1,60 @@
1+## Context2+3+The engine treats core properties and each level's `automata[].property` as semantic predicates. Every other predicate becomes a noun transform. The loader validates token syntax but has no author warning for a property typo, allows an object noun to equal a custom property, and preserves unknown `manifest.features` silently. Local CommonJS and data-only shared packs both use `validateMod`; pack-service previews currently expose only errors.4+5+Clockwork needs diagnostics without changing turn semantics. Existing `#pack` v1 links and the shipped automata example omit feature declarations, so the new host must continue accepting them.6+7+## Goals / Non-Goals8+9+**Goals:**10+11+- Distinguish unsupported property intent from a legitimate noun transform during authoring.12+- Reject known semantic property/noun collisions and unknown required features before a pack is installed.13+- Return bounded nonfatal warnings in the same preview envelope for local and shared packs.14+- Preserve existing v1 links, authored automata data, and the `manifest.engine: 1` contract.15+16+**Non-Goals:**17+18+- Executing custom property callbacks, `pairs`, or any new engine effect.19+- Inferring every sentence players might form by moving words; this pass inspects authored sentence positions.20+- Treating a presentation glossary alone as proof that the engine implements a property.21+- A visual layout decision for Gift/Workshop; that remains with design.22+23+## Decisions24+25+### Use one normalized diagnostic pass after validation26+27+Keep `validateMod()` as the existing error-array API. Add a pure diagnostic function that takes validated, normalized pack data and returns a bounded list of warning records with rule/word source context. It uses the engine's rule parser for authored horizontal, vertical, stacked, and `AND` sentences so the warning logic does not invent a second grammar. Warnings are nonfatal because a new noun transform is legal.28+29+The known noun set is pack-wide: placed object nouns, palette keys, and declared vocabulary. The semantic property set is core properties plus implemented level declarations such as `automata[].property`. A glossary entry without a matching implemented declaration does not suppress a warning. A warning is emitted when a parsed predicate belongs to neither set. Diagnostics are stable and de-duplicated by level and predicate source word, with a cap for hostile or oversized packs.30+31+### Enforce custom property/object collisions at the level boundary32+33+Before validating level objects, collect that level's implemented custom property tokens. An object whose noun equals one of them is invalid, just as a core-property noun is invalid today. The engine's direct `createGame()` validator receives the same check so local modules and direct engine callers agree. This does not reserve an automaton property in unrelated levels where it has not been declared.34+35+### Treat feature flags as explicit minimum requirements36+37+`manifest.features` is an optional array of unique lowercase feature IDs. The current host recognizes `automata`; an unknown ID is a blocking validation error with player-readable upgrade guidance. A valid pack with `automata` data and no feature array remains supported so old v1 links and current examples keep working. New authored packs should declare `automata` explicitly. A future feature that needs old hosts to reject it must also change the engine schema version, because old hosts ignore unknown manifest fields; flags alone cannot retroactively protect them.38+39+### Keep warnings out of authored and shared data40+41+Local import and shared decode both run the diagnostic pass and return `warnings: [{ message, detail, levelId? }]` in their pack-service preview envelopes. Successful results retain `errors: []`. Warnings are not serialized into CommonJS exports, share URLs, installed pack records, or engine snapshots. The application passes the warning records to Gift/Workshop for design-owned presentation; a warning never silently becomes an error.42+43+## Risks / Trade-offs44+45+- [Risk] A property typo in a sentence formed only during play is absent from authored positions. → Warn on initially formed predicates now; the future editor can run the same diagnostic after each edit.46+- [Risk] Pack-wide noun recognition can mask a typo that matches a noun in another proof. → Preserve the pack-wide vocabulary contract and report source location for each warning; consider level-local vocabulary later.47+- [Risk] Feature flags do not protect old deployed code. → Preserve v1 compatibility here and require a future engine version bump for a new unsupported mechanic.48+- [Risk] Warning rendering can crowd the Gift card. → Keep service records independent of layout and request a design placement before shipping player presentation.49+50+## Migration Plan51+52+1. Add diagnostics and validation fixtures at the loader and direct-engine boundaries.53+2. Expose warnings in pack-service local/share previews and add a minimal readable status path.54+3. Verify old v1 automata links still import; confirm unknown features fail before installation.55+4. Hand warning placement to design for review, then run browser and sharing acceptance.56+57+## Open Questions58+59+- Design's placement of warning summary and proof/word details in Gift and Workshop.60+- Whether the world team wants new Clockwork exports to declare `features: ['automata']` immediately; the host accepts both forms.@@ -0,0 +1,28 @@
1+## Why2+3+A misspelled or unsupported property word can silently become a noun transformation. Clockwork's `DOOR IS SHUT` example turns doors into unglyphed SHUT objects when the host does not implement SHUT. Authors need a clear diagnostic, and packs need a way to declare mechanics that a host must recognize before play.4+5+## What Changes6+7+- Report nonfatal author warnings when an authored sentence uses a predicate that is neither a supported property nor a known noun in the pack.8+- Reject object nouns that collide with a level's declared property words.9+- Validate optional `manifest.features` identifiers and reject unknown required features with player-readable feedback.10+- Carry warnings separately from errors through local and shared pack previews without serializing transient diagnostics into exported pack data.11+- Preserve existing supported `#pack` v1 links and CommonJS packs while introducing the feature contract.12+13+## Capabilities14+15+### New Capabilities16+17+None.18+19+### Modified Capabilities20+21+- `commonjs-mods`: validate declared mechanic features and property/noun collisions; diagnose unknown predicates.22+- `level-sharing`: apply the same feature gate to decoded data and return nonfatal warnings in preview envelopes.23+24+## Impact25+26+- `src/mods.js`, the CommonJS and data-only validators, and pack-service result envelopes.27+- Gift/Workshop warning presentation, coordinated through the design inbox.28+- Clockwork authoring and compatibility fixtures; no change to engine turn semantics.@@ -0,0 +1,28 @@
1+## ADDED Requirements2+3+### Requirement: Pack validation SHALL distinguish unknown rule words from unsupported mechanics4+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. For each initially formed sentence whose predicate is neither an implemented property nor a noun known from the pack's objects, palette, or vocabulary, the loader SHALL report a nonfatal warning with proof and word context. Existing packs with automata and no feature list SHALL remain valid.5+6+#### Scenario: Unknown predicate receives a warning7+- **WHEN** a pack contains `DOOR IS SHUT` with `SHUT` absent from its implemented properties and known nouns8+- **THEN** local preview succeeds, reports a warning identifying `SHUT` and the proof, and does not transform the warning into a blocking validation error9+10+#### Scenario: Known noun transformation remains valid11+- **WHEN** a pack contains `ROCK IS MIAU` and `MIAU` is declared by an object, palette entry, or vocabulary entry12+- **THEN** no unknown-predicate warning is returned for `MIAU`13+14+#### Scenario: Declared automaton property remains semantic15+- **WHEN** a level declares `TICK` through `automata[].property` and contains `MOUSE IS TICK`16+- **THEN** no unknown-predicate warning is returned for `TICK`17+18+#### Scenario: Property noun collision is rejected19+- **WHEN** a level declares `TICK` as an automaton property and places an object whose noun is `TICK`20+- **THEN** the loader rejects the level with the object's path and does not register part of the pack21+22+#### Scenario: Unsupported feature is rejected23+- **WHEN** a pack declares `manifest.features: ['pairs']` in a host that supports only `automata`24+- **THEN** the loader rejects the pack with a readable newer-version message before any level is installed25+26+#### Scenario: Legacy automata pack remains usable27+- **WHEN** a valid existing pack contains automata but omits `manifest.features`28+- **THEN** the current loader accepts it and preserves its automata behavior@@ -0,0 +1,16 @@
1+## ADDED Requirements2+3+### Requirement: Pack previews SHALL expose nonfatal rule warnings without serializing them4+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 player-language messages, raw details, and optional level IDs. 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.5+6+#### Scenario: Local and shared preview agree on warnings7+- **WHEN** the same valid pack with an initially formed unknown predicate is previewed from a local module and a shared link8+- **THEN** both previews succeed and expose the same warning context without installing the pack9+10+#### Scenario: Diagnostics stay outside portable data11+- **WHEN** a warned pack is exported as CommonJS or encoded into a share URL and decoded again12+- **THEN** the authored data remains valid, the warning is recomputed on preview, and no transient diagnostic field appears in the exported data13+14+#### Scenario: Unsupported shared feature fails before Gift installation15+- **WHEN** a shared payload declares a feature unsupported by the current host16+- **THEN** the decoder returns a player-readable error and Gift cannot install partial content@@ -0,0 +1,16 @@
1+## 1. Validation contract2+3+- [ ] 1.1 Add loader and direct-engine fixtures for a custom property/object noun collision, known transforms, known automaton predicates, and unknown predicate warnings.4+- [ ] 1.2 Validate optional unique `manifest.features` and reject unsupported identifiers with readable upgrade guidance while preserving legacy automata packs.5+- [ ] 1.3 Implement a pure, bounded warning pass using normalized authored sentences and pack-known noun/property sets.6+7+## 2. Preview and sharing8+9+- [ ] 2.1 Return warning records separately from errors in local and shared pack-service preview envelopes.10+- [ ] 2.2 Keep diagnostics out of installed data, CommonJS exports, and share payloads; verify v1 automata links remain usable.11+- [ ] 2.3 Coordinate Gift/Workshop warning placement with design and add a readable player-facing warning path.12+13+## 3. Verification and release14+15+- [ ] 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.