# SOP — WaterStorage / Watershed CookieBlob + Game Crafter Build

**Version:** 0.1  
**Date:** 2026-07-17  
**Working title:** Watershed  
**Public package:** `waterstorage-cross-platform`

## 1. Purpose

Build the first playable Watershed prototype twice, in parallel:

1. as a WordPress-safe CookieBlob room using inline HTML, CSS, JavaScript, and browser persistence;
2. as a physical card-and-mat prototype prepared for Game Crafter production.

Both versions are one system. They are not separate games with loosely related themes. The shared behavior is defined in `parity-matrix.md`.

## 2. Product decision

The shared unit is a **phase transition** in an information hydrological system. A player moves a basin through a loop of water and information states while managing flow, energy, pressure, pollution, storage, and health.

The first implementation is deliberately small:

- W01 Evaporate is playable;
- W02 Condense is playable;
- W03–W10 are named and reserved;
- all meters, persistence, trace, and recovery behavior are real;
- parity is tested before content expansion.

This makes the CookieBlob and table versions co-design surfaces instead of waiting for one finished format before starting the other.

## 3. Source-of-truth hierarchy

When artifacts disagree, use this order:

1. latest user decision in the active conversation;
2. this SOP for workflow and scope;
3. `parity-matrix.md` for state, actions, and fixtures;
4. `cookieblob/` and `game-crafter/` implementation files;
5. older WaterStorage documents and prototypes as reference only.

Do not silently rename WaterStorage. Use **Watershed** as the playable prototype title and retain WaterStorage as the framework / project name until the user makes a final naming decision.

## 4. Shared state model

Use the fields and defaults in `parity-matrix.md`:

- cycle;
- phase;
- health;
- flow;
- cloud;
- pollution;
- energy;
- groundwater;
- reservoir;
- pressure;
- trace.

The CookieBlob state key must be namespaced, for example `waterstorage_watershed_v01`. Never use a generic key such as `state` or `gameState`.

## 5. Build sequence

### Step 1 — Freeze the contract

Before writing reducer logic or laying out cards:

1. read `parity-matrix.md`;
2. verify the JSON defaults against `cookieblob/cookieblob-state-schema.json`;
3. verify the two active actions by hand;
4. do not add undocumented variables to either prototype.

**Gate:** F01–F06 are written and understood.

### Step 2 — Implement the shared reducer

Implement the same conceptual reducer in both formats:

1. normalize state;
2. identify current phase;
3. evaluate requirements;
4. apply success or blocked deltas;
5. clamp bounded values;
6. append a trace event capped at 12 entries;
7. persist or record the resulting state.

The CookieBlob reducer may be JavaScript. The table reducer is the player-facing action procedure. Their outputs must match the fixtures, not necessarily their internal notation.

**Gate:** A fresh W01 state produces F01 exactly.

### Step 3 — Build CookieBlob room

Use existing CookieBlob techniques:

- self-contained HTML fragment suitable for WordPress;
- no external framework dependency;
- namespaced localStorage;
- safe JSON parse and default recovery;
- visible meters and current phase;
- one clear action button for the active phase;
- trace log visible on revisit;
- reset control;
- export seed control;
- import seed control;
- optional transmission / RSS hooks isolated from game logic.

Do not place transmission code in the reducer. A transmission failure must not corrupt play.

**Gate:** Reloading the page preserves state; reset returns to the normalized defaults; malformed stored state recovers safely.

### Step 4 — Build Game Crafter print prototype

Prepare:

- basin mat;
- W01–W10 phase cards;
- W01 and W02 active action text;
- reserved W03–W10 cards;
- tokens for every meter;
- trace strip;
- seed card;
- player aid.

The physical player should be able to execute W01 and W02 without a phone or website. The seed card is a bridge between formats, not a dependency.

**Gate:** A player can reset, execute F01–F04, and record the result using only printed components.

### Step 5 — Run parity tests

Run F01–F06 against both implementations. Record pass / fail in `parity-test-log.md`.

If a result differs:

1. stop adding features;
2. reproduce from a fresh state;
3. compare the phase, requirement, deltas, clamping, cycle, and trace event;
4. update the matrix only if the intended rule was wrong;
5. fix both implementations if the matrix is correct;
6. rerun all fixtures.

### Step 6 — Review for playability

Ask:

- Can a new player tell what phase they are in?
- Can they tell what resource is limiting the next transition?
- Does a blocked action teach them something rather than merely punish them?
- Does revisiting the CookieBlob show meaningful continuity?
- Can the physical game preserve a trace without excessive bookkeeping?
- Is the same story legible in both formats?

Keep the answer grounded in observed playtests, not assumed usability.

### Step 7 — Expand one transition at a time

After F01–F06 pass, implement W03 only. Update the matrix first, then both versions, then fixtures and the test log. Repeat for W04–W10.

Never implement a CookieBlob phase without creating its physical card specification in the same work cycle. Never print a physical phase whose CookieBlob semantics are undefined.

## 6. CookieBlob safety and persistence rules

- Use a versioned storage key.
- Treat localStorage as untrusted input.
- Parse inside `try/catch`.
- Normalize every imported or stored field.
- Clamp numeric values to the matrix bounds.
- Ignore unknown phase IDs and unknown fields.
- Never execute imported HTML.
- Keep export JSON data-only.
- Keep the reset button explicit and reversible only through import if a seed was exported.
- Avoid cookies for primary state; CookieBlob refers to the room / persistence technique, while localStorage holds the prototype state.

## 7. Game Crafter production rules

- Put the version and component ID on every card.
- Use high-contrast text and labels in addition to color.
- Keep card backs consistent by component family.
- Maintain a print manifest with quantities and dimensions before ordering.
- Prototype on ordinary paper first.
- Use tokens that cannot be confused between health, pressure, pollution, and flow.
- Leave W03–W10 visibly marked as reserved rather than implying unfinished text is final.

## 8. Deliverables for v0.1

Required in this public package:

- this SOP;
- `parity-matrix.md`;
- `parity-test-log.md`;
- CookieBlob README and state schema;
- Game Crafter README and print specification;
- changelog.

Required before v0.1 is called playable:

- CookieBlob room HTML;
- physical card text / print files;
- all six fixture results recorded;
- a short playtest note for each format.

## 9. Public sync procedure

From `/home/workspace`:

```bash
zopub sync waterstorage-cross-platform /home/workspace/WaterStorage/watershed-cross-platform-public
```

After each meaningful revision:

1. inspect the package tree;
2. run the parity fixtures;
3. update `parity-test-log.md` and `CHANGELOG.md`;
4. sync the same collection name;
5. report the collection URL.

## 10. Definition of done for this build stage

This stage is complete when the package is publicly synced and contains the shared contract plus both implementation specifications. It is not complete merely because the folder exists. The next build stage is the CookieBlob room and the first printable W01 / W02 card set.
