1# rule-engine Specification23## Purpose4Define deterministic grid state, movable word rules, turn resolution, contact5effects, undo, and the settled event records consumed by presentation.6## Requirements7### Requirement: The engine SHALL represent a deterministic stacked grid state8The engine SHALL represent a level as a bounded rectangular grid containing uniquely identified object and word entities. Multiple entities, including words, SHALL be allowed in one cell, and a turn snapshot SHALL include positions, entity kinds, word text, active rules, move count, win state, and the complete history needed for undo.910#### Scenario: Multiple words share a cell11- **WHEN** two word entities occupy the same coordinate12- **THEN** both remain addressable and rule scanning considers both word texts at that coordinate1314#### Scenario: Invalid movement is rejected15- **WHEN** a caller requests a diagonal move, an out-of-bounds move, or a move after the level is won16- **THEN** the engine leaves state and undo history unchanged1718### Requirement: The engine SHALL derive the MVP rule vocabulary from movable words19The engine SHALL scan horizontal and vertical straight lines for `NOUN IS VALUE` sentences, with adjacent `AND` terms expanding the noun side or value side. The initial semantic properties SHALL be exactly `YOU`, `PUSH`, `STOP`, `WIN`, `SINK`, and `DEFEAT`; a noun-to-noun value SHALL be treated as a transformation. Rules SHALL be recomputed from the current word positions after a turn that changes board state, including after contact effects remove word entities. The settled active rules, physical sentence spans, derived properties, and rule deltas SHALL describe only surviving words before the next player intent.2021#### Scenario: An AND sentence expands to multiple properties22- **WHEN** the board contains `BABA IS YOU AND PUSH` in one straight line23- **THEN** the active rule table contains `BABA IS YOU` and `BABA IS PUSH`2425#### Scenario: A moved word changes the active rules26- **WHEN** a legal move changes the position of a word entity27- **THEN** the engine replaces the active rule table with rules parsed from the new word positions before the next player intent2829#### Scenario: A malformed line is ignored30- **WHEN** a word line lacks `IS` or has no noun and value on both sides31- **THEN** the line produces no active rule and does not make the turn fail3233#### Scenario: SINK removes a rule word34- **WHEN** a turn causes `SINK` to destroy the `STOP` word in `ROCK IS STOP`35- **THEN** the settled state has no `ROCK IS STOP` rule or sentence span, the event reports that rule removed, and the next move onto ROCK is not blocked by `STOP`3637#### Scenario: Contact removal updates derived control and automata38- **WHEN** contact destruction removes a word granting `YOU` or a declared automaton property39- **THEN** the settled state's control and automata carriers reflect the surviving words, and Undo restores the previous derivations4041#### Scenario: A destroyed WIN word cannot grant a final victory42- **WHEN** a contact destroys the word that supplied a surviving entity's `WIN` property43- **THEN** the final victory check uses the surviving rule table and does not mark the level won from the destroyed word4445#### Scenario: Restore a state after rule-word destruction46- **WHEN** a settled snapshot lacking a destroyed rule word is restored or the level is reset47- **THEN** the restored state derives rules from its present words, while reset restores the initial words and their rules4849### Requirement: The engine SHALL resolve controlled movement and pushes atomically50Entities whose noun has `YOU` SHALL receive the requested cardinal intent. A moving entity SHALL push a contiguous chain of `PUSH` entities when every destination is in bounds and free of `STOP` entities; a blocked chain SHALL not move any member. Word entities SHALL be pushable by default so that players can edit rules.5152#### Scenario: A legal push moves the complete chain53- **WHEN** a `YOU` entity moves toward one or more adjacent `PUSH` entities with an empty in-bounds destination54- **THEN** the chain moves one cell in the requested direction and the move count increases by one5556#### Scenario: STOP blocks a push57- **WHEN** a requested movement would push an entity into a `STOP` entity or outside the grid58- **THEN** no entity moves and the move count does not increase5960#### Scenario: Several YOU entities use stable ordering61- **WHEN** more than one `YOU` entity receives the same intent62- **THEN** the engine resolves them in a documented stable order and produces the same state for the same initial state and intent6364### Requirement: The engine SHALL apply transformations and contact effects deterministically65After movement, the engine SHALL apply active noun-to-noun transformations, then resolve contact effects using the MVP properties. `SINK` SHALL remove all occupants of a contact cell, `DEFEAT` SHALL remove controlled entities sharing its cell, and `WIN` SHALL mark the level won when a surviving entity has both `YOU` and `WIN` or when a surviving `YOU` shares its cell with a distinct surviving `WIN` entity. The engine SHALL expose the settled state only after these effects complete.6667#### Scenario: A noun transforms68- **WHEN** the active rule `BABA IS FENN` is present after a successful turn69- **THEN** every object with noun `BABA` becomes noun `FENN` before the next rule scan7071#### Scenario: Sink removes contact occupants72- **WHEN** an entity with `SINK` shares a cell with another entity after movement73- **THEN** every entity in that cell is removed before the turn is committed7475#### Scenario: Defeat removes YOU76- **WHEN** a `YOU` entity shares a cell with an entity having `DEFEAT`77- **THEN** the controlled entity is removed and the level is not marked won by that contact7879#### Scenario: A surviving same-entity YOU and WIN wins80- **WHEN** a surviving entity has both `YOU` and `WIN` after transformations and contact destruction settle81- **THEN** the engine marks the level won and the settled event reports `won: true`8283#### Scenario: Distinct YOU and WIN entities still win84- **WHEN** a surviving `YOU` entity shares a cell with a distinct surviving entity having `WIN`85- **THEN** the engine marks the level won and rejects later movement until reset or progression8687#### Scenario: Destruction takes precedence over same-entity victory88- **WHEN** an entity with both `YOU` and `WIN` is removed by `SINK` or `DEFEAT` during contact resolution89- **THEN** the entity is listed in destruction details and the level is not marked won by that removed entity9091#### Scenario: Proof 03 reaches the win state92- **WHEN** the authored proof 03 rule `MIAU IS YOU AND WIN` is active and the controlled MIAU completes its winning move93- **THEN** the settled state and event report `won: true`, and the browser opens the existing Win scene9495### Requirement: The engine SHALL support complete turn undo and reset96The engine SHALL save the complete pre-turn state before each successful movement and SHALL restore it with `undo`. `reset` SHALL restore the original level, clear history, clear the win state, and rebuild rules and derived effects.9798#### Scenario: Undo restores a rule edit99- **WHEN** a successful push moves a word and the caller invokes `undo`100- **THEN** the word positions, active rules, objects, move count, and win state match the state before that push101102#### Scenario: Undo with no history is harmless103- **WHEN** the caller invokes `undo` before any successful move104- **THEN** the engine returns a false or equivalent no-op result and leaves the state unchanged105106#### Scenario: Reset returns to the level start107- **WHEN** the caller invokes `reset` after any sequence of moves and effects108- **THEN** the initial entities and rules are restored, move count is zero, win is false, and undo history is empty109110### Requirement: Active rules SHALL identify their source words111Each active semantic rule SHALL expose the word entity IDs that formed it in reading order and whether the sentence runs horizontally or vertically. Duplicate semantic rules at different physical locations SHALL remain deduplicated in the active rule table while retaining deterministic source information. The settled state SHALL additionally expose `sentences`, an ordered list of every physical maximal sentence span as `{ ids, axis }`. A span that is a strict subset of a longer span on the same axis SHALL be omitted; exact duplicate sentences at different locations SHALL both remain.112113#### Scenario: A horizontal sentence reports its source114- **WHEN** adjacent word entities form `MIAU IS YOU` from left to right115- **THEN** the resulting semantic rule identifies those word IDs in order, reports horizontal axis, and `state.sentences` contains the physical span with those ids and axis `h`116117#### Scenario: A vertical sentence reports its source118- **WHEN** adjacent word entities form `ROCK IS PUSH` from top to bottom119- **THEN** the resulting semantic rule identifies those word IDs in order, reports vertical axis, and `state.sentences` contains the physical span with those ids and axis `v`120121#### Scenario: Exact duplicate sentences remain physical spans122- **WHEN** two separate word runs form the same semantic sentence123- **THEN** the active rule table contains one semantic rule while `state.sentences` contains both physical spans124125#### Scenario: Strict subsets are removed126- **WHEN** a candidate span is a strict subset of a longer valid span on the same axis127- **THEN** `state.sentences` contains only the longer maximal span128129#### Scenario: Stacked words create separate spans130- **WHEN** two noun words share a cell and each forms a valid sentence with the same following words131- **THEN** `state.sentences` contains one span for each physical noun path132133### Requirement: Engine actions SHALL return settled turn events134`step`, `undo`, and `reset` SHALL return an event record after resolving state. Every record SHALL have `kind: 'step' | 'undo' | 'reset'`, `accepted`, ordered `moved`, full-record `rulesAdded` and `rulesRemoved`, ordered `transformed`, ordered `destroyed`, `controlLost`, and final `won` fields. A blocked or invalid step SHALL retain `kind: 'step'`, report `accepted: false`, and leave state unchanged.135136For movement, each entry SHALL be `{ id, from, to, pushedBy }`, where `pushedBy` is the immediate pusher's entity id or `null` for a directly controlled mover. A physical block SHALL be `{ id, dir, blockerId, reason }`, where `blockerId` is the blocking entity id or `null` at the board edge and `reason` is `stop` or `bounds`. Rule delta entries SHALL be complete rule records with `subject`, `predicate`, `sourceIds`, and `axis`. Destroyed entries SHALL be `{ id, noun|text, at, cause }` with `cause` `sink` or `defeat`. Arrays SHALL preserve engine resolution order: movement, transformation, destruction, then win evaluation. `controlLost` SHALL be true when the settled state has no `YOU` entity.137138#### Scenario: Breaking a rule produces a rule delta139- **WHEN** a successful push moves a word out of a sentence140- **THEN** the step result lists the word movement with `from`, `to`, and `pushedBy`, and lists the removed rule as a full record retaining its former `sourceIds` and `axis`141142#### Scenario: A blocked push produces no state change143- **WHEN** a push chain is blocked by `STOP` or the board edge144- **THEN** the step result has `kind: 'step'`, reports `accepted: false`, identifies `id`, `dir`, `blockerId`, and `reason`, and leaves move count and history unchanged145146#### Scenario: Undo reports a restored state147- **WHEN** a successful move is undone148- **THEN** the undo result has `kind: 'undo'`, reports `accepted: true`, the reverse movement with `pushedBy: null`, the rule changes, `controlLost`, and the restored win state149150#### Scenario: Contact destruction includes presentation details151- **WHEN** a `SINK` or `DEFEAT` interaction removes an entity152- **THEN** the step result lists its id, noun or text, cell coordinate, and `cause` in the destruction order153154#### Scenario: Control loss is explicit155- **WHEN** a settled step removes the last entity with the `YOU` property156- **THEN** the step result reports `controlLost: true` even though the state remains inspectable for the loss feedback157158#### Scenario: Event arrays preserve resolution order159- **WHEN** one accepted step moves entities, transforms an object, destroys contacts, and evaluates a win160- **THEN** the event arrays retain movement order first, transformation order second, destruction order third, and the final win result after those phases161