ground-game/editions/CATALOG.md

147 lines
6.3 KiB
Markdown
Raw Normal View History

# Edition & rules catalog (schema 2 — composable modules by **aspect**)
**Authority:** this file + [`catalog.yaml`](catalog.yaml) on `main`.
**Aspect map:** [`ASPECTS.md`](ASPECTS.md) — full design-space dimensionality for GROUND.
**Simulator research:** clay-borg `research/CB-RES-0010-game-aspects-and-design-space.md`
**Purpose:** pin **baseline content** and **independent rules modules** so humans and **clay-borg** can run any module alone or in combination, measure, keep, or reject — without silent baseline edits.
---
## Model
```
┌─────────────────────┐
│ baseline content │ editions/ground-darvo-rN/
│ (CSVs, print data) │
└──────────┬──────────┘
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
problem_stress attack_relief end_condition …
(≤1 module) (≤1 module) (≤1 module)
▲ ▲ ▲
└────────── aspects of the game ────────────┘
```
| Concept | Meaning |
|---------|---------|
| **Aspect** | An orthogonal **design dimension** of the game (how stress is routed, how the game ends, how Problems enter play, …). Full list: [ASPECTS.md](ASPECTS.md). |
| **Baseline** | Edition **data** package (`Problems.csv`, modes, …). Frozen columns still require `rN→rN+1` (GROUND-WP-0002 T01). |
| **Module** | One implementable choice on **one aspect**. Defaults are named modules with no delta. |
| **Profile** | Named list of modules (convenience). **Not** a third rules source — expands to baseline + modules. |
| **Configuration** | Baseline + resolved module list = what is actually played. |
| **Composition** | At most **one module per aspect**. Missing aspects use `default_module`. |
**Independence rule:** a module may only declare rules on its **own aspect**. Cross-aspect effects belong in a **profile** (explicit combo) or a new aspect — never silent coupling inside one module.
**Legacy experiments** (`editions/experiments/h1-…`, `h2-…`) remain on disk as measured packages; they map to **profiles**. Prefer `module_id` / `profile_id` going forward.
**Synonym:** older docs said *axis* for aspect. Machine field is `aspect:`.
---
## Aspects with modules (registered)
| Aspect | Default | Other modules |
|--------|---------|----------------|
| `problem_stress` | `none` | `flat_any_open` (H1-A, reject), `scoped` (H2, keep) |
| `attack_relief` | `none` | `self_soothe_ge4` (H1-B) |
| `end_condition` | `fixed_rounds_5` | `hybrid_clear_collapse` (**ready-for-implement**) |
| `problem_deal` | `fixed_setup` | `pressure_deck` (**ready-for-implement**) |
Many other aspects exist but are **fixed in r0** until a competing design appears (see ASPECTS.md § full map).
---
## Selection (clay-borg / trials)
### Preferred API
```yaml
baseline: ground-darvo-r0
modules:
- problem_stress.scoped
- end_condition.hybrid_clear_collapse # when implemented
# other aspects → defaults
```
Or:
```yaml
profile: h2
# expands to modules: [problem_stress.scoped]
```
Or multi-aspect:
```yaml
profile: scoped_plus_attack_soothe
# problem_stress.scoped + attack_relief.self_soothe_ge4
```
### Validation
1. Every `module_id` exists and `selectable: true`.
2. No two modules share the same **aspect**.
3. `status: proposed` modules may be selected only if the host declares `allow_proposed: true` (kernel may no-op or refuse).
4. State / recordings must store the **resolved module list** (and baseline id), not only a legacy experiment string — so A/B names the **point in design space**.
### Implementation
- Baseline CSVs: vendor as today.
- Each module: apply `rules_delta` + optional `data_overlays` from its `path`.
- Apply modules in **aspect order** listed in `catalog.yaml` `aspects:` (stable, documented).
- Conflict: refuse composition rather than last-write-wins.
- **`consumed_files` (RPT-0006):** when present on a module, a consumer that
has not read those paths is in a **detectable** incomplete state — not
silence. Freshness/edition-check should fail or warn if a listed file is
unread or undigested. Modules without the field still work; new modules
should list it.
---
## Profiles (named combos)
| profile_id | modules | note |
|------------|---------|------|
| `baseline` | (defaults) | Pure r0 |
| `h1` | flat + attack soothe | Legacy H1; reject-as-baseline |
| `h2` | scoped | Legacy H2; keep-as-experiment |
| `scoped_plus_attack_soothe` | scoped + soothe | Unmeasured combo |
| `scoped_plus_hybrid_end` | scoped + hybrid end | Needs kernel for end |
| `scoped_plus_pressure_deck` | scoped + pressure deck | Needs kernel for deal |
---
## Adding a module (checklist)
1. Confirm the **aspect** exists in [ASPECTS.md](ASPECTS.md); add the aspect first if needed.
2. Create `editions/modules/<aspect>/<slug>/` with `MODULE.md` and, if non-default, `rules_delta.yaml` (+ CSV overlays if needed).
3. Register under `modules:` with `aspect`, `path`, `status`, `decision`.
4. Optionally add a **profile** that includes it alone and/or with other modules.
5. Message clay-borg: `module_id`, aspect, delta path, compose examples.
6. Measure **alone** first when possible; then measure interesting **profiles**.
7. Update `utility_estimate` / `decision` per module (and per profile if combo-specific).
### What must not happen
- Silent edit of frozen baseline columns inside `ground-darvo-r0`.
- A new mega-experiment that re-bundles three aspects into one non-decomposable id (use a profile instead).
- Modules that hard-require another aspects module without documenting a profile.
---
## Git
**main + catalog** is discovery; commits pin digests; branches optional for WIP. Modules live as directories on `main`.
---
## Legacy map
| Old experiment | Prefer |
|----------------|--------|
| `h1-problem-stress` | profile `h1` or modules `problem_stress.flat_any_open` + `attack_relief.self_soothe_ge4` |
| `h2-scoped-problem-stress` | profile `h2` or module `problem_stress.scoped` |