clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

Refine mod notes for proof-local word meaning

Dami committed a7f1725
commit
a7f17259823610ef61c60bea0526344d79202dc0
parent
6197c58c3ffb8ec29a476fbdba21a20765fbb29e
author
Dami <dami.etoile@gmail.com>
5 files changed, +39 -26
Mopenspec/changes/validate-mod-feature-contract/design.md23++++++++++++-----------
Mopenspec/changes/validate-mod-feature-contract/proposal.md4++--
Mopenspec/changes/validate-mod-feature-contract/specs/commonjs-mods/spec.md24++++++++++++++++++------
Mopenspec/changes/validate-mod-feature-contract/specs/level-sharing/spec.md2+-
Mopenspec/changes/validate-mod-feature-contract/tasks.md12++++++------
M openspec/changes/validate-mod-feature-contract/design.md +12 -11
@@ -8,7 +8,7 @@ Clockwork needs diagnostics without changing turn semantics. Existing `#pack` v1
88 99 **Goals:**1010 11-- Distinguish unsupported property intent from a legitimate noun transform during authoring.11+- Distinguish unsupported property intent from a legitimate noun transform, even before a loose word forms a sentence.1212 - Reject known semantic property/noun collisions and unknown required features before a pack is installed.1313 - Return bounded nonfatal warnings in the same preview envelope for local and shared packs.1414 - Preserve existing v1 links, authored automata data, and the `manifest.engine: 1` contract.
@@ -16,7 +16,7 @@ Clockwork needs diagnostics without changing turn semantics. Existing `#pack` v1
1616 **Non-Goals:**1717 1818 - 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.19+- Predicting every future sentence or blocking legal noun transformations.2020 - Treating a presentation glossary alone as proof that the engine implements a property.2121 - A visual layout decision for Gift/Workshop; that remains with design.2222
@@ -26,7 +26,9 @@ Clockwork needs diagnostics without changing turn semantics. Existing `#pack` v1
2626 2727 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.2828 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.29+The diagnostic scans **every authored word tile**, including loose words. Its known noun set is level-local: placed object nouns and that level's automata subjects. A pack-wide palette supplies glyphs, not evidence that a word is a noun in this proof; pack-wide vocabulary or an object in another proof cannot suppress the note. The semantic property set is core properties plus implemented declarations in this level. A glossary entry without a matching implemented declaration does not suppress a note. If a word names a property implemented elsewhere in the pack but not here, the note specifically says it has no behavior in this proof.30+31+The rule parser still supplies context for already formed sentences. The note records `word`, `levelId`, `levelTitle`, `sentence` (or `null` for a loose word), player-language `message`, and a source-path `detail`. It is de-duplicated by word text and proof, with a cap for hostile or oversized packs. Thus two physical SHUT tiles in one proof produce one note, while a SHUT in another proof receives its own note.3032 3133 ### Enforce custom property/object collisions at the level boundary3234
@@ -38,23 +40,22 @@ Before validating level objects, collect that level's implemented custom propert
3840 3941 ### Keep warnings out of authored and shared data4042 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.43+Local import and shared decode both run the diagnostic pass and return `warnings` 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. Gift shows an amber NOTE line and expandable detail card; Workshop shows an amber notes chip and action, as specified in design D24. A warning never silently becomes an error.4244 4345 ## Risks / Trade-offs4446 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] A future legitimate noun transform can mention a noun not yet placed in the proof. → Keep notes nonfatal and explain the transform consequence; authors can intentionally keep such a note.48+- [Risk] A word may form several different sentences during play. → Report one note for that word and proof, using an authored sentence for context when available.4749 - [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.50+- [Risk] Warning rendering can crowd the Gift card. → Use design's expandable NOTE card with at most five visible lines and a count for the remainder.4951 5052 ## Migration Plan5153 5254 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.55+2. Expose warnings in pack-service local/share previews and render design's Gift and Workshop note affordances.5456 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.57+4. Run browser and sharing acceptance, then ask design to review the warning card.5658 5759 ## Open Questions5860 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.61+None for the initial note contract. The host accepts legacy automata packs without a feature list.
M openspec/changes/validate-mod-feature-contract/proposal.md +2 -2
M openspec/changes/validate-mod-feature-contract/specs/commonjs-mods/spec.md +18 -6
@@ -1,20 +1,32 @@
11 ## ADDED Requirements22 33 ### 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.4+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 word tile whose text is neither a core word, a property implemented in that proof, nor a noun placed or named as an automaton subject in that proof, the loader SHALL report a nonfatal note with word and proof context, whether or not the word currently completes a sentence. A property implemented in another proof SHALL still receive a note if it has no behavior in this one. Existing packs with automata and no feature list SHALL remain valid.55 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 error6+#### Scenario: Unknown predicate receives a note7+- **WHEN** a proof contains `DOOR IS SHUT` with `SHUT` absent from that proof's implemented properties and nouns8+- **THEN** local preview succeeds, reports a note identifying `SHUT`, the proof, and the noun-transform consequence, without blocking installation9+10+#### Scenario: Loose unknown word receives a note11+- **WHEN** a proof places a loose `SHUT` word that can be moved into a sentence but declares no `SHUT` behavior or noun in that proof12+- **THEN** preview reports a note for `SHUT` even before the sentence is formed913 1014 #### 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`15+- **WHEN** a proof contains `ROCK IS MIAU` and places a `MIAU` object in that proof16+- **THEN** no unknown-word note is returned for `MIAU`17+18+#### Scenario: Another proof's noun does not silence a note19+- **WHEN** one proof uses `SHUT` as an object noun and another proof contains the `SHUT` word without a local SHUT noun or behavior20+- **THEN** the second proof receives a note even if the pack palette and vocabulary list SHUT1321 1422 #### Scenario: Declared automaton property remains semantic1523 - **WHEN** a level declares `TICK` through `automata[].property` and contains `MOUSE IS TICK`1624 - **THEN** no unknown-predicate warning is returned for `TICK`1725 26+#### Scenario: Property declared only in another proof receives a note27+- **WHEN** one proof declares `TICK` through automata and another proof contains `CLOCK IS TICK` without a TICK automaton28+- **THEN** the second proof reports that TICK has no behavior there29+1830 #### Scenario: Property noun collision is rejected1931 - **WHEN** a level declares `TICK` as an automaton property and places an object whose noun is `TICK`2032 - **THEN** the loader rejects the level with the object's path and does not register part of the pack
M openspec/changes/validate-mod-feature-contract/specs/level-sharing/spec.md +1 -1
M openspec/changes/validate-mod-feature-contract/tasks.md +6 -6
@@ -1,14 +1,14 @@
11 ## 1. Validation contract22 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.3+- [ ] 1.1 Add loader and direct-engine fixtures for a custom property/object noun collision, known transforms, loose unknown words, level-local nouns, and properties declared only in another proof.4+- [x] 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 over every word tile using proof-local noun/property sets and authored sentence context.66 77 ## 2. Preview and sharing88 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.9+- [x] 2.1 Return warning records separately from errors in local and shared pack-service preview envelopes.10+- [x] 2.2 Keep diagnostics out of installed data, CommonJS exports, and share payloads; verify v1 automata links remain usable.11+- [ ] 2.3 Render the design-approved Gift NOTE summary/details and Workshop notes chip/action, with accessible and copyable diagnostics.1212 1313 ## 3. Verification and release1414