clone

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

main
miau-is-true / openspec / changes / add-channel-linked-gates / specs / channel-linked-gates / spec.md
spec.md 6.4K source

ADDED Requirements

Requirement: Channel metadata SHALL be stable and declarative

Authored channel metadata SHALL be validated against the host channel palette, remain attached to its authored entity ID through noun transformations, and contain no executable behavior.

Scenario: A channel-linked pair loads

  • WHEN a level declares a PLATE and GATE with the same supported channel
  • THEN both entities load with their stable channel metadata and participate in one circuit

Scenario: A malformed channel fails closed

  • WHEN a pack uses an unknown channel, unsupported metadata field, or executable channel value
  • THEN validation rejects the pack before installation with the declaration path

Scenario: Channel survives a noun transform

  • WHEN GATE IS CRATE transforms an authored gate
  • THEN the entity becomes an ordinary CRATE while retaining its authored channel for a later transformation back to GATE

Requirement: Plate pressure SHALL use final occupancy

At the end of an accepted turn, after movement, transforms, automata, and contacts, a current-noun PLATE SHALL be pressed when any other surviving entity occupies its cell. Words and objects count regardless of properties.

Scenario: Anything can press a plate

  • WHEN a word, non-PUSH YOU object, pushed object, or automaton actor ends on a plate
  • THEN the plate is pressed at the settled boundary

Scenario: A plate does not press itself

  • WHEN a plate has no other surviving entity in its cell
  • THEN it is unpressed even though the plate entity occupies the cell

Scenario: SINK releases a plate on the same turn

  • WHEN the only presser on a plate is destroyed by SINK or DEFEAT during a turn
  • THEN the settled plate is unpressed and its linked gate is recomputed from the released final occupancy

Requirement: Closed gates SHALL block from the prior settled state

During movement planning, a current-noun GATE SHALL block entry as an unconditional STOP when its prior settled projection is closed. Gate changes SHALL not take effect mid-turn.

Scenario: Pressing a plate does not open the gate mid-turn

  • WHEN a mover enters a plate on the same turn that it would cross the linked closed gate
  • THEN the gate blocks that turn and is available on the following turn if the plate remains pressed

Scenario: Rules cannot reopen a closed gate

  • WHEN a closed gate has a rule that would otherwise remove or override STOP
  • THEN movement into the gate remains blocked

Scenario: An open gate is traversable

  • WHEN the prior settled projection is open
  • THEN the gate contributes no movement blocker and does not crush an entity entering or occupying its cell

Requirement: Gate openness SHALL be memoryless and channel linked

After contacts, each current-noun GATE SHALL be open exactly when its channel has a pressed current-noun PLATE or another surviving entity occupies the gate cell. A transformed-away gate SHALL leave the circuit; a gate transformed back SHALL recompute its state from the final board without remembered openness.

Scenario: A jam keeps a gate open

  • WHEN a gate would lose its pressed plate but another surviving entity occupies the gate cell after contacts
  • THEN the gate remains open and is marked jammed until that cell is empty

Scenario: A gate closes after the jam clears

  • WHEN the jammed gate cell becomes empty and no linked plate is pressed
  • THEN the settled gate becomes closed

Scenario: Transforming away and back recomputes

  • WHEN a gate transforms to CRATE, later transforms back to GATE, and the final channel plate and gate cell are empty
  • THEN it rejoins closed; no prior open state affects the result

The gate and plate projections SHALL be a derived mechanic contract. open, jammed, and pressed SHALL NOT be persisted as hidden mutable mechanic fields or redundantly encoded in solver frontier bytes. They SHALL be recomputed from the restored objects, rules, occupancy, and authored channel metadata.

Requirement: Gate and plate changes SHALL be observable in settled events

Settled results SHALL expose cloned gateChanged and plateChanged arrays when their final projections change. Gate records SHALL contain id, open, and jammed; plate records SHALL contain id and pressed.

Scenario: A circuit transition emits both records

  • WHEN a crate leaves a plate and the linked gate closes
  • THEN the settled result reports the plate release and gate closure with stable authored IDs

Scenario: Returned events cannot mutate state

  • WHEN a caller edits a returned gateChanged or plateChanged record
  • THEN the engine's next getState() and turn use the original projections

Requirement: Gate state SHALL survive history and solver replay

Reset, Undo, restore, public transitions, and fast solver transitions SHALL derive identical gate and plate projections from the same settled object/rule state. The compact solver identity SHALL not omit any value that affects the prior settled blocker projection and SHALL reject hidden mutable gate fields.

Scenario: Undo restores a jam and release

  • WHEN a turn opens or jams a gate and the player invokes Undo
  • THEN the prior plate and gate projections return and the next movement matches direct replay

Scenario: Solver parity preserves the next gate decision

  • WHEN a compact snapshot is decoded and restored before a movement that approaches a gate
  • THEN public and fast transitions agree on accepted status, object state, gate projection, and emitted gate/plate changes

Scenario: Restore recomputes a memoryless projection

  • WHEN a snapshot containing the same authoritative objects and channel metadata is restored after a prior gate projection
  • THEN the gate and plate projections are recomputed identically without carrying an open, jammed, or pressed bit from the prior state

Scenario: Hidden gate state fails closed

  • WHEN a gate implementation attempts to encode a mutable openness field that is not part of the derived projection inputs
  • THEN the mechanic registry or solver codec rejects the state before play or search

Scenario: Two channels remain independent

  • WHEN an amber plate is pressed while a teal plate is not
  • THEN only amber gates open or jam; teal gates remain governed by teal occupancy