Files
Lore Engine Dev 3c32bf2702 slice 6.1: Setting + Plane schema + ontology
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.
2026-06-19 12:24:38 -04:00

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