clone

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

main
miau-is-true / openspec / changes / archive / 2026-09-23-expose-sentence-spans / design.md
design.md 3.0K rendered
1## Context23The engine already deduplicates semantic rules so simulation does not apply the same `subject IS predicate` more than once. The designer's sentence bars need a different view: every physical sentence on the board, including exact duplicates and stacked-word paths. E3 has been implemented in the engine and tests; this change records that landed contract before the implementation is committed.45## Goals / Non-Goals67**Goals:**89- Expose `state.sentences: [{ ids, axis }]` for presentation consumers.10- Preserve one semantic rule per unique sentence meaning in `state.rules`.11- Keep exact duplicate physical runs, stacked-word paths, and horizontal/vertical axes deterministic.12- Drop strict subset spans when a longer span exists on the same axis.1314**Non-Goals:**1516- Changing rule semantics, movement, transformations, contact effects, or event payloads.17- Drawing sentence bars or choosing their visual placement.18- Adding new vocabulary or changing the parser beyond the physical span projection.1920## Decisions2122### 1. Keep semantic rules and physical spans as separate projections2324The parser discovers candidate source paths once. It emits every physical path into `state.sentences`, while the existing semantic map keeps only the first deterministic source for each rule text. A renderer uses spans for bars and rules for behavior.2526### 2. Store only source IDs and axis in spans2728The span contract is intentionally small: `ids` preserves the source word entity order and `axis` is `h` or `v`. Positions and text remain available from state objects, avoiding a second mutable representation that could drift from the board.2930### 3. Filter strict subsets by axis and source membership3132After candidates are collected, remove a span when another candidate on the same axis has more source IDs and contains every ID in the shorter span. Exact duplicates are retained because they are distinct candidate records and have equal length. This matches the prototype parser's maximal-span behavior.3334### 4. Recompute spans with rules3536`state.sentences` is rebuilt whenever rules are refreshed, including reset, word movement, undo restoration, and transformations that trigger a re-scan. It is derived state and is not independently edited by mods or renderers.3738## Risks / Trade-offs3940- [ID membership can mistake disjoint spans for subsets] → Require same-axis and strict-length comparisons while retaining candidate order; fixtures cover horizontal, vertical, stacked, and duplicate cases.41- [Consumers assume semantic rule count equals bar count] → Document `state.sentences` as the physical source and keep `state.rules` as the semantic source of truth.42- [Parser changes alter bar order] → Preserve deterministic discovery order and assert exact ordered spans in engine tests.4344## Migration Plan45461. Keep existing `state.rules` consumers unchanged.472. Read `state.sentences` in sentence-bar rendering when that separate presentation change lands.483. Archive this change after the engine implementation and tests are committed.4950## Open Questions5152None for the E3 data contract.