Promotes Setting and Plane from the write-tools allowlist to first-class Layer-1 NODE_LABELS. Adds 5 plane-relation edge types to EDGE_TYPES (EXISTS_IN, REFLECTS, LAYER_OF, ADJACENT_TO, ACCESSIBLE_VIA). Per docs/17-planes.md: EXISTS_IN is the timeless type-assertion that an entity belongs to a Setting; time-bounded planar membership is carried by a separate reified :Relation (slice 6.5). +6 tests (712 → 718). All green. No regressions.
97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
"""Slice 6.1 — Setting + Plane dataclasses.
|
|
|
|
The Setting / Plane data model is documented in
|
|
``docs/17-planes.md`` (full design) and
|
|
``docs/plan/06-slice-planes.md`` (acceptance criteria). This
|
|
module is the *POC-scoped* contract — the minimal field set the
|
|
slice 6 work depends on. The full design adds non-contract
|
|
metadata (canonical_time, alignment_tendency, etc.) that is
|
|
captured in YAML frontmatter but is not yet typed here.
|
|
|
|
Both dataclasses are pure data; persistence happens via the
|
|
``GraphBackend`` Protocol methods (slice 6.2):
|
|
|
|
- ``graph.add_setting(Setting)``
|
|
- ``graph.add_plane(Plane)``
|
|
|
|
Why a dedicated module:
|
|
|
|
- A typed constructor makes the slice 6 migration's
|
|
``--dry-run`` diff easier to read (per
|
|
``docs/plan/exec/06-planes.md`` sub-slice 6.6).
|
|
- The dataclass is the single source of truth for what fields
|
|
the engine recognises — both the writer (``01_ingest.py``)
|
|
and the reader (read_tools) import from here.
|
|
- The field set is the *contract* that ``ALLOWED_LABELS`` in
|
|
``write_tools.py`` is checked against for entities whose
|
|
``label == "Setting" | "Plane"``.
|
|
|
|
Distinction from the polymorphic Layer 2 (slice 5T):
|
|
|
|
- Layer 1 (``NODE_LABELS``): these labels are closed-vocabulary,
|
|
one-of-36, registered in ``ontology.py``. ``Setting`` and
|
|
``Plane`` are Layer 1.
|
|
- Layer 2 (``DomainEntity`` + ``TypeTemplate``): a user can
|
|
declare a new domain type by dropping a YAML in
|
|
``templates/``. Setting/Plane are not user-extensible.
|
|
|
|
Per ADR 0004: ``Region`` is a *geographic* label (a place
|
|
inside a plane); ``Plane`` is a *planar* label (a place an
|
|
entity can travel to). The two are distinct; see
|
|
``docs/10-critique.md#S3.2``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Setting:
|
|
"""A self-contained world.
|
|
|
|
Contract (slice 6.1):
|
|
- id: stable string identifier (e.g., ``"mardonari"``)
|
|
- kind: free-form genre/category (e.g., ``"campaign"``,
|
|
``"novel"``, ``"west-marches"``)
|
|
- current_era: id of the ``:Era`` node the world is
|
|
currently in (per the world-builder's calendar)
|
|
- schema_version: graph-model version this setting was
|
|
authored under (per the docs/12-storage-strategy.md
|
|
convention)
|
|
- created_at: ISO-8601 timestamp
|
|
|
|
Non-contract fields (full design, deferred):
|
|
- name, summary, genres, canonical_time
|
|
"""
|
|
|
|
id: str
|
|
kind: str
|
|
current_era: str
|
|
schema_version: str
|
|
created_at: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Plane:
|
|
"""A planar subdivision of a Setting.
|
|
|
|
Contract (slice 6.1):
|
|
- id: stable string identifier (e.g.,
|
|
``"mardonari.voldramir"``)
|
|
- setting_id: id of the parent :Setting
|
|
- name: human-readable (e.g., ``"Voldramir"``)
|
|
- kind: ``"material"`` | ``"shadow"`` | ``"fey"`` |
|
|
``"astral"`` | ``"elemental"`` | ``"custom"`` (free
|
|
string — designers can use their own taxonomy)
|
|
|
|
Non-contract fields (full design, deferred):
|
|
- parent_plane (planes can nest), accessible (bool),
|
|
alignment_tendency, summary, valid_from, valid_until
|
|
"""
|
|
|
|
id: str
|
|
setting_id: str
|
|
name: str
|
|
kind: str
|