clone

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

Archive rules revision compatibility contract

Dami committed c788896
commit
c7888968cec9019c11bffb5d528e50c903e03b2f
parent
af337db37cd5ae8be58572d2d18aeca769b7969e
author
Dami <dami.etoile@gmail.com>
6 files changed, +86 -3
Ropenspec/changes/add-rules-compatibility-revision/.openspec.yaml → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/.openspec.yaml0
Ropenspec/changes/add-rules-compatibility-revision/design.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/design.md0
Ropenspec/changes/add-rules-compatibility-revision/proposal.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/proposal.md0
Ropenspec/changes/add-rules-compatibility-revision/specs/level-sharing/spec.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/specs/level-sharing/spec.md0
Ropenspec/changes/add-rules-compatibility-revision/tasks.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/tasks.md6+-
Mopenspec/specs/level-sharing/spec.md83++++++++++++++++++++++++++++++
R openspec/changes/add-rules-compatibility-revision/.openspec.yaml → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/.openspec.yaml +0 -0

No content changes.

R openspec/changes/add-rules-compatibility-revision/design.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/design.md +0 -0

No content changes.

R openspec/changes/add-rules-compatibility-revision/proposal.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/proposal.md +0 -0

No content changes.

R openspec/changes/add-rules-compatibility-revision/specs/level-sharing/spec.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/specs/level-sharing/spec.md +0 -0

No content changes.

R openspec/changes/add-rules-compatibility-revision/tasks.md → openspec/changes/archive/2026-09-24-add-rules-compatibility-revision/tasks.md +3 -3
M openspec/specs/level-sharing/spec.md +83 -0
@@ -110,3 +110,86 @@ Local CommonJS previews and data-only shared-link previews SHALL apply the same
110110 - **WHEN** a shared payload declares a feature unsupported by the current host111111 - **THEN** the decoder returns a player-readable error and Gift cannot install partial content112112 113+### Requirement: Pack manifests SHALL declare or derive a semantic rules revision114+115+The loader SHALL validate `manifest.rules` as a positive integer no greater116+than the host's current rules revision. The host's current revision SHALL be117+`2`, representing the post-W6 precedence, transform-reading, and contact-order118+contract. An omitted field SHALL mean legacy revision `1` and SHALL be119+materialized in normalized pack data. A value greater than `2` SHALL reject the120+pack before any catalog mutation.121+122+All pack-service manifest projections, including `manifestFromView()` and123+`createPackView()`, SHALL preserve the effective revision. A view round trip or124+persisted catalog record SHALL not silently remove `manifest.rules`.125+126+#### Scenario: A current pack loads without a compatibility note127+128+- **WHEN** a valid pack declares `manifest.rules: 2`129+- **THEN** local preview succeeds with `errors: []`, no rules-version warning,130+ and normalized data retains `manifest.rules: 2`131+132+#### Scenario: An omitted revision uses legacy semantics metadata133+134+- **WHEN** a valid imported pack omits `manifest.rules`135+- **THEN** preview succeeds, normalized data contains `manifest.rules: 1`, and136+ the catalog remains unchanged until the caller explicitly installs it137+138+#### Scenario: A pack view preserves its revision139+140+- **WHEN** a legacy pack is previewed, installed, and projected back through a141+ pack-service view142+- **THEN** the view and any later export/share operation retain143+ `manifest.rules: 1` rather than rebuilding a manifest without the field144+145+#### Scenario: Malformed revisions fail validation with player copy146+147+- **WHEN** a pack declares `manifest.rules` as `0`, `-1`, `1.5`, or a string148+- **THEN** preview fails with the player message `This pack's rules version149+ isn't valid, so it can't be installed.`, preserves the technical150+ `manifest.rules` validation detail, and does not install or partially register151+ the pack152+153+#### Scenario: Future revisions fail atomically with player copy154+155+- **WHEN** a pack declares `manifest.rules: 3`156+- **THEN** preview fails with the player message `This pack needs a newer157+ version of Miau Is True. Update the game to play it.`, preserves the158+ technical unsupported-rules-revision detail, and the catalog contains none159+ of that pack's levels160+161+### Requirement: Older rules SHALL produce one nonblocking W11 warning162+163+The preview service SHALL return one bounded, nonblocking warning when a164+pack's effective rules revision is below the host revision.165+166+When a pack's effective rules revision is below the host revision, local167+CommonJS and data-only shared previews SHALL return one warning, while keeping168+`errors: []` and allowing explicit installation. The warning SHALL have169+`word: 'RULES'`, `levelId: null`, `levelTitle: null`, `sentence: null`, and the170+player message `This pack was made for older rules; some proofs may play differently.`171+Its technical detail SHALL identify the declared or derived revision and the172+current host revision. The host SHALL continue to run current rules semantics;173+the warning is not a legacy simulation mode.174+175+#### Scenario: An explicit old revision is surfaced once176+177+- **WHEN** a valid pack declares `manifest.rules: 1` and contains seven proofs178+- **THEN** preview succeeds with one pack-level warning, the exact player179+ message, and detail showing `1` versus current `2`; it does not emit seven180+ duplicate warnings181+182+#### Scenario: Local and shared previews agree183+184+- **WHEN** the same legacy pack is previewed from CommonJS and from a data-only185+ shared link186+- **THEN** both previews expose the same warning envelope and normalized187+ `manifest.rules: 1` without installing the pack as a side effect188+189+#### Scenario: Warnings remain transient190+191+- **WHEN** a warned legacy pack is installed, exported, or encoded as a shared192+ link193+- **THEN** its normalized manifest retains only `rules: 1`, no warning field is194+ serialized, and the warning is recomputed when the pack is previewed again195+